first commit
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
node_modules/
|
||||||
|
package-lock.json
|
||||||
|
|
||||||
89
app/services.js
Normal file
89
app/services.js
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
var uuid = require('node-uuid'),
|
||||||
|
authCodes = {},
|
||||||
|
accessTokens = {},
|
||||||
|
tokenHeartbeats = {},
|
||||||
|
clients = {
|
||||||
|
'F8Nbz9gGUvLgdn8T': {
|
||||||
|
id: '1',
|
||||||
|
secret: 'Fesmx7hHCCMx7Cby7FhV2fAtf2NYEFzP5fCKuwEEdpf8hpnsnnQn9qYhNHt6SsDD',
|
||||||
|
grantTypes: ['client_credentials']
|
||||||
|
},
|
||||||
|
'dev52VrnSufxEyKT': {
|
||||||
|
id: '2',
|
||||||
|
secret: 'nK2jnqhdWnrmAFDw9zWVueAqUQvSxmAyjf2Sz7ZrmYVSH5GSxER4rPQCuBUewF',
|
||||||
|
grantTypes: ['client_credentials']
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const services = {
|
||||||
|
flushExpiredTokens: function (maxAge) {
|
||||||
|
let oldTokens = [];
|
||||||
|
let now = new Date().getTime();
|
||||||
|
for (let token in accessTokens) {
|
||||||
|
if (tokenHeartbeats[token] && tokenHeartbeats[token] < now - 1000 * maxAge) {
|
||||||
|
oldTokens.push(token)
|
||||||
|
delete accessTokens[token]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log('Flush expired tokens execution completed.', oldTokens)
|
||||||
|
},
|
||||||
|
getAccessTokens: function () {
|
||||||
|
return accessTokens;
|
||||||
|
},
|
||||||
|
getClients: function () {
|
||||||
|
return clients;
|
||||||
|
},
|
||||||
|
heartbeat: {
|
||||||
|
puls: function (token) {
|
||||||
|
tokenHeartbeats[token] = new Date().getTime();
|
||||||
|
},
|
||||||
|
signal: function (authHeader) {
|
||||||
|
if (authHeader) {
|
||||||
|
let token = authHeader.split(' ').pop()
|
||||||
|
if (accessTokens[token]) {
|
||||||
|
services.heartbeat.puls(token)
|
||||||
|
return tokenHeartbeats[token];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clientService: {
|
||||||
|
getById: function (id, callback) {
|
||||||
|
return callback(null, clients[id]);
|
||||||
|
},
|
||||||
|
isValidRedirectUri: function (/*client, requestedUri*/) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tokenService: {
|
||||||
|
generateToken: function (callback) {
|
||||||
|
callback(null, uuid.v4());
|
||||||
|
},
|
||||||
|
generateAuthorizationCode: function (callback) {
|
||||||
|
callback(null, uuid.v4());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
authorizationService: {
|
||||||
|
saveAuthorizationCode: function (codeData, callback) {
|
||||||
|
authCodes[codeData.code] = codeData;
|
||||||
|
return callback(null, authCodes[codeData.code]);
|
||||||
|
},
|
||||||
|
saveAccessToken: function (tokenData, callback) {
|
||||||
|
accessTokens[tokenData.access_token] = tokenData;
|
||||||
|
return callback(null, accessTokens[tokenData.access_token]);
|
||||||
|
},
|
||||||
|
getAuthorizationCode: function (code, callback) {
|
||||||
|
return callback(null, authCodes[code]);
|
||||||
|
},
|
||||||
|
getAccessToken: function (token, callback) {
|
||||||
|
return callback(null, accessTokens[token]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
membershipService: {
|
||||||
|
areUserCredentialsValid: function (userName, password, scope, callback) {
|
||||||
|
return callback(null, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports = services
|
||||||
139
index.js
Normal file
139
index.js
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
var proxy = require('express-http-proxy'),
|
||||||
|
express = require('express'),
|
||||||
|
expressLogging = require('express-logging'),
|
||||||
|
logger = require('logops'),
|
||||||
|
port = 32100, hostname = '127.0.0.1',
|
||||||
|
supportedScopes = ['profile', 'status', 'avatar'],
|
||||||
|
expiresIn = 3600,
|
||||||
|
low = require('lowdb'),
|
||||||
|
FileSync = require('lowdb/adapters/FileSync'),
|
||||||
|
HttpStatus = require('http-status-codes'),
|
||||||
|
cron = require('node-cron');
|
||||||
|
|
||||||
|
const services = require('./app/services');
|
||||||
|
const adapter = new FileSync(__dirname + '/storage/db.json')
|
||||||
|
const db = low(adapter)
|
||||||
|
|
||||||
|
db.get('authCodes').value()
|
||||||
|
.forEach(codeData => {
|
||||||
|
codeData.expiresDate = function () {
|
||||||
|
var d = new Date();
|
||||||
|
d.setDate(d.getDate() + 2);
|
||||||
|
return d;
|
||||||
|
}();
|
||||||
|
services.authorizationService.saveAuthorizationCode(codeData, function (n, codeData) {
|
||||||
|
// console.log(codeData)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
var OAuthServer = require('simple-oauth-server'),
|
||||||
|
oauthServer = new OAuthServer(
|
||||||
|
services.clientService,
|
||||||
|
services.tokenService,
|
||||||
|
services.authorizationService,
|
||||||
|
services.membershipService,
|
||||||
|
expiresIn,
|
||||||
|
supportedScopes
|
||||||
|
);
|
||||||
|
|
||||||
|
function authorize(request, response) {
|
||||||
|
response.statusCode = 403;
|
||||||
|
response.json({ code: 501, message: 'Not Implemented' });
|
||||||
|
return true;
|
||||||
|
oauthServer.authorizeRequest(request, 'accountid', function (error, authorizationResult) {
|
||||||
|
if (error) {
|
||||||
|
response.statusCode = 400;
|
||||||
|
return response.end(JSON.stringify(error));
|
||||||
|
}
|
||||||
|
// var code = require('url').parse(authorizationResult.redirectUri, true).query.code;
|
||||||
|
// response.statusCode = 302;
|
||||||
|
// response.setHeader('Location', 'http://localhost:8080/oauth/token?client_id=1&grant_type=authorization_code&client_secret=kittens&code=' + code);
|
||||||
|
|
||||||
|
response.end(JSON.stringify(authorizationResult));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function grantToken(request, response) {
|
||||||
|
oauthServer.grantAccessToken(request, function (error, token) {
|
||||||
|
if (error) {
|
||||||
|
console.log(error)
|
||||||
|
response.statusCode = 400;
|
||||||
|
return response.json(error);
|
||||||
|
}
|
||||||
|
if (services.getClients()[request.query.client_id].id == 1) {
|
||||||
|
services.heartbeat.puls(token.access_token);
|
||||||
|
}
|
||||||
|
response.json(token);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function apiEndpoint(request, response) {
|
||||||
|
console.log(oauthServer.validateAccessToken(request, function (error, validationResult) {
|
||||||
|
if (error) {
|
||||||
|
response.statusCode = 401;
|
||||||
|
return response.json(error);
|
||||||
|
}
|
||||||
|
response.json(validationResult);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function heartbeat(request, response) {
|
||||||
|
let updated = services.heartbeat.signal(request.headers.authorization);
|
||||||
|
response.json({ code: updated ? 200 : 400, data: updated });
|
||||||
|
}
|
||||||
|
|
||||||
|
cron.schedule('0 * * * * *', () => {
|
||||||
|
services.flushExpiredTokens(300);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const app = express()
|
||||||
|
app.use(expressLogging(logger));
|
||||||
|
const proxyFilter = function (req, res) {
|
||||||
|
return req.hostname == hostname ? true : new Promise(function (resolve) {
|
||||||
|
resolve(function () {
|
||||||
|
if (req.headers.authorization) {
|
||||||
|
let tokenData = services.getAccessTokens()[req.headers.authorization.split(' ').pop()];
|
||||||
|
// console.log('App token data', tokenData)
|
||||||
|
|
||||||
|
if (!tokenData || !tokenData.access_token) {
|
||||||
|
res.json({ code: HttpStatus.NOT_ACCEPTABLE })
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (tokenData.expiresDate < new Date()) {
|
||||||
|
res.json({ code: HttpStatus.NOT_ACCEPTABLE })
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
app.use('/api/v1/headless', proxy('127.0.0.1:32101', {
|
||||||
|
filter: proxyFilter
|
||||||
|
}));
|
||||||
|
|
||||||
|
app.use('/api/v1/spider', proxy('127.0.0.1:32102', {
|
||||||
|
filter: proxyFilter
|
||||||
|
}));
|
||||||
|
|
||||||
|
app.use('/api/v1/spiduler', proxy('127.0.0.1:32103', {
|
||||||
|
filter: proxyFilter
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
app.get('/oauth/authorize', authorize)
|
||||||
|
|
||||||
|
app.get('/api/v1/oauth/token', grantToken)
|
||||||
|
app.get('/oauth/token', grantToken)
|
||||||
|
|
||||||
|
app.get('/api/test', apiEndpoint)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
app.listen(port)
|
||||||
|
console.log('Server starting port ' + port)
|
||||||
25
package.json
Normal file
25
package.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "cm-auth",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"dependencies": {
|
||||||
|
"express": "^4.17.1",
|
||||||
|
"express-http-proxy": "^1.5.1",
|
||||||
|
"express-logging": "^1.1.1",
|
||||||
|
"http-status-codes": "^1.3.2",
|
||||||
|
"kgo": "^4.0.3",
|
||||||
|
"logops": "^2.1.1",
|
||||||
|
"lowdb": "^1.0.0",
|
||||||
|
"node-cron": "^2.0.3",
|
||||||
|
"node-uuid": "^1.4.8",
|
||||||
|
"simple-oauth-server": "^1.0.6"
|
||||||
|
},
|
||||||
|
"devDependencies": {},
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"start": "node app/index.js"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC"
|
||||||
|
}
|
||||||
11
storage/db.json
Normal file
11
storage/db.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"authCodes": [
|
||||||
|
{
|
||||||
|
"code": "a9c6380a-9e34-467f-a1ae-514bb51a7724",
|
||||||
|
"redirectUri": "http://google.com",
|
||||||
|
"clientId": "F8Nbz9gGUvLgdn8T",
|
||||||
|
"expiresDate": null,
|
||||||
|
"accountId": "accountid"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user