alp-node-auth 10.0.0 → 12.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +42 -0
- package/README.md +13 -13
- package/dist/definitions/MongoUsersManager.d.ts +2 -2
- package/dist/definitions/MongoUsersManager.d.ts.map +1 -1
- package/dist/definitions/authApolloContext.d.ts +4 -4
- package/dist/definitions/authApolloContext.d.ts.map +1 -1
- package/dist/definitions/authSocketIO.d.ts +4 -4
- package/dist/definitions/authSocketIO.d.ts.map +1 -1
- package/dist/definitions/createAuthController.d.ts +6 -9
- package/dist/definitions/createAuthController.d.ts.map +1 -1
- package/dist/definitions/createRoutes.d.ts +3 -3
- package/dist/definitions/createRoutes.d.ts.map +1 -1
- package/dist/definitions/index.d.ts +24 -25
- package/dist/definitions/index.d.ts.map +1 -1
- package/dist/definitions/services/authentification/AuthenticationService.d.ts +6 -8
- package/dist/definitions/services/authentification/AuthenticationService.d.ts.map +1 -1
- package/dist/definitions/services/authentification/types.d.ts +3 -3
- package/dist/definitions/services/user/UserAccountGoogleService.d.ts +4 -4
- package/dist/definitions/services/user/UserAccountGoogleService.d.ts.map +1 -1
- package/dist/definitions/services/user/UserAccountSlackService.d.ts +4 -4
- package/dist/definitions/services/user/UserAccountSlackService.d.ts.map +1 -1
- package/dist/definitions/services/user/UserAccountsService.d.ts +6 -7
- package/dist/definitions/services/user/UserAccountsService.d.ts.map +1 -1
- package/dist/definitions/services/user/types.d.ts +1 -1
- package/dist/definitions/types.d.ts +1 -1
- package/dist/definitions/utils/cookies.d.ts +3 -4
- package/dist/definitions/utils/cookies.d.ts.map +1 -1
- package/dist/definitions/utils/createFindLoggedInUser.d.ts +4 -4
- package/dist/definitions/utils/createFindLoggedInUser.d.ts.map +1 -1
- package/dist/{index-node18.mjs → index-node.mjs} +308 -302
- package/dist/index-node.mjs.map +1 -0
- package/package.json +28 -26
- package/src/MongoUsersManager.ts +5 -6
- package/src/authApolloContext.ts +10 -10
- package/src/authSocketIO.ts +10 -10
- package/src/createAuthController.ts +19 -16
- package/src/createRoutes.ts +8 -8
- package/src/index.ts +58 -63
- package/src/services/authentification/AuthenticationService.ts +37 -37
- package/src/services/authentification/types.ts +6 -6
- package/src/services/user/UserAccountGoogleService.ts +8 -9
- package/src/services/user/UserAccountSlackService.ts +8 -9
- package/src/services/user/UserAccountsService.ts +23 -25
- package/src/services/user/types.ts +1 -1
- package/src/types.ts +1 -1
- package/src/utils/cookies.ts +8 -8
- package/src/utils/createFindLoggedInUser.ts +9 -9
- package/src/utils/generators.ts +4 -4
- package/strategies/dropbox.js +7 -7
- package/strategies/facebook.js +7 -7
- package/strategies/foursquare.js +7 -7
- package/strategies/github.js +7 -7
- package/strategies/google.js +7 -7
- package/strategies/slack.js +7 -7
- package/strategies/strategies.d.ts +7 -7
- package/dist/index-node18.mjs.map +0 -1
- package/src/.eslintrc.json +0 -38
- package/strategies/.eslintrc.json +0 -3
|
@@ -8,15 +8,15 @@ import Cookies from 'cookies';
|
|
|
8
8
|
function createAuthController({
|
|
9
9
|
usersManager,
|
|
10
10
|
authenticationService,
|
|
11
|
-
homeRouterKey =
|
|
11
|
+
homeRouterKey = "/",
|
|
12
12
|
defaultStrategy,
|
|
13
13
|
authHooks = {}
|
|
14
14
|
}) {
|
|
15
15
|
return {
|
|
16
16
|
async login(ctx) {
|
|
17
|
-
const strategy = ctx.
|
|
18
|
-
if (!strategy) throw new Error(
|
|
19
|
-
const params = authHooks.paramsForLogin &&
|
|
17
|
+
const strategy = ctx.namedRouteParam("strategy") || defaultStrategy;
|
|
18
|
+
if (!strategy) throw new Error("Strategy missing");
|
|
19
|
+
const params = authHooks.paramsForLogin && await authHooks.paramsForLogin(strategy, ctx) || {};
|
|
20
20
|
await authenticationService.redirectAuthUrl(ctx, strategy, {}, params);
|
|
21
21
|
},
|
|
22
22
|
/**
|
|
@@ -28,25 +28,31 @@ function createAuthController({
|
|
|
28
28
|
ctx.redirectTo(homeRouterKey);
|
|
29
29
|
return;
|
|
30
30
|
}
|
|
31
|
-
const strategy = ctx.
|
|
32
|
-
if (!strategy) throw new Error(
|
|
33
|
-
const scopeKey = ctx.
|
|
34
|
-
if (!scopeKey) throw new Error(
|
|
35
|
-
await authenticationService.redirectAuthUrl(ctx, strategy, {
|
|
36
|
-
scopeKey
|
|
37
|
-
});
|
|
31
|
+
const strategy = ctx.namedRouteParam("strategy") || defaultStrategy;
|
|
32
|
+
if (!strategy) throw new Error("Strategy missing");
|
|
33
|
+
const scopeKey = ctx.namedRouteParam("scopeKey");
|
|
34
|
+
if (!scopeKey) throw new Error("Scope missing");
|
|
35
|
+
await authenticationService.redirectAuthUrl(ctx, strategy, { scopeKey });
|
|
38
36
|
},
|
|
39
37
|
async response(ctx) {
|
|
40
|
-
const strategy = ctx.
|
|
38
|
+
const strategy = ctx.namedRouteParam(
|
|
39
|
+
"strategy"
|
|
40
|
+
);
|
|
41
41
|
ctx.assert(strategy);
|
|
42
|
-
const loggedInUser = await authenticationService.accessResponse(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
const loggedInUser = await authenticationService.accessResponse(
|
|
43
|
+
ctx,
|
|
44
|
+
strategy,
|
|
45
|
+
!!ctx.state.loggedInUser,
|
|
46
|
+
{
|
|
47
|
+
afterLoginSuccess: authHooks.afterLoginSuccess,
|
|
48
|
+
afterScopeUpdate: authHooks.afterScopeUpdate
|
|
49
|
+
}
|
|
50
|
+
);
|
|
46
51
|
const keyPath = usersManager.store.keyPath;
|
|
47
52
|
await ctx.setLoggedIn(loggedInUser[keyPath], loggedInUser);
|
|
48
53
|
ctx.redirectTo(homeRouterKey);
|
|
49
54
|
},
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/require-await -- keep async in case i later need await in this method
|
|
50
56
|
async logout(ctx) {
|
|
51
57
|
ctx.logout();
|
|
52
58
|
ctx.redirectTo(homeRouterKey);
|
|
@@ -54,27 +60,29 @@ function createAuthController({
|
|
|
54
60
|
};
|
|
55
61
|
}
|
|
56
62
|
|
|
57
|
-
const createRoutes = controller => ({
|
|
58
|
-
login: [
|
|
59
|
-
|
|
60
|
-
segment
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
const createRoutes = (controller) => ({
|
|
64
|
+
login: [
|
|
65
|
+
"/login/:strategy?",
|
|
66
|
+
(segment) => {
|
|
67
|
+
segment.add("/response", controller.response, "authResponse");
|
|
68
|
+
segment.defaultRoute(controller.login, "login");
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
addScope: ["/add-scope/:strategy/:scopeKey", controller.addScope],
|
|
72
|
+
logout: ["/logout", controller.logout]
|
|
64
73
|
});
|
|
65
74
|
|
|
66
75
|
const randomBytesPromisified = promisify(randomBytes);
|
|
67
76
|
async function randomHex(size) {
|
|
68
77
|
const buffer = await randomBytesPromisified(size);
|
|
69
|
-
return buffer.toString(
|
|
78
|
+
return buffer.toString("hex");
|
|
70
79
|
}
|
|
71
80
|
|
|
72
|
-
|
|
73
|
-
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
74
|
-
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
75
|
-
/* eslint-disable camelcase, max-lines */
|
|
76
|
-
const logger$4 = new Logger('alp:auth:authentication');
|
|
81
|
+
const logger$4 = new Logger("alp:auth:authentication");
|
|
77
82
|
class AuthenticationService extends EventEmitter {
|
|
83
|
+
config;
|
|
84
|
+
strategies;
|
|
85
|
+
userAccountsService;
|
|
78
86
|
constructor(config, strategies, userAccountsService) {
|
|
79
87
|
super();
|
|
80
88
|
this.config = config;
|
|
@@ -82,88 +90,79 @@ class AuthenticationService extends EventEmitter {
|
|
|
82
90
|
this.userAccountsService = userAccountsService;
|
|
83
91
|
}
|
|
84
92
|
generateAuthUrl(strategy, params) {
|
|
85
|
-
logger$4.debug(
|
|
86
|
-
strategy,
|
|
87
|
-
params
|
|
88
|
-
});
|
|
93
|
+
logger$4.debug("generateAuthUrl", { strategy, params });
|
|
89
94
|
const strategyInstance = this.strategies[strategy];
|
|
90
95
|
switch (strategyInstance.type) {
|
|
91
|
-
case
|
|
96
|
+
case "oauth2":
|
|
92
97
|
return strategyInstance.oauth2.authorizationCode.authorizeURL(params);
|
|
93
98
|
default:
|
|
94
|
-
throw new Error(
|
|
99
|
+
throw new Error("Invalid strategy");
|
|
95
100
|
}
|
|
96
101
|
}
|
|
97
102
|
async getTokens(strategy, options) {
|
|
98
|
-
logger$4.debug(
|
|
99
|
-
strategy,
|
|
100
|
-
options
|
|
101
|
-
});
|
|
103
|
+
logger$4.debug("getTokens", { strategy, options });
|
|
102
104
|
const strategyInstance = this.strategies[strategy];
|
|
103
105
|
switch (strategyInstance.type) {
|
|
104
|
-
case
|
|
105
|
-
|
|
106
|
-
|
|
106
|
+
case "oauth2": {
|
|
107
|
+
const result = await strategyInstance.oauth2.authorizationCode.getToken(
|
|
108
|
+
{
|
|
107
109
|
code: options.code,
|
|
108
110
|
redirect_uri: options.redirectUri
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
if (!result) return result;
|
|
114
|
+
const tokens = result.token;
|
|
115
|
+
return {
|
|
116
|
+
accessToken: tokens.access_token,
|
|
117
|
+
refreshToken: tokens.refresh_token,
|
|
118
|
+
tokenType: tokens.token_type,
|
|
119
|
+
expiresIn: tokens.expires_in,
|
|
120
|
+
expireDate: (() => {
|
|
121
|
+
if (tokens.expires_in == null) return null;
|
|
122
|
+
const d = /* @__PURE__ */ new Date();
|
|
123
|
+
d.setTime(d.getTime() + tokens.expires_in * 1e3);
|
|
124
|
+
return d;
|
|
125
|
+
})(),
|
|
126
|
+
idToken: tokens.id_token
|
|
127
|
+
};
|
|
128
|
+
}
|
|
127
129
|
default:
|
|
128
|
-
throw new Error(
|
|
130
|
+
throw new Error("Invalid stategy");
|
|
129
131
|
}
|
|
130
132
|
}
|
|
131
133
|
async refreshToken(strategy, tokensParam) {
|
|
132
|
-
logger$4.debug(
|
|
133
|
-
strategy
|
|
134
|
-
});
|
|
134
|
+
logger$4.debug("refreshToken", { strategy });
|
|
135
135
|
if (!tokensParam.refreshToken) {
|
|
136
|
-
throw new Error(
|
|
136
|
+
throw new Error("Missing refresh token");
|
|
137
137
|
}
|
|
138
138
|
const strategyInstance = this.strategies[strategy];
|
|
139
139
|
switch (strategyInstance.type) {
|
|
140
|
-
case
|
|
141
|
-
{
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
140
|
+
case "oauth2": {
|
|
141
|
+
const token = strategyInstance.oauth2.clientCredentials.createToken({
|
|
142
|
+
refresh_token: tokensParam.refreshToken
|
|
143
|
+
});
|
|
144
|
+
const result = await token.refresh();
|
|
145
|
+
const tokens = result.token;
|
|
146
|
+
return {
|
|
147
|
+
accessToken: tokens.access_token,
|
|
148
|
+
tokenType: tokens.token_type,
|
|
149
|
+
expiresIn: tokens.expires_in,
|
|
150
|
+
expireDate: (() => {
|
|
151
|
+
if (tokens.expires_in == null) return null;
|
|
152
|
+
const d = /* @__PURE__ */ new Date();
|
|
153
|
+
d.setTime(d.getTime() + tokens.expires_in * 1e3);
|
|
154
|
+
return d;
|
|
155
|
+
})(),
|
|
156
|
+
idToken: tokens.id_token
|
|
157
|
+
};
|
|
158
|
+
}
|
|
160
159
|
default:
|
|
161
|
-
throw new Error(
|
|
160
|
+
throw new Error("Invalid stategy");
|
|
162
161
|
}
|
|
163
162
|
}
|
|
164
163
|
redirectUri(ctx, strategy) {
|
|
165
|
-
const host = `http${this.config.get(
|
|
166
|
-
return `${host}${ctx.urlGenerator(
|
|
164
|
+
const host = `http${this.config.get("allowHttps") ? "s" : ""}://${ctx.request.host}`;
|
|
165
|
+
return `${host}${ctx.urlGenerator("authResponse", {
|
|
167
166
|
strategy
|
|
168
167
|
})}`;
|
|
169
168
|
}
|
|
@@ -173,56 +172,60 @@ class AuthenticationService extends EventEmitter {
|
|
|
173
172
|
user,
|
|
174
173
|
accountId
|
|
175
174
|
}, params) {
|
|
176
|
-
logger$4.debug(
|
|
177
|
-
strategy,
|
|
178
|
-
scopeKey,
|
|
179
|
-
refreshToken
|
|
180
|
-
});
|
|
175
|
+
logger$4.debug("redirectAuthUrl", { strategy, scopeKey, refreshToken });
|
|
181
176
|
const state = await randomHex(8);
|
|
182
|
-
const
|
|
177
|
+
const isLoginAccess = !scopeKey || scopeKey === "login";
|
|
178
|
+
const scope = this.userAccountsService.getScope(
|
|
179
|
+
strategy,
|
|
180
|
+
scopeKey || "login",
|
|
181
|
+
user,
|
|
182
|
+
accountId
|
|
183
|
+
);
|
|
183
184
|
if (!scope) {
|
|
184
|
-
throw new Error(
|
|
185
|
-
}
|
|
186
|
-
ctx.cookies.set(
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
185
|
+
throw new Error("Invalid empty scope");
|
|
186
|
+
}
|
|
187
|
+
ctx.cookies.set(
|
|
188
|
+
`auth_${strategy}_${state}`,
|
|
189
|
+
JSON.stringify({
|
|
190
|
+
scopeKey,
|
|
191
|
+
scope,
|
|
192
|
+
isLoginAccess
|
|
193
|
+
}),
|
|
194
|
+
{
|
|
195
|
+
maxAge: 10 * 60 * 1e3,
|
|
196
|
+
httpOnly: true,
|
|
197
|
+
secure: this.config.get("allowHttps")
|
|
198
|
+
}
|
|
199
|
+
);
|
|
195
200
|
const redirectUri = this.generateAuthUrl(strategy, {
|
|
196
201
|
redirect_uri: this.redirectUri(ctx, strategy),
|
|
197
202
|
scope,
|
|
198
203
|
state,
|
|
199
|
-
access_type: refreshToken ?
|
|
204
|
+
access_type: refreshToken ? "offline" : "online",
|
|
200
205
|
...params
|
|
201
206
|
});
|
|
202
207
|
ctx.redirect(redirectUri);
|
|
203
208
|
}
|
|
204
209
|
async accessResponse(ctx, strategy, isLoggedIn, hooks) {
|
|
205
|
-
const errorParam = ctx.params.queryParam(
|
|
210
|
+
const errorParam = ctx.params.queryParam("error").notEmpty();
|
|
206
211
|
if (errorParam.isValid()) {
|
|
207
|
-
ctx.throw(errorParam.value
|
|
212
|
+
ctx.throw(403, errorParam.value);
|
|
208
213
|
}
|
|
209
|
-
const code = ctx.validParams.queryParam(
|
|
210
|
-
const state = ctx.validParams.queryParam(
|
|
214
|
+
const code = ctx.validParams.queryParam("code").notEmpty().value;
|
|
215
|
+
const state = ctx.validParams.queryParam("state").notEmpty().value;
|
|
211
216
|
const cookieName = `auth_${strategy}_${state}`;
|
|
212
217
|
const cookie = ctx.cookies.get(cookieName);
|
|
213
|
-
ctx.cookies.set(cookieName,
|
|
214
|
-
expires: new Date(1)
|
|
215
|
-
});
|
|
218
|
+
ctx.cookies.set(cookieName, "", { expires: /* @__PURE__ */ new Date(1) });
|
|
216
219
|
if (!cookie) {
|
|
217
|
-
throw new Error(
|
|
220
|
+
throw new Error("No cookie for this state");
|
|
218
221
|
}
|
|
219
222
|
const parsedCookie = JSON.parse(cookie);
|
|
220
223
|
if (!parsedCookie?.scope) {
|
|
221
|
-
throw new Error(
|
|
224
|
+
throw new Error("Unexpected cookie value");
|
|
222
225
|
}
|
|
223
226
|
if (!parsedCookie.isLoginAccess) {
|
|
224
227
|
if (!isLoggedIn) {
|
|
225
|
-
throw new Error(
|
|
228
|
+
throw new Error("You are not connected");
|
|
226
229
|
}
|
|
227
230
|
}
|
|
228
231
|
const tokens = await this.getTokens(strategy, {
|
|
@@ -230,19 +233,32 @@ class AuthenticationService extends EventEmitter {
|
|
|
230
233
|
redirectUri: this.redirectUri(ctx, strategy)
|
|
231
234
|
});
|
|
232
235
|
if (parsedCookie.isLoginAccess) {
|
|
233
|
-
const
|
|
236
|
+
const user2 = await this.userAccountsService.findOrCreateFromStrategy(
|
|
237
|
+
strategy,
|
|
238
|
+
tokens,
|
|
239
|
+
parsedCookie.scope,
|
|
240
|
+
parsedCookie.scopeKey
|
|
241
|
+
);
|
|
234
242
|
if (hooks.afterLoginSuccess) {
|
|
235
|
-
await hooks.afterLoginSuccess(strategy,
|
|
243
|
+
await hooks.afterLoginSuccess(strategy, user2);
|
|
236
244
|
}
|
|
237
|
-
return
|
|
245
|
+
return user2;
|
|
238
246
|
}
|
|
239
247
|
const loggedInUser = ctx.state.loggedInUser;
|
|
240
|
-
const {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
248
|
+
const { account, user } = await this.userAccountsService.update(
|
|
249
|
+
loggedInUser,
|
|
250
|
+
strategy,
|
|
251
|
+
tokens,
|
|
252
|
+
parsedCookie.scope,
|
|
253
|
+
parsedCookie.scopeKey
|
|
254
|
+
);
|
|
244
255
|
if (hooks.afterScopeUpdate) {
|
|
245
|
-
await hooks.afterScopeUpdate(
|
|
256
|
+
await hooks.afterScopeUpdate(
|
|
257
|
+
strategy,
|
|
258
|
+
parsedCookie.scopeKey,
|
|
259
|
+
account,
|
|
260
|
+
user
|
|
261
|
+
);
|
|
246
262
|
}
|
|
247
263
|
return loggedInUser;
|
|
248
264
|
}
|
|
@@ -253,9 +269,8 @@ class AuthenticationService extends EventEmitter {
|
|
|
253
269
|
return this.refreshToken(account.provider, {
|
|
254
270
|
// accessToken: account.accessToken,
|
|
255
271
|
refreshToken: account.refreshToken
|
|
256
|
-
}).then(tokens => {
|
|
272
|
+
}).then((tokens) => {
|
|
257
273
|
if (!tokens) {
|
|
258
|
-
// serviceGoogle.updateFields({ accessToken:null, refreshToken:null, status: .OUTDATED });
|
|
259
274
|
return false;
|
|
260
275
|
}
|
|
261
276
|
account.accessToken = tokens.accessToken;
|
|
@@ -265,53 +280,53 @@ class AuthenticationService extends EventEmitter {
|
|
|
265
280
|
}
|
|
266
281
|
}
|
|
267
282
|
|
|
268
|
-
|
|
269
|
-
const logger$3 = new Logger('alp:auth:userAccounts');
|
|
283
|
+
const logger$3 = new Logger("alp:auth:userAccounts");
|
|
270
284
|
const STATUSES = {
|
|
271
|
-
VALIDATED:
|
|
272
|
-
DELETED:
|
|
285
|
+
VALIDATED: "validated",
|
|
286
|
+
DELETED: "deleted"
|
|
273
287
|
};
|
|
274
288
|
class UserAccountsService extends EventEmitter {
|
|
289
|
+
strategyToService;
|
|
290
|
+
usersManager;
|
|
275
291
|
constructor(usersManager, strategyToService) {
|
|
276
292
|
super();
|
|
277
293
|
this.usersManager = usersManager;
|
|
278
294
|
this.strategyToService = strategyToService;
|
|
279
295
|
}
|
|
280
296
|
getScope(strategy, scopeKey, user, accountId) {
|
|
281
|
-
logger$3.debug(
|
|
282
|
-
strategy,
|
|
283
|
-
userId: user?._id
|
|
284
|
-
});
|
|
297
|
+
logger$3.debug("getScope", { strategy, userId: user?._id });
|
|
285
298
|
const service = this.strategyToService[strategy];
|
|
286
299
|
if (!service) {
|
|
287
|
-
throw new Error(
|
|
300
|
+
throw new Error("Strategy not supported");
|
|
288
301
|
}
|
|
289
302
|
const newScope = service.scopeKeyToScope[scopeKey];
|
|
290
303
|
if (!user || !accountId) {
|
|
291
304
|
return newScope;
|
|
292
305
|
}
|
|
293
|
-
const account = user.accounts.find(
|
|
306
|
+
const account = user.accounts.find(
|
|
307
|
+
(account2) => account2.provider === strategy && account2.accountId === accountId
|
|
308
|
+
);
|
|
294
309
|
if (!account) {
|
|
295
|
-
throw new Error(
|
|
310
|
+
throw new Error("Could not found associated account");
|
|
296
311
|
}
|
|
297
|
-
return service.getScope(account.scope, newScope).join(
|
|
312
|
+
return service.getScope(account.scope, newScope).join(" ");
|
|
298
313
|
}
|
|
299
314
|
async update(user, strategy, tokens, scope, subservice) {
|
|
300
315
|
const service = this.strategyToService[strategy];
|
|
301
316
|
const profile = await service.getProfile(tokens);
|
|
302
317
|
const accountId = service.getId(profile);
|
|
303
|
-
const account = user.accounts.find(
|
|
318
|
+
const account = user.accounts.find(
|
|
319
|
+
(account2) => account2.provider === strategy && account2.accountId === accountId
|
|
320
|
+
);
|
|
304
321
|
if (!account) {
|
|
305
|
-
|
|
306
|
-
// TODO else add a new account in this user
|
|
307
|
-
throw new Error('Could not found associated account');
|
|
322
|
+
throw new Error("Could not found associated account");
|
|
308
323
|
}
|
|
309
|
-
account.status =
|
|
324
|
+
account.status = "valid";
|
|
310
325
|
account.accessToken = tokens.accessToken;
|
|
311
326
|
if (tokens.refreshToken) {
|
|
312
327
|
account.refreshToken = tokens.refreshToken;
|
|
313
328
|
}
|
|
314
|
-
if (tokens.expireDate !==
|
|
329
|
+
if (tokens.expireDate !== void 0) {
|
|
315
330
|
account.tokenExpireDate = tokens.expireDate;
|
|
316
331
|
}
|
|
317
332
|
account.scope = service.getScope(account.scope, scope);
|
|
@@ -320,24 +335,21 @@ class UserAccountsService extends EventEmitter {
|
|
|
320
335
|
account.subservices.push(subservice);
|
|
321
336
|
}
|
|
322
337
|
await this.usersManager.replaceOne(user);
|
|
323
|
-
return {
|
|
324
|
-
user,
|
|
325
|
-
account
|
|
326
|
-
};
|
|
338
|
+
return { user, account };
|
|
327
339
|
}
|
|
328
340
|
async findOrCreateFromStrategy(strategy, tokens, scope, subservice) {
|
|
329
341
|
const service = this.strategyToService[strategy];
|
|
330
|
-
if (!service) throw new Error(
|
|
342
|
+
if (!service) throw new Error("Strategy not supported");
|
|
331
343
|
const profile = await service.getProfile(tokens);
|
|
332
344
|
const accountId = service.getId(profile);
|
|
333
|
-
if (!accountId) throw new Error(
|
|
345
|
+
if (!accountId) throw new Error("Invalid profile: no id found");
|
|
334
346
|
const emails = service.getEmails(profile);
|
|
335
347
|
let user = await this.usersManager.findOneByAccountOrEmails({
|
|
336
348
|
provider: service.providerKey,
|
|
337
349
|
accountId,
|
|
338
350
|
emails
|
|
339
351
|
});
|
|
340
|
-
logger$3.info(!user ?
|
|
352
|
+
logger$3.info(!user ? "create user" : "existing user", {
|
|
341
353
|
userId: user?._id,
|
|
342
354
|
accountId
|
|
343
355
|
/*emails , user*/
|
|
@@ -351,23 +363,21 @@ class UserAccountsService extends EventEmitter {
|
|
|
351
363
|
status: STATUSES.VALIDATED
|
|
352
364
|
});
|
|
353
365
|
if (!user.accounts) user.accounts = [];
|
|
354
|
-
let account = user.accounts.find(
|
|
366
|
+
let account = user.accounts.find(
|
|
367
|
+
(account2) => account2.provider === strategy && account2.accountId === accountId
|
|
368
|
+
);
|
|
355
369
|
if (!account) {
|
|
356
|
-
account = {
|
|
357
|
-
provider: strategy,
|
|
358
|
-
accountId
|
|
359
|
-
};
|
|
360
|
-
// @ts-expect-error well...
|
|
370
|
+
account = { provider: strategy, accountId };
|
|
361
371
|
user.accounts.push(account);
|
|
362
372
|
}
|
|
363
373
|
account.name = service.getAccountName(profile);
|
|
364
|
-
account.status =
|
|
374
|
+
account.status = "valid";
|
|
365
375
|
account.profile = profile;
|
|
366
376
|
account.accessToken = tokens.accessToken;
|
|
367
377
|
if (tokens.refreshToken) {
|
|
368
378
|
account.refreshToken = tokens.refreshToken;
|
|
369
379
|
}
|
|
370
|
-
if (tokens.expireDate !==
|
|
380
|
+
if (tokens.expireDate !== void 0) {
|
|
371
381
|
account.tokenExpireDate = tokens.expireDate;
|
|
372
382
|
}
|
|
373
383
|
account.scope = service.getScope(account.scope, scope);
|
|
@@ -377,14 +387,18 @@ class UserAccountsService extends EventEmitter {
|
|
|
377
387
|
}
|
|
378
388
|
if (!user.emails) user.emails = [];
|
|
379
389
|
const userEmails = user.emails;
|
|
380
|
-
emails.forEach(email => {
|
|
390
|
+
emails.forEach((email) => {
|
|
381
391
|
if (!userEmails.includes(email)) {
|
|
382
392
|
userEmails.push(email);
|
|
383
393
|
}
|
|
384
394
|
});
|
|
385
395
|
user.emailDomains = [
|
|
386
|
-
|
|
387
|
-
|
|
396
|
+
// eslint-disable-next-line unicorn/no-array-reduce
|
|
397
|
+
...user.emails.reduce(
|
|
398
|
+
(domains, email) => domains.add(email.split("@", 2)[1]),
|
|
399
|
+
/* @__PURE__ */ new Set()
|
|
400
|
+
)
|
|
401
|
+
];
|
|
388
402
|
const keyPath = this.usersManager.store.keyPath;
|
|
389
403
|
if (user[keyPath]) {
|
|
390
404
|
await this.usersManager.replaceOne(user);
|
|
@@ -399,14 +413,12 @@ class UserAccountsService extends EventEmitter {
|
|
|
399
413
|
}
|
|
400
414
|
}
|
|
401
415
|
|
|
402
|
-
const COOKIE_NAME_TOKEN =
|
|
403
|
-
const COOKIE_NAME_STATE =
|
|
416
|
+
const COOKIE_NAME_TOKEN = "loggedInUserToken";
|
|
417
|
+
const COOKIE_NAME_STATE = "loggedInUserState";
|
|
404
418
|
const getTokenFromRequest = (req, options) => {
|
|
405
|
-
if (req.headers.authorization?.startsWith(
|
|
406
|
-
return req.headers.authorization.slice(
|
|
419
|
+
if (req.headers.authorization?.startsWith("Bearer ")) {
|
|
420
|
+
return req.headers.authorization.slice("Bearer ".length);
|
|
407
421
|
}
|
|
408
|
-
|
|
409
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
410
422
|
const cookies = new Cookies(req, null, {
|
|
411
423
|
...options,
|
|
412
424
|
secure: true
|
|
@@ -415,37 +427,36 @@ const getTokenFromRequest = (req, options) => {
|
|
|
415
427
|
};
|
|
416
428
|
|
|
417
429
|
const verifyPromisified = promisify(jsonwebtoken.verify);
|
|
418
|
-
const createDecodeJWT = secretKey => async (token, jwtAudience) => {
|
|
430
|
+
const createDecodeJWT = (secretKey) => async (token, jwtAudience) => {
|
|
419
431
|
const result = await verifyPromisified(token, secretKey, {
|
|
420
|
-
algorithms: [
|
|
432
|
+
algorithms: ["HS512"],
|
|
421
433
|
audience: jwtAudience
|
|
422
434
|
});
|
|
423
435
|
return result?.loggedInUserId;
|
|
424
436
|
};
|
|
425
437
|
const createFindLoggedInUser = (secretKey, usersManager, logger) => {
|
|
426
438
|
const decodeJwt = createDecodeJWT(secretKey);
|
|
427
|
-
|
|
439
|
+
const findLoggedInUser = async (jwtAudience, token) => {
|
|
428
440
|
if (!token || !jwtAudience) return [null, null];
|
|
429
441
|
let loggedInUserId;
|
|
430
442
|
try {
|
|
431
443
|
loggedInUserId = await decodeJwt(token, jwtAudience);
|
|
432
444
|
} catch (error) {
|
|
433
|
-
logger.debug(
|
|
434
|
-
err: error
|
|
435
|
-
});
|
|
445
|
+
logger.debug("failed to verify authentification", { err: error });
|
|
436
446
|
}
|
|
437
447
|
if (loggedInUserId == null) return [null, null];
|
|
438
448
|
const loggedInUser = await usersManager.findById(loggedInUserId);
|
|
439
449
|
if (!loggedInUser) return [null, null];
|
|
440
450
|
return [loggedInUserId, loggedInUser];
|
|
441
451
|
};
|
|
452
|
+
return findLoggedInUser;
|
|
442
453
|
};
|
|
443
454
|
|
|
444
455
|
class MongoUsersManager {
|
|
456
|
+
store;
|
|
445
457
|
constructor(store) {
|
|
446
458
|
this.store = store;
|
|
447
459
|
}
|
|
448
|
-
|
|
449
460
|
/** @deprecated use findById instead */
|
|
450
461
|
findConnected(connected) {
|
|
451
462
|
return this.store.findByKey(connected);
|
|
@@ -468,26 +479,25 @@ class MongoUsersManager {
|
|
|
468
479
|
provider
|
|
469
480
|
}) {
|
|
470
481
|
let query = {
|
|
471
|
-
|
|
472
|
-
|
|
482
|
+
"accounts.provider": provider,
|
|
483
|
+
"accounts.accountId": accountId
|
|
473
484
|
};
|
|
474
485
|
if (emails && emails.length > 0) {
|
|
475
486
|
query = {
|
|
476
|
-
$or: [
|
|
477
|
-
|
|
478
|
-
|
|
487
|
+
$or: [
|
|
488
|
+
query,
|
|
489
|
+
{
|
|
490
|
+
emails: { $in: emails }
|
|
479
491
|
}
|
|
480
|
-
|
|
492
|
+
]
|
|
481
493
|
};
|
|
482
494
|
}
|
|
483
|
-
|
|
484
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
485
495
|
return this.store.findOne(query);
|
|
486
496
|
}
|
|
487
497
|
updateAccount(user, account) {
|
|
488
498
|
const accountIndex = user.accounts.indexOf(account);
|
|
489
499
|
if (accountIndex === -1) {
|
|
490
|
-
throw new Error(
|
|
500
|
+
throw new Error("Invalid account");
|
|
491
501
|
}
|
|
492
502
|
return this.store.partialUpdateOne(user, {
|
|
493
503
|
$set: {
|
|
@@ -495,8 +505,6 @@ class MongoUsersManager {
|
|
|
495
505
|
}
|
|
496
506
|
});
|
|
497
507
|
}
|
|
498
|
-
|
|
499
|
-
// eslint-disable-next-line @typescript-eslint/class-methods-use-this
|
|
500
508
|
sanitizeBaseUser(user) {
|
|
501
509
|
return {
|
|
502
510
|
_id: user._id,
|
|
@@ -507,7 +515,7 @@ class MongoUsersManager {
|
|
|
507
515
|
status: user.status,
|
|
508
516
|
emails: user.emails,
|
|
509
517
|
emailDomains: user.emailDomains,
|
|
510
|
-
accounts: user.accounts.map(account => ({
|
|
518
|
+
accounts: user.accounts.map((account) => ({
|
|
511
519
|
provider: account.provider,
|
|
512
520
|
accountId: account.accountId,
|
|
513
521
|
name: account.name,
|
|
@@ -518,20 +526,19 @@ class MongoUsersManager {
|
|
|
518
526
|
}
|
|
519
527
|
}
|
|
520
528
|
|
|
521
|
-
/* eslint-disable @typescript-eslint/class-methods-use-this */
|
|
522
|
-
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
523
|
-
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
524
|
-
|
|
525
529
|
class UserAccountGoogleService {
|
|
530
|
+
scopeKeyToScope;
|
|
526
531
|
constructor(scopeKeyToScope) {
|
|
527
532
|
this.scopeKeyToScope = {
|
|
528
533
|
...scopeKeyToScope,
|
|
529
|
-
login:
|
|
534
|
+
login: "openid profile email"
|
|
530
535
|
};
|
|
531
536
|
}
|
|
532
|
-
providerKey =
|
|
537
|
+
providerKey = "google";
|
|
533
538
|
getProfile(tokens) {
|
|
534
|
-
return fetch(
|
|
539
|
+
return fetch(
|
|
540
|
+
`https://www.googleapis.com/oauth2/v1/userinfo?access_token=${tokens.accessToken}`
|
|
541
|
+
).then((response) => response.json());
|
|
535
542
|
}
|
|
536
543
|
getId(profile) {
|
|
537
544
|
return profile.id;
|
|
@@ -556,28 +563,28 @@ class UserAccountGoogleService {
|
|
|
556
563
|
};
|
|
557
564
|
}
|
|
558
565
|
getDefaultScope(newScope) {
|
|
559
|
-
return this.getScope(
|
|
566
|
+
return this.getScope(void 0, newScope);
|
|
560
567
|
}
|
|
561
568
|
getScope(oldScope, newScope) {
|
|
562
|
-
return !oldScope ? newScope.split(
|
|
569
|
+
return !oldScope ? newScope.split(" ") : [...oldScope, ...newScope.split(" ")].filter(
|
|
570
|
+
(item, i, ar) => ar.indexOf(item) === i
|
|
571
|
+
);
|
|
563
572
|
}
|
|
564
573
|
}
|
|
565
574
|
|
|
566
|
-
/* eslint-disable @typescript-eslint/class-methods-use-this */
|
|
567
|
-
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
568
|
-
|
|
569
|
-
// https://api.slack.com/methods/users.identity
|
|
570
|
-
|
|
571
575
|
class UserAccountSlackService {
|
|
576
|
+
scopeKeyToScope;
|
|
572
577
|
constructor(scopeKeyToScope) {
|
|
573
578
|
this.scopeKeyToScope = {
|
|
574
579
|
...scopeKeyToScope,
|
|
575
|
-
login:
|
|
580
|
+
login: "identity.basic identity.email identity.avatar"
|
|
576
581
|
};
|
|
577
582
|
}
|
|
578
|
-
providerKey =
|
|
583
|
+
providerKey = "google";
|
|
579
584
|
getProfile(tokens) {
|
|
580
|
-
return fetch(
|
|
585
|
+
return fetch(
|
|
586
|
+
`https://slack.com/api/users.identity?token=${tokens.accessToken}`
|
|
587
|
+
).then((response) => response.json());
|
|
581
588
|
}
|
|
582
589
|
getId(profile) {
|
|
583
590
|
if (!profile?.team?.id || !profile.user?.id) {
|
|
@@ -594,78 +601,73 @@ class UserAccountSlackService {
|
|
|
594
601
|
getDisplayName(profile) {
|
|
595
602
|
return profile.user.name;
|
|
596
603
|
}
|
|
597
|
-
getFullName() {
|
|
604
|
+
getFullName(profile) {
|
|
598
605
|
return null;
|
|
599
606
|
}
|
|
600
607
|
getDefaultScope(newScope) {
|
|
601
|
-
return this.getScope(
|
|
608
|
+
return this.getScope(void 0, newScope);
|
|
602
609
|
}
|
|
603
610
|
getScope(oldScope, newScope) {
|
|
604
|
-
return !oldScope ? newScope.split(
|
|
611
|
+
return !oldScope ? newScope.split(" ") : [...oldScope, ...newScope.split(" ")].filter(
|
|
612
|
+
(item, i, ar) => ar.indexOf(item) === i
|
|
613
|
+
);
|
|
605
614
|
}
|
|
606
615
|
}
|
|
607
616
|
|
|
608
|
-
const logger$2 = new Logger(
|
|
617
|
+
const logger$2 = new Logger("alp:auth");
|
|
609
618
|
const authSocketIO = (app, usersManager, io, jwtAudience) => {
|
|
610
|
-
const findLoggedInUser = createFindLoggedInUser(
|
|
611
|
-
|
|
619
|
+
const findLoggedInUser = createFindLoggedInUser(
|
|
620
|
+
app.config.get("authentication").secretKey,
|
|
621
|
+
usersManager,
|
|
622
|
+
logger$2
|
|
623
|
+
);
|
|
624
|
+
const users = /* @__PURE__ */ new Map();
|
|
612
625
|
io.users = users;
|
|
613
626
|
io.use(async (socket, next) => {
|
|
614
627
|
const handshakeData = socket.request;
|
|
615
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
616
628
|
const token = getTokenFromRequest(handshakeData);
|
|
617
629
|
if (!token) return next();
|
|
618
630
|
const [loggedInUserId, loggedInUser] = await findLoggedInUser(
|
|
619
|
-
|
|
620
|
-
|
|
631
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
632
|
+
jwtAudience || handshakeData.headers["user-agent"],
|
|
633
|
+
token
|
|
634
|
+
);
|
|
621
635
|
if (!loggedInUserId || !loggedInUser) return next();
|
|
622
636
|
socket.user = loggedInUser;
|
|
623
637
|
users.set(socket.client.id, loggedInUser);
|
|
624
|
-
socket.on(
|
|
638
|
+
socket.on("disconnected", () => users.delete(socket.client.id));
|
|
625
639
|
await next();
|
|
626
640
|
});
|
|
627
641
|
};
|
|
628
642
|
|
|
629
|
-
const logger$1 = new Logger(
|
|
630
|
-
const getTokenFromReq = req => {
|
|
643
|
+
const logger$1 = new Logger("alp:auth");
|
|
644
|
+
const getTokenFromReq = (req) => {
|
|
631
645
|
if (req.cookies) return req.cookies[COOKIE_NAME_TOKEN];
|
|
632
646
|
return getTokenFromRequest(req);
|
|
633
647
|
};
|
|
634
|
-
|
|
635
|
-
/*
|
|
636
|
-
* Not tested yet.
|
|
637
|
-
* @internal
|
|
638
|
-
*/
|
|
639
648
|
const createAuthApolloContext = (config, usersManager) => {
|
|
640
|
-
const findLoggedInUser = createFindLoggedInUser(
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
649
|
+
const findLoggedInUser = createFindLoggedInUser(
|
|
650
|
+
config.get("authentication").secretKey,
|
|
651
|
+
usersManager,
|
|
652
|
+
logger$1
|
|
653
|
+
);
|
|
654
|
+
return async ({ req, connection }) => {
|
|
645
655
|
if (connection?.loggedInUser) {
|
|
646
|
-
return {
|
|
647
|
-
user: connection.loggedInUser
|
|
648
|
-
};
|
|
656
|
+
return { user: connection.loggedInUser };
|
|
649
657
|
}
|
|
650
658
|
if (!req) return null;
|
|
651
|
-
|
|
652
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
653
659
|
const token = getTokenFromReq(req);
|
|
654
|
-
if (!token) return {
|
|
655
|
-
user: undefined
|
|
656
|
-
};
|
|
660
|
+
if (!token) return { user: void 0 };
|
|
657
661
|
const [, loggedInUser] = await findLoggedInUser(
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
};
|
|
662
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
663
|
+
req.headers["user-agent"],
|
|
664
|
+
token
|
|
665
|
+
);
|
|
666
|
+
return { user: loggedInUser };
|
|
663
667
|
};
|
|
664
668
|
};
|
|
665
669
|
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
const logger = new Logger('alp:auth');
|
|
670
|
+
const logger = new Logger("alp:auth");
|
|
669
671
|
const signPromisified = promisify(jsonwebtoken.sign);
|
|
670
672
|
function init({
|
|
671
673
|
homeRouterKey,
|
|
@@ -676,10 +678,16 @@ function init({
|
|
|
676
678
|
authHooks,
|
|
677
679
|
jwtAudience
|
|
678
680
|
}) {
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
681
|
+
return (app) => {
|
|
682
|
+
const userAccountsService = new UserAccountsService(
|
|
683
|
+
usersManager,
|
|
684
|
+
strategyToService
|
|
685
|
+
);
|
|
686
|
+
const authenticationService = new AuthenticationService(
|
|
687
|
+
app.config,
|
|
688
|
+
strategies,
|
|
689
|
+
userAccountsService
|
|
690
|
+
);
|
|
683
691
|
const controller = createAuthController({
|
|
684
692
|
usersManager,
|
|
685
693
|
authenticationService,
|
|
@@ -687,82 +695,80 @@ function init({
|
|
|
687
695
|
defaultStrategy,
|
|
688
696
|
authHooks
|
|
689
697
|
});
|
|
690
|
-
app.context.setLoggedIn = async function (loggedInUserId, loggedInUser) {
|
|
691
|
-
logger.debug(
|
|
692
|
-
loggedInUser
|
|
693
|
-
});
|
|
698
|
+
app.context.setLoggedIn = async function setLoggedIn(loggedInUserId, loggedInUser) {
|
|
699
|
+
logger.debug("setLoggedIn", { loggedInUser });
|
|
694
700
|
if (!loggedInUserId) {
|
|
695
|
-
throw new Error(
|
|
701
|
+
throw new Error("Illegal value for setLoggedIn");
|
|
696
702
|
}
|
|
697
703
|
this.state.loggedInUserId = loggedInUserId;
|
|
698
704
|
this.state.loggedInUser = loggedInUser;
|
|
699
|
-
const token = await signPromisified(
|
|
700
|
-
loggedInUserId,
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
705
|
+
const token = await signPromisified(
|
|
706
|
+
{ loggedInUserId, time: Date.now() },
|
|
707
|
+
this.config.get("authentication").get("secretKey"),
|
|
708
|
+
{
|
|
709
|
+
algorithm: "HS512",
|
|
710
|
+
audience: jwtAudience || this.request.headers["user-agent"],
|
|
711
|
+
expiresIn: "30 days"
|
|
712
|
+
}
|
|
713
|
+
);
|
|
714
|
+
const calcExpiresTime = () => {
|
|
715
|
+
const date = /* @__PURE__ */ new Date();
|
|
716
|
+
date.setDate(date.getDate() + 30);
|
|
717
|
+
return date.getTime();
|
|
718
|
+
};
|
|
708
719
|
this.cookies.set(COOKIE_NAME_TOKEN, token, {
|
|
709
720
|
httpOnly: true,
|
|
710
|
-
secure: this.config.get(
|
|
711
|
-
});
|
|
712
|
-
this.cookies.set(COOKIE_NAME_STATE, JSON.stringify({
|
|
713
|
-
loggedInUserId,
|
|
714
|
-
expiresIn: (() => {
|
|
715
|
-
const date = new Date();
|
|
716
|
-
date.setDate(date.getDate() + 30);
|
|
717
|
-
return date.getTime();
|
|
718
|
-
})()
|
|
719
|
-
}), {
|
|
720
|
-
httpOnly: false,
|
|
721
|
-
secure: this.config.get('allowHttps')
|
|
721
|
+
secure: this.config.get("allowHttps")
|
|
722
722
|
});
|
|
723
|
+
this.cookies.set(
|
|
724
|
+
COOKIE_NAME_STATE,
|
|
725
|
+
JSON.stringify({ loggedInUserId, expiresIn: calcExpiresTime() }),
|
|
726
|
+
{
|
|
727
|
+
httpOnly: false,
|
|
728
|
+
secure: this.config.get("allowHttps")
|
|
729
|
+
}
|
|
730
|
+
);
|
|
723
731
|
};
|
|
724
|
-
app.context.logout = function () {
|
|
732
|
+
app.context.logout = function logout() {
|
|
725
733
|
delete this.state.loggedInUserId;
|
|
726
734
|
delete this.state.loggedInUser;
|
|
727
|
-
this.cookies.set(COOKIE_NAME_TOKEN,
|
|
728
|
-
|
|
729
|
-
});
|
|
730
|
-
this.cookies.set(COOKIE_NAME_STATE, '', {
|
|
731
|
-
expires: new Date(1)
|
|
732
|
-
});
|
|
735
|
+
this.cookies.set(COOKIE_NAME_TOKEN, "", { expires: /* @__PURE__ */ new Date(1) });
|
|
736
|
+
this.cookies.set(COOKIE_NAME_STATE, "", { expires: /* @__PURE__ */ new Date(1) });
|
|
733
737
|
};
|
|
734
|
-
const findLoggedInUser = createFindLoggedInUser(
|
|
738
|
+
const findLoggedInUser = createFindLoggedInUser(
|
|
739
|
+
app.config.get("authentication").secretKey,
|
|
740
|
+
usersManager,
|
|
741
|
+
logger
|
|
742
|
+
);
|
|
735
743
|
return {
|
|
736
744
|
routes: createRoutes(controller),
|
|
737
|
-
findLoggedInUserFromRequest: req => {
|
|
745
|
+
findLoggedInUserFromRequest: (req) => {
|
|
738
746
|
const token = getTokenFromRequest(req);
|
|
739
|
-
return findLoggedInUser(
|
|
747
|
+
return findLoggedInUser(
|
|
748
|
+
jwtAudience || req.headers["user-agent"],
|
|
749
|
+
token
|
|
750
|
+
);
|
|
740
751
|
},
|
|
741
752
|
findLoggedInUser,
|
|
742
753
|
middleware: async (ctx, next) => {
|
|
743
754
|
const token = ctx.cookies.get(COOKIE_NAME_TOKEN);
|
|
744
|
-
const userAgent = ctx.request.headers[
|
|
745
|
-
logger.debug(
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
ctx.
|
|
750
|
-
ctx.
|
|
751
|
-
ctx.sanitizedState.loggedInUserId = loggedInUserId;
|
|
752
|
-
ctx.sanitizedState.loggedInUser = loggedInUser && usersManager.sanitize(loggedInUser);
|
|
755
|
+
const userAgent = ctx.request.headers["user-agent"];
|
|
756
|
+
logger.debug("middleware", { token });
|
|
757
|
+
const setState = (loggedInUserId2, loggedInUser2) => {
|
|
758
|
+
ctx.state.loggedInUserId = loggedInUserId2;
|
|
759
|
+
ctx.state.user = loggedInUser2;
|
|
760
|
+
ctx.sanitizedState.loggedInUserId = loggedInUserId2;
|
|
761
|
+
ctx.sanitizedState.loggedInUser = loggedInUser2 && usersManager.sanitize(loggedInUser2);
|
|
753
762
|
};
|
|
754
|
-
const [loggedInUserId, loggedInUser] = await findLoggedInUser(
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
763
|
+
const [loggedInUserId, loggedInUser] = await findLoggedInUser(
|
|
764
|
+
jwtAudience || userAgent,
|
|
765
|
+
token
|
|
766
|
+
);
|
|
767
|
+
logger.debug("middleware", { loggedInUserId });
|
|
758
768
|
if (loggedInUserId == null || loggedInUser == null) {
|
|
759
769
|
if (token) {
|
|
760
|
-
ctx.cookies.set(COOKIE_NAME_TOKEN,
|
|
761
|
-
|
|
762
|
-
});
|
|
763
|
-
ctx.cookies.set(COOKIE_NAME_STATE, '', {
|
|
764
|
-
expires: new Date(1)
|
|
765
|
-
});
|
|
770
|
+
ctx.cookies.set(COOKIE_NAME_TOKEN, "", { expires: /* @__PURE__ */ new Date(1) });
|
|
771
|
+
ctx.cookies.set(COOKIE_NAME_STATE, "", { expires: /* @__PURE__ */ new Date(1) });
|
|
766
772
|
}
|
|
767
773
|
setState(null, null);
|
|
768
774
|
return next();
|
|
@@ -775,4 +781,4 @@ function init({
|
|
|
775
781
|
}
|
|
776
782
|
|
|
777
783
|
export { AuthenticationService, MongoUsersManager, STATUSES, UserAccountGoogleService, UserAccountSlackService, authSocketIO, createAuthApolloContext, init as default };
|
|
778
|
-
//# sourceMappingURL=index-
|
|
784
|
+
//# sourceMappingURL=index-node.mjs.map
|