-
Notifications
You must be signed in to change notification settings - Fork 40
/
Copy pathsessions.js
78 lines (63 loc) · 2.76 KB
/
sessions.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/**
* Copyright (C) 2021 3D Repo Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
const { CSRF_COOKIE, CSRF_HEADER, SESSION_HEADER } = require('./sessions.constants');
const { cookie, cookie_domain } = require('./config');
const { escapeRegexChrs, getURLDomain } = require('./helper/strings');
const { apiUrls } = require('./config');
const { deleteIfUndefined } = require('./helper/objects');
const { events } = require('../services/eventsManager/eventsManager.constants');
const { publish } = require('../services/eventsManager/eventsManager');
const { validateAndRefreshToken } = require('../services/sso/frontegg');
const referrerMatch = (sessionReferrer, headerReferrer) => {
const domain = getURLDomain(headerReferrer);
return domain === sessionReferrer
|| apiUrls.all.some((api) => api.match(escapeRegexChrs(domain)));
};
const SessionUtils = {};
const validateCookie = async (session, cookies, headers) => {
const referrerMatched = !headers.referer || referrerMatch(session.user.referer, headers.referer);
const headerToken = headers[CSRF_HEADER] || headers[CSRF_HEADER.toLowerCase()];
const csrfMatched = !!session.token && (headerToken === session.token);
const internalSessionValid = csrfMatched && referrerMatched;
if (internalSessionValid) {
try {
const user = await validateAndRefreshToken(session.user.auth.tokenInfo);
return user.sub === session.user.auth.userId;
} catch (err) {
return false;
}
}
return false;
};
SessionUtils.isSessionValid = (session, cookies, headers, ignoreApiKey = false) => {
const user = session?.user;
if (user) {
return session.user.isAPIKey ? !ignoreApiKey
: validateCookie(session, cookies, headers);
}
return Promise.resolve(false);
};
SessionUtils.getUserFromSession = ({ user } = {}) => (user ? user.username : undefined);
SessionUtils.destroySession = (session, res, callback, elective) => {
session.destroy(() => {
res.clearCookie(CSRF_COOKIE, { domain: cookie.domain });
res.clearCookie(SESSION_HEADER, { domain: cookie_domain, path: '/' });
publish(events.SESSIONS_REMOVED, deleteIfUndefined({ ids: [session.id], elective }));
callback();
});
};
module.exports = SessionUtils;