|
|
@@ -30,7 +30,7 @@ function getSessionId(cookieObject) {
|
|
|
return cookieObject?.[SESSION_COOKIE];
|
|
|
}
|
|
|
|
|
|
-function getLoggedUser(cookieObject) {
|
|
|
+function getSessionObj(cookieObject) {
|
|
|
let cookie = getSessionId(cookieObject);
|
|
|
if (!cookie)
|
|
|
return null;
|
|
|
@@ -39,59 +39,14 @@ function getLoggedUser(cookieObject) {
|
|
|
if (!sessionEntry || sessionEntry.expire < now)
|
|
|
return null;
|
|
|
sessionEntry.expire = now + SESSION_TIME;
|
|
|
- return sessionEntry.username;
|
|
|
+ return sessionEntry;
|
|
|
}
|
|
|
|
|
|
-function isUserValid(username) {
|
|
|
- return new Promise((ok, ko) => {
|
|
|
- ldapReady.then(() => {
|
|
|
- ldap.search(CONFIG.ldapBase, { filter: CONFIG.ldapFilter?.replaceAll('{0}', username), attributes: [ 'mail', 'cn', 'sn', 'dn' ], scope: 'one' }, (err, res) => {
|
|
|
- if (err) {
|
|
|
- console.error(err);
|
|
|
- ko(err);
|
|
|
- return;
|
|
|
- }
|
|
|
- let found = null;
|
|
|
- res.on('searchEntry', i => found = i.object);
|
|
|
- res.on('error', console.error);
|
|
|
- res.on('end', () => {
|
|
|
- if (!found) {
|
|
|
- ko();
|
|
|
- return;
|
|
|
- }
|
|
|
- const now = (new Date()).getTime();
|
|
|
- let sessionEntry = {
|
|
|
- loginDateTime: now,
|
|
|
- expire: now + SESSION_TIME,
|
|
|
- username: found.cn || found.sn,
|
|
|
- mail: Array.isArray(found.mail) ? found.mail[0] : found.mail,
|
|
|
- dn: found.dn,
|
|
|
- random: Math.random()
|
|
|
- };
|
|
|
- ok(sessionEntry);
|
|
|
- });
|
|
|
- });
|
|
|
- });
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-function checkPassword(dn, password) {
|
|
|
- return new Promise((ok, ko) => {
|
|
|
- let ldap = require('ldapjs').createClient({ url: [ CONFIG.ldapUrl, CONFIG.ldapUrl ]});
|
|
|
- ldap.on('error', err => {
|
|
|
- console.error("Login failure: " +err);
|
|
|
- ko(err.message);
|
|
|
- });
|
|
|
- ldap.bind(dn, password, err => {
|
|
|
- if (err) {
|
|
|
- console.error("Login failure: " +err);
|
|
|
- ko(err instanceof ldapjs.InvalidCredentialsError ? undefined : err.message);
|
|
|
- return;
|
|
|
- }
|
|
|
- ldap.unbind();
|
|
|
- ok();
|
|
|
- });
|
|
|
- });
|
|
|
+function getAccessList(cookieObject) {
|
|
|
+ let session = getSessionObj(cookieObject);
|
|
|
+ if (!session)
|
|
|
+ return null;
|
|
|
+ return session.accessList;
|
|
|
}
|
|
|
|
|
|
function getRequestIp(req) {
|
|
|
@@ -102,90 +57,51 @@ function sign(msg) {
|
|
|
return crypto.sign('sha256', Buffer.from(msg), decodeKey(CONFIG.privKey)).toString('base64');
|
|
|
}
|
|
|
|
|
|
-function checkSign(remoteHostConfig, message, signature) {
|
|
|
- let result = false;
|
|
|
- try {
|
|
|
- result = crypto.verify('sha256', Buffer.from(message), decodeKey(remoteHostConfig.pubKey), Buffer.from(signature, 'base64'));
|
|
|
- } catch (e) {
|
|
|
- console.error(e);
|
|
|
- result = false;
|
|
|
- }
|
|
|
- if (!result)
|
|
|
- console.error("Crypto::checkSign failed to check signature for message !");
|
|
|
- return result;
|
|
|
+function Access() {
|
|
|
}
|
|
|
+Access.prototype.id = function() { return ""; }
|
|
|
|
|
|
-function encodeKey(key) { return btoa(key); }
|
|
|
-function decodeKey(key) { return atob(key); }
|
|
|
-
|
|
|
-function generateKeys() {
|
|
|
- return new Promise((ok, ko) => {
|
|
|
- crypto.generateKeyPair('rsa', {
|
|
|
- modulusLength: 4096,
|
|
|
- publicKeyEncoding: { type: 'spki', format: 'pem' },
|
|
|
- privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
|
|
|
- }, (err, pubKey, privKey) => {
|
|
|
- if (err) {
|
|
|
- ko(err);
|
|
|
- return;
|
|
|
- }
|
|
|
- ok({pubKey: encodeKey(pubKey), privKey: encodeKey(privKey)});
|
|
|
- });
|
|
|
- });
|
|
|
+function LinkAccess(linkId) {
|
|
|
+ Access.call(this);
|
|
|
+ this.linkId = linkId;
|
|
|
}
|
|
|
+LinkAccess.prototype = Object.create(Access.prototype);
|
|
|
+LinkAccess.prototype.id = function() { return "LINK_"+this.linkId; }
|
|
|
|
|
|
module.exports = {
|
|
|
- isLoggedUser: (cookieObject) => {
|
|
|
- return getLoggedUser(cookieObject) !== null;
|
|
|
- },
|
|
|
- getLoggedUser: getLoggedUser,
|
|
|
+ getAccessList: getAccessList,
|
|
|
getRequestIp: getRequestIp,
|
|
|
- getSessionId: (cookieObj) => { return getLoggedUser(cookieObj) ? getSessionId(cookieObj) : null },
|
|
|
- forceLogin: (app, req) => {
|
|
|
- if (!CONFIG.DEBUG_forceLogin)
|
|
|
- throw "Security::ForceLogin: Access Denied";
|
|
|
- const wrongCredentialsMsg = "Invalid username or password";
|
|
|
- return new Promise((ok, ko) => {
|
|
|
- isUserValid(CONFIG.DEBUG_forceLogin).catch(err => {
|
|
|
- ko(err ? ("Internal error: " +err) : wrongCredentialsMsg);
|
|
|
- }).then(sessionInfos => {
|
|
|
- sessionInfos.userAgent = req.headers['user-agent'];
|
|
|
- sessionInfos.instance = CONFIG.instanceHostname;
|
|
|
- sessionInfos.ipAddress = getRequestIp(req);
|
|
|
- let sessionKey = MD5(JSON.stringify(sessionInfos));
|
|
|
- sessionInfos.sessionId = sessionKey;
|
|
|
- loggedCache[sessionKey] = sessionInfos;
|
|
|
- let sessionDbModel = new SessionModel(sessionInfos);
|
|
|
- app.databaseHelper.insertOne(new SessionModel(sessionInfos));
|
|
|
- ok(sessionKey);
|
|
|
- });
|
|
|
- });
|
|
|
+ createSession: req => {
|
|
|
+ const now = Date.now();
|
|
|
+ let sessionInfos = {
|
|
|
+ loginDateTime: now,
|
|
|
+ expire: now + SESSION_TIME,
|
|
|
+ accessList: {},
|
|
|
+ random: Math.random(),
|
|
|
+ userAgent: req.headers['user-agent'],
|
|
|
+ ipAddress: getRequestIp(req)
|
|
|
+ };
|
|
|
+ let sessionKey = MD5(JSON.stringify(sessionInfos));
|
|
|
+ sessionInfos.sessionId = sessionKey;
|
|
|
+ loggedCache[sessionKey] = sessionInfos;
|
|
|
+ req.cookies[SESSION_COOKIE] = sessionKey;
|
|
|
+ return { key: sessionKey, accessList: sessionInfos.accessList };
|
|
|
+ },
|
|
|
+ addLinkToSession: (req, linkId) => {
|
|
|
+ let session = getSessionObj(req.cookies);
|
|
|
+ if (!session)
|
|
|
+ return;
|
|
|
+ let accessList = new LinkAccess(linkId);
|
|
|
+ session.accessList[accessList.id()] = accessList;
|
|
|
+ return session.accessList;
|
|
|
},
|
|
|
- tryLogin: (app, req, username, password) => {
|
|
|
- const wrongCredentialsMsg = "Invalid username or password";
|
|
|
- return new Promise((ok, ko) => {
|
|
|
- isUserValid(username).catch(err => {
|
|
|
- ko(err ? ("Internal error: " +err) : wrongCredentialsMsg);
|
|
|
- }).then(sessionInfos => {
|
|
|
- return checkPassword(sessionInfos.dn, password).then(() => {
|
|
|
- sessionInfos.userAgent = req.headers['user-agent'];
|
|
|
- sessionInfos.instance = CONFIG.instanceHostname;
|
|
|
- sessionInfos.ipAddress = getRequestIp(req);
|
|
|
- let sessionKey = MD5(JSON.stringify(sessionInfos));
|
|
|
- sessionInfos.sessionId = sessionKey;
|
|
|
- loggedCache[sessionKey] = sessionInfos;
|
|
|
- let sessionDbModel = new SessionModel(sessionInfos);
|
|
|
- app.databaseHelper.insertOne(new SessionModel(sessionInfos));
|
|
|
- ok(sessionKey);
|
|
|
- });
|
|
|
- }).catch(err => {
|
|
|
- ko(err ? ("Internal error: " +err) : wrongCredentialsMsg);
|
|
|
- });
|
|
|
- });
|
|
|
+ removeFromSession: (req, accessId) => {
|
|
|
+ let session = getSessionObj(req.cookies);
|
|
|
+ if (!session)
|
|
|
+ return;
|
|
|
+ delete session.accessList[accessId];
|
|
|
+ return session.accessList;
|
|
|
},
|
|
|
- sign: sign,
|
|
|
- checkSign: checkSign,
|
|
|
- generateKeys: generateKeys,
|
|
|
SESSION_COOKIE: SESSION_COOKIE
|
|
|
};
|
|
|
|