alp-node-auth 6.0.8 → 6.1.1
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 +20 -0
- package/README.md +3 -0
- package/dist/authSocketIO.d.ts +1 -1
- package/dist/authSocketIO.d.ts.map +1 -1
- package/dist/index-node14.mjs +26 -132
- package/dist/index-node14.mjs.map +1 -1
- package/dist/utils/cookies.d.ts +1 -1
- package/dist/utils/cookies.d.ts.map +1 -1
- package/package.json +15 -15
- package/src/.eslintrc.json +3 -2
- package/rollup.config.mjs +0 -5
- package/tsconfig.eslint.json +0 -7
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,26 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [6.1.1](https://github.com/christophehurpeau/alp/compare/alp-node-auth@6.1.0...alp-node-auth@6.1.1) (2022-10-19)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package alp-node-auth
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# [6.1.0](https://github.com/christophehurpeau/alp/compare/alp-node-auth@6.0.8...alp-node-auth@6.1.0) (2022-10-16)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* **deps:** update dependency liwi-mongo to v9 ([#339](https://github.com/christophehurpeau/alp/issues/339)) ([14fa557](https://github.com/christophehurpeau/alp/commit/14fa55719c5623cdbc2f2da6909fdea35eb3658e))
|
|
20
|
+
* update to react 18 ([6ac42b8](https://github.com/christophehurpeau/alp/commit/6ac42b84b80bf76853773f3b93819666684327d1))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
6
26
|
## [6.0.8](https://github.com/christophehurpeau/alp/compare/alp-node-auth@6.0.7...alp-node-auth@6.0.8) (2022-10-13)
|
|
7
27
|
|
|
8
28
|
**Note:** Version bump only for package alp-node-auth
|
package/README.md
CHANGED
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
<p align="center">
|
|
10
10
|
<a href="https://npmjs.org/package/alp-node-auth"><img src="https://img.shields.io/npm/v/alp-node-auth.svg?style=flat-square"></a>
|
|
11
|
+
<a href="https://npmjs.org/package/alp-node-auth"><img src="https://img.shields.io/npm/dw/alp-node-auth.svg?style=flat-square"></a>
|
|
12
|
+
<a href="https://npmjs.org/package/alp-node-auth"><img src="https://img.shields.io/node/v/alp-node-auth.svg?style=flat-square"></a>
|
|
13
|
+
<a href="https://npmjs.org/package/alp-node-auth"><img src="https://img.shields.io/npm/types/alp-node-auth.svg?style=flat-square"></a>
|
|
11
14
|
</p>
|
|
12
15
|
|
|
13
16
|
## Install
|
package/dist/authSocketIO.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ import type { NodeApplication } from 'alp-types';
|
|
|
2
2
|
import type { Option } from 'cookies';
|
|
3
3
|
import type { User } from '../types.d';
|
|
4
4
|
import type MongoUsersManager from './MongoUsersManager';
|
|
5
|
-
export declare const authSocketIO: <U extends User = User>(app: NodeApplication, usersManager: MongoUsersManager<U, import("../types.d").UserSanitized>, io: any, options?: Pick<Option,
|
|
5
|
+
export declare const authSocketIO: <U extends User = User>(app: NodeApplication, usersManager: MongoUsersManager<U, import("../types.d").UserSanitized>, io: any, options?: Pick<Option, Exclude<keyof Option, 'secure'>>) => void;
|
|
6
6
|
//# sourceMappingURL=authSocketIO.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authSocketIO.d.ts","sourceRoot":"","sources":["../src/authSocketIO.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,iBAAiB,MAAM,qBAAqB,CAAC;AAMzD,eAAO,MAAM,YAAY,+BAClB,eAAe,8EAGhB,GAAG,
|
|
1
|
+
{"version":3,"file":"authSocketIO.d.ts","sourceRoot":"","sources":["../src/authSocketIO.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,iBAAiB,MAAM,qBAAqB,CAAC;AAMzD,eAAO,MAAM,YAAY,+BAClB,eAAe,8EAGhB,GAAG,YACG,KAAK,MAAM,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,CAAC,CAAC,KACtD,IAgCF,CAAC"}
|
package/dist/index-node14.mjs
CHANGED
|
@@ -21,13 +21,11 @@ function createAuthController({
|
|
|
21
21
|
const params = authHooks.paramsForLogin && (await authHooks.paramsForLogin(strategy, ctx)) || {};
|
|
22
22
|
await authenticationService.redirectAuthUrl(ctx, strategy, {}, params);
|
|
23
23
|
},
|
|
24
|
-
|
|
25
24
|
async addScope(ctx) {
|
|
26
25
|
if (ctx.state.connected) {
|
|
27
26
|
await ctx.redirectTo(homeRouterKey);
|
|
28
27
|
return;
|
|
29
28
|
}
|
|
30
|
-
|
|
31
29
|
const strategy = ctx.namedParam('strategy') || defaultStrategy;
|
|
32
30
|
if (!strategy) throw new Error('Strategy missing');
|
|
33
31
|
const scopeKey = ctx.namedParam('scopeKey');
|
|
@@ -36,13 +34,11 @@ function createAuthController({
|
|
|
36
34
|
scopeKey
|
|
37
35
|
});
|
|
38
36
|
},
|
|
39
|
-
|
|
40
37
|
async loginResponse(ctx) {
|
|
41
38
|
if (ctx.state.connected) {
|
|
42
39
|
await ctx.redirectTo(homeRouterKey);
|
|
43
40
|
return;
|
|
44
41
|
}
|
|
45
|
-
|
|
46
42
|
const strategy = ctx.namedParam('strategy');
|
|
47
43
|
ctx.assert(strategy);
|
|
48
44
|
const connectedUser = await authenticationService.accessResponse(ctx, strategy, ctx.state.connected, {
|
|
@@ -53,12 +49,10 @@ function createAuthController({
|
|
|
53
49
|
await ctx.setConnected(connectedUser[keyPath], connectedUser);
|
|
54
50
|
await ctx.redirectTo(homeRouterKey);
|
|
55
51
|
},
|
|
56
|
-
|
|
57
52
|
async logout(ctx) {
|
|
58
53
|
ctx.logout();
|
|
59
54
|
await ctx.redirectTo(homeRouterKey);
|
|
60
55
|
}
|
|
61
|
-
|
|
62
56
|
};
|
|
63
57
|
}
|
|
64
58
|
|
|
@@ -86,30 +80,25 @@ class AuthenticationService extends EventEmitter {
|
|
|
86
80
|
this.strategies = strategies;
|
|
87
81
|
this.userAccountsService = userAccountsService;
|
|
88
82
|
}
|
|
89
|
-
|
|
90
83
|
generateAuthUrl(strategy, params) {
|
|
91
84
|
logger$4.debug('generateAuthUrl', {
|
|
92
85
|
strategy,
|
|
93
86
|
params
|
|
94
87
|
});
|
|
95
88
|
const strategyInstance = this.strategies[strategy];
|
|
96
|
-
|
|
97
89
|
switch (strategyInstance.type) {
|
|
98
90
|
case 'oauth2':
|
|
99
91
|
return strategyInstance.oauth2.authorizationCode.authorizeURL(params);
|
|
100
|
-
|
|
101
92
|
default:
|
|
102
93
|
throw new Error('Invalid strategy');
|
|
103
94
|
}
|
|
104
95
|
}
|
|
105
|
-
|
|
106
96
|
async getTokens(strategy, options) {
|
|
107
97
|
logger$4.debug('getTokens', {
|
|
108
98
|
strategy,
|
|
109
99
|
options
|
|
110
100
|
});
|
|
111
101
|
const strategyInstance = this.strategies[strategy];
|
|
112
|
-
|
|
113
102
|
switch (strategyInstance.type) {
|
|
114
103
|
case 'oauth2':
|
|
115
104
|
{
|
|
@@ -129,25 +118,22 @@ class AuthenticationService extends EventEmitter {
|
|
|
129
118
|
return d;
|
|
130
119
|
})(),
|
|
131
120
|
idToken: result.id_token
|
|
132
|
-
};
|
|
121
|
+
};
|
|
122
|
+
// return strategyInstance.accessToken.create(result);
|
|
133
123
|
}
|
|
134
124
|
|
|
135
125
|
default:
|
|
136
126
|
throw new Error('Invalid stategy');
|
|
137
127
|
}
|
|
138
128
|
}
|
|
139
|
-
|
|
140
129
|
async refreshToken(strategy, tokensParam) {
|
|
141
130
|
logger$4.debug('refreshToken', {
|
|
142
131
|
strategy
|
|
143
132
|
});
|
|
144
|
-
|
|
145
133
|
if (!tokensParam.refreshToken) {
|
|
146
134
|
throw new Error('Missing refresh token');
|
|
147
135
|
}
|
|
148
|
-
|
|
149
136
|
const strategyInstance = this.strategies[strategy];
|
|
150
|
-
|
|
151
137
|
switch (strategyInstance.type) {
|
|
152
138
|
case 'oauth2':
|
|
153
139
|
{
|
|
@@ -168,19 +154,16 @@ class AuthenticationService extends EventEmitter {
|
|
|
168
154
|
idToken: tokens.id_token
|
|
169
155
|
};
|
|
170
156
|
}
|
|
171
|
-
|
|
172
157
|
default:
|
|
173
158
|
throw new Error('Invalid stategy');
|
|
174
159
|
}
|
|
175
160
|
}
|
|
176
|
-
|
|
177
161
|
redirectUri(ctx, strategy) {
|
|
178
162
|
const host = `http${this.config.get('allowHttps') ? 's' : ''}://${ctx.request.host}`;
|
|
179
163
|
return `${host}${ctx.urlGenerator('loginResponse', {
|
|
180
164
|
strategy
|
|
181
165
|
})}`;
|
|
182
166
|
}
|
|
183
|
-
|
|
184
167
|
async redirectAuthUrl(ctx, strategy, {
|
|
185
168
|
refreshToken,
|
|
186
169
|
scopeKey,
|
|
@@ -194,11 +177,9 @@ class AuthenticationService extends EventEmitter {
|
|
|
194
177
|
});
|
|
195
178
|
const state = await randomHex(8);
|
|
196
179
|
const scope = this.userAccountsService.getScope(strategy, scopeKey || 'login', user, accountId);
|
|
197
|
-
|
|
198
180
|
if (!scope) {
|
|
199
181
|
throw new Error('Invalid empty scope');
|
|
200
182
|
}
|
|
201
|
-
|
|
202
183
|
ctx.cookies.set(`auth_${strategy}_${state}`, JSON.stringify({
|
|
203
184
|
scopeKey,
|
|
204
185
|
scope,
|
|
@@ -217,7 +198,6 @@ class AuthenticationService extends EventEmitter {
|
|
|
217
198
|
});
|
|
218
199
|
return ctx.redirect(redirectUri);
|
|
219
200
|
}
|
|
220
|
-
|
|
221
201
|
async accessResponse(ctx, strategy, isConnected, hooks) {
|
|
222
202
|
if (ctx.query.error) {
|
|
223
203
|
const error = new Error(ctx.query.error);
|
|
@@ -225,7 +205,6 @@ class AuthenticationService extends EventEmitter {
|
|
|
225
205
|
error.expose = true;
|
|
226
206
|
throw error;
|
|
227
207
|
}
|
|
228
|
-
|
|
229
208
|
const code = ctx.query.code;
|
|
230
209
|
const state = ctx.query.state;
|
|
231
210
|
const cookieName = `auth_${strategy}_${state}`;
|
|
@@ -233,56 +212,43 @@ class AuthenticationService extends EventEmitter {
|
|
|
233
212
|
ctx.cookies.set(cookieName, '', {
|
|
234
213
|
expires: new Date(1)
|
|
235
214
|
});
|
|
236
|
-
|
|
237
215
|
if (!cookie) {
|
|
238
216
|
throw new Error('No cookie for this state');
|
|
239
217
|
}
|
|
240
|
-
|
|
241
218
|
cookie = JSON.parse(cookie);
|
|
242
|
-
|
|
243
219
|
if (!cookie || !cookie.scope) {
|
|
244
220
|
throw new Error('Unexpected cookie value');
|
|
245
221
|
}
|
|
246
|
-
|
|
247
222
|
if (!cookie.isLoginAccess) {
|
|
248
223
|
if (!isConnected) {
|
|
249
224
|
throw new Error('You are not connected');
|
|
250
225
|
}
|
|
251
226
|
}
|
|
252
|
-
|
|
253
227
|
const tokens = await this.getTokens(strategy, {
|
|
254
228
|
code,
|
|
255
229
|
redirectUri: this.redirectUri(ctx, strategy)
|
|
256
230
|
});
|
|
257
|
-
|
|
258
231
|
if (cookie.isLoginAccess) {
|
|
259
232
|
const user = await this.userAccountsService.findOrCreateFromStrategy(strategy, tokens, cookie.scope, cookie.scopeKey);
|
|
260
|
-
|
|
261
233
|
if (hooks.afterLoginSuccess) {
|
|
262
234
|
await hooks.afterLoginSuccess(strategy, user);
|
|
263
235
|
}
|
|
264
|
-
|
|
265
236
|
return user;
|
|
266
237
|
}
|
|
267
|
-
|
|
268
238
|
const connectedUser = ctx.state.user;
|
|
269
239
|
const {
|
|
270
240
|
account,
|
|
271
241
|
user
|
|
272
242
|
} = await this.userAccountsService.update(connectedUser, strategy, tokens, cookie.scope, cookie.scopeKey);
|
|
273
|
-
|
|
274
243
|
if (hooks.afterScopeUpdate) {
|
|
275
244
|
await hooks.afterScopeUpdate(strategy, cookie.scopeKey, account, user);
|
|
276
245
|
}
|
|
277
|
-
|
|
278
246
|
return connectedUser;
|
|
279
247
|
}
|
|
280
|
-
|
|
281
248
|
refreshAccountTokens(user, account) {
|
|
282
249
|
if (account.tokenExpireDate && account.tokenExpireDate.getTime() > Date.now()) {
|
|
283
250
|
return Promise.resolve(false);
|
|
284
251
|
}
|
|
285
|
-
|
|
286
252
|
return this.refreshToken(account.provider, {
|
|
287
253
|
// accessToken: account.accessToken,
|
|
288
254
|
refreshToken: account.refreshToken
|
|
@@ -291,13 +257,11 @@ class AuthenticationService extends EventEmitter {
|
|
|
291
257
|
// serviceGoogle.updateFields({ accessToken:null, refreshToken:null, status: .OUTDATED });
|
|
292
258
|
return false;
|
|
293
259
|
}
|
|
294
|
-
|
|
295
260
|
account.accessToken = tokens.accessToken;
|
|
296
261
|
account.tokenExpireDate = tokens.expireDate;
|
|
297
262
|
return this.userAccountsService.updateAccount(user, account).then(() => true);
|
|
298
263
|
});
|
|
299
264
|
}
|
|
300
|
-
|
|
301
265
|
}
|
|
302
266
|
|
|
303
267
|
/* eslint-disable @typescript-eslint/no-shadow */
|
|
@@ -312,70 +276,54 @@ class UserAccountsService extends EventEmitter {
|
|
|
312
276
|
this.usersManager = usersManager;
|
|
313
277
|
this.strategyToService = strategyToService;
|
|
314
278
|
}
|
|
315
|
-
|
|
316
279
|
getScope(strategy, scopeKey, user, accountId) {
|
|
317
280
|
logger$3.debug('getScope', {
|
|
318
281
|
strategy,
|
|
319
282
|
userId: user?._id
|
|
320
283
|
});
|
|
321
284
|
const service = this.strategyToService[strategy];
|
|
322
|
-
|
|
323
285
|
if (!service) {
|
|
324
286
|
throw new Error('Strategy not supported');
|
|
325
287
|
}
|
|
326
|
-
|
|
327
288
|
const newScope = service.scopeKeyToScope[scopeKey];
|
|
328
|
-
|
|
329
289
|
if (!user || !accountId) {
|
|
330
290
|
return newScope;
|
|
331
291
|
}
|
|
332
|
-
|
|
333
292
|
const account = user.accounts.find(account => account.provider === strategy && account.accountId === accountId);
|
|
334
|
-
|
|
335
293
|
if (!account) {
|
|
336
294
|
throw new Error('Could not found associated account');
|
|
337
295
|
}
|
|
338
|
-
|
|
339
296
|
return service.getScope(account.scope, newScope).join(' ');
|
|
340
297
|
}
|
|
341
|
-
|
|
342
298
|
async update(user, strategy, tokens, scope, subservice) {
|
|
343
299
|
const service = this.strategyToService[strategy];
|
|
344
300
|
const profile = await service.getProfile(tokens);
|
|
345
301
|
const accountId = service.getId(profile);
|
|
346
302
|
const account = user.accounts.find(account => account.provider === strategy && account.accountId === accountId);
|
|
347
|
-
|
|
348
303
|
if (!account) {
|
|
349
304
|
// TODO check if already exists in other user => merge
|
|
350
305
|
// TODO else add a new account in this user
|
|
351
306
|
throw new Error('Could not found associated account');
|
|
352
307
|
}
|
|
353
|
-
|
|
354
308
|
account.status = 'valid';
|
|
355
309
|
account.accessToken = tokens.accessToken;
|
|
356
|
-
|
|
357
310
|
if (tokens.refreshToken) {
|
|
358
311
|
account.refreshToken = tokens.refreshToken;
|
|
359
312
|
}
|
|
360
|
-
|
|
361
313
|
if (tokens.expireDate) {
|
|
362
314
|
account.tokenExpireDate = tokens.expireDate;
|
|
363
315
|
}
|
|
364
|
-
|
|
365
316
|
account.scope = service.getScope(account.scope, scope);
|
|
366
317
|
account.subservices = account.subservices || [];
|
|
367
|
-
|
|
368
318
|
if (subservice && !account.subservices.includes(subservice)) {
|
|
369
319
|
account.subservices.push(subservice);
|
|
370
320
|
}
|
|
371
|
-
|
|
372
321
|
await this.usersManager.replaceOne(user);
|
|
373
322
|
return {
|
|
374
323
|
user,
|
|
375
324
|
account
|
|
376
325
|
};
|
|
377
326
|
}
|
|
378
|
-
|
|
379
327
|
async findOrCreateFromStrategy(strategy, tokens, scope, subservice) {
|
|
380
328
|
const service = this.strategyToService[strategy];
|
|
381
329
|
if (!service) throw new Error('Strategy not supported');
|
|
@@ -392,11 +340,9 @@ class UserAccountsService extends EventEmitter {
|
|
|
392
340
|
emails,
|
|
393
341
|
user
|
|
394
342
|
});
|
|
395
|
-
|
|
396
343
|
if (!user) {
|
|
397
344
|
user = {};
|
|
398
345
|
}
|
|
399
|
-
|
|
400
346
|
Object.assign(user, {
|
|
401
347
|
displayName: service.getDisplayName(profile),
|
|
402
348
|
fullName: service.getFullName(profile),
|
|
@@ -404,36 +350,29 @@ class UserAccountsService extends EventEmitter {
|
|
|
404
350
|
});
|
|
405
351
|
if (!user.accounts) user.accounts = [];
|
|
406
352
|
let account = user.accounts.find(account => account.provider === strategy && account.accountId === accountId);
|
|
407
|
-
|
|
408
353
|
if (!account) {
|
|
409
354
|
account = {
|
|
410
355
|
provider: strategy,
|
|
411
356
|
accountId
|
|
412
|
-
};
|
|
413
|
-
|
|
357
|
+
};
|
|
358
|
+
// @ts-expect-error well...
|
|
414
359
|
user.accounts.push(account);
|
|
415
360
|
}
|
|
416
|
-
|
|
417
361
|
account.name = service.getAccountName(profile);
|
|
418
362
|
account.status = 'valid';
|
|
419
363
|
account.profile = profile;
|
|
420
364
|
account.accessToken = tokens.accessToken;
|
|
421
|
-
|
|
422
365
|
if (tokens.refreshToken) {
|
|
423
366
|
account.refreshToken = tokens.refreshToken;
|
|
424
367
|
}
|
|
425
|
-
|
|
426
368
|
if (tokens.expireDate) {
|
|
427
369
|
account.tokenExpireDate = tokens.expireDate;
|
|
428
370
|
}
|
|
429
|
-
|
|
430
371
|
account.scope = service.getScope(account.scope, scope);
|
|
431
372
|
if (!account.subservices) account.subservices = [];
|
|
432
|
-
|
|
433
373
|
if (subservice && !account.subservices.includes(subservice)) {
|
|
434
374
|
account.subservices.push(subservice);
|
|
435
375
|
}
|
|
436
|
-
|
|
437
376
|
if (!user.emails) user.emails = [];
|
|
438
377
|
const userEmails = user.emails;
|
|
439
378
|
emails.forEach(email => {
|
|
@@ -441,37 +380,34 @@ class UserAccountsService extends EventEmitter {
|
|
|
441
380
|
userEmails.push(email);
|
|
442
381
|
}
|
|
443
382
|
});
|
|
444
|
-
user.emailDomains = [
|
|
383
|
+
user.emailDomains = [
|
|
384
|
+
// eslint-disable-next-line unicorn/no-array-reduce
|
|
445
385
|
...user.emails.reduce((domains, email) => domains.add(email.split('@', 2)[1]), new Set())];
|
|
446
386
|
const keyPath = this.usersManager.store.keyPath;
|
|
447
|
-
|
|
448
387
|
if (user[keyPath]) {
|
|
449
388
|
await this.usersManager.replaceOne(user);
|
|
450
389
|
} else {
|
|
451
390
|
await this.usersManager.insertOne(user);
|
|
452
391
|
}
|
|
453
|
-
|
|
454
392
|
return user;
|
|
455
393
|
}
|
|
456
|
-
|
|
457
394
|
async updateAccount(user, account) {
|
|
458
395
|
await this.usersManager.updateAccount(user, account);
|
|
459
396
|
return user;
|
|
460
397
|
}
|
|
461
|
-
|
|
462
398
|
}
|
|
463
399
|
|
|
464
400
|
const COOKIE_NAME = 'connectedUser';
|
|
465
401
|
const getTokenFromRequest = (req, options) => {
|
|
466
402
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
467
|
-
const cookies = new Cookies(req, null, {
|
|
403
|
+
const cookies = new Cookies(req, null, {
|
|
404
|
+
...options,
|
|
468
405
|
secure: true
|
|
469
406
|
});
|
|
470
407
|
return cookies.get(COOKIE_NAME);
|
|
471
408
|
};
|
|
472
409
|
|
|
473
410
|
const verifyPromisified = promisify(jsonwebtoken.verify);
|
|
474
|
-
|
|
475
411
|
const createDecodeJWT = secretKey => async (token, jwtAudience) => {
|
|
476
412
|
const result = await verifyPromisified(token, secretKey, {
|
|
477
413
|
algorithms: ['HS512'],
|
|
@@ -479,13 +415,11 @@ const createDecodeJWT = secretKey => async (token, jwtAudience) => {
|
|
|
479
415
|
});
|
|
480
416
|
return result?.connected;
|
|
481
417
|
};
|
|
482
|
-
|
|
483
418
|
const createFindConnectedAndUser = (secretKey, usersManager, logger) => {
|
|
484
419
|
const decodeJwt = createDecodeJWT(secretKey);
|
|
485
420
|
return async (jwtAudience, token) => {
|
|
486
421
|
if (!token || !jwtAudience) return [null, null];
|
|
487
422
|
let connected;
|
|
488
|
-
|
|
489
423
|
try {
|
|
490
424
|
connected = await decodeJwt(token, jwtAudience);
|
|
491
425
|
} catch (err) {
|
|
@@ -493,7 +427,6 @@ const createFindConnectedAndUser = (secretKey, usersManager, logger) => {
|
|
|
493
427
|
err
|
|
494
428
|
});
|
|
495
429
|
}
|
|
496
|
-
|
|
497
430
|
if (connected == null) return [null, null];
|
|
498
431
|
const user = await usersManager.findConnected(connected);
|
|
499
432
|
return [connected, user];
|
|
@@ -504,23 +437,18 @@ class MongoUsersManager {
|
|
|
504
437
|
constructor(store) {
|
|
505
438
|
this.store = store;
|
|
506
439
|
}
|
|
507
|
-
|
|
508
440
|
findConnected(connected) {
|
|
509
441
|
return this.store.findByKey(connected);
|
|
510
442
|
}
|
|
511
|
-
|
|
512
443
|
insertOne(user) {
|
|
513
444
|
return this.store.insertOne(user);
|
|
514
445
|
}
|
|
515
|
-
|
|
516
446
|
replaceOne(user) {
|
|
517
447
|
return this.store.replaceOne(user);
|
|
518
448
|
}
|
|
519
|
-
|
|
520
449
|
sanitize(user) {
|
|
521
450
|
return this.sanitizeBaseUser(user);
|
|
522
451
|
}
|
|
523
|
-
|
|
524
452
|
findOneByAccountOrEmails({
|
|
525
453
|
accountId,
|
|
526
454
|
emails,
|
|
@@ -530,7 +458,6 @@ class MongoUsersManager {
|
|
|
530
458
|
'accounts.provider': provider,
|
|
531
459
|
'accounts.accountId': accountId
|
|
532
460
|
};
|
|
533
|
-
|
|
534
461
|
if (emails && emails.length > 0) {
|
|
535
462
|
query = {
|
|
536
463
|
$or: [query, {
|
|
@@ -539,26 +466,22 @@ class MongoUsersManager {
|
|
|
539
466
|
}
|
|
540
467
|
}]
|
|
541
468
|
};
|
|
542
|
-
}
|
|
543
|
-
|
|
469
|
+
}
|
|
544
470
|
|
|
471
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
545
472
|
return this.store.findOne(query);
|
|
546
473
|
}
|
|
547
|
-
|
|
548
474
|
updateAccount(user, account) {
|
|
549
475
|
const accountIndex = user.accounts.indexOf(account);
|
|
550
|
-
|
|
551
476
|
if (accountIndex === -1) {
|
|
552
477
|
throw new Error('Invalid account');
|
|
553
478
|
}
|
|
554
|
-
|
|
555
479
|
return this.store.partialUpdateOne(user, {
|
|
556
480
|
$set: {
|
|
557
481
|
[`accounts.${accountIndex}`]: account
|
|
558
482
|
}
|
|
559
483
|
});
|
|
560
484
|
}
|
|
561
|
-
|
|
562
485
|
sanitizeBaseUser(user) {
|
|
563
486
|
return {
|
|
564
487
|
_id: user._id,
|
|
@@ -578,109 +501,88 @@ class MongoUsersManager {
|
|
|
578
501
|
}))
|
|
579
502
|
};
|
|
580
503
|
}
|
|
581
|
-
|
|
582
504
|
}
|
|
583
505
|
|
|
584
506
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
585
507
|
class UserAccountGoogleService {
|
|
586
508
|
constructor(scopeKeyToScope) {
|
|
587
|
-
this.scopeKeyToScope = {
|
|
509
|
+
this.scopeKeyToScope = {
|
|
510
|
+
...scopeKeyToScope,
|
|
588
511
|
login: 'openid profile email'
|
|
589
512
|
};
|
|
590
513
|
}
|
|
591
|
-
|
|
592
514
|
providerKey = 'google';
|
|
593
|
-
|
|
594
515
|
getProfile(tokens) {
|
|
595
516
|
return fetch(`https://www.googleapis.com/oauth2/v1/userinfo?access_token=${tokens.accessToken}`).then(response => response.json());
|
|
596
517
|
}
|
|
597
|
-
|
|
598
518
|
getId(profile) {
|
|
599
519
|
return profile.id;
|
|
600
520
|
}
|
|
601
|
-
|
|
602
521
|
getAccountName(profile) {
|
|
603
522
|
return profile.email;
|
|
604
523
|
}
|
|
605
|
-
|
|
606
524
|
getEmails(profile) {
|
|
607
525
|
const emails = [];
|
|
608
|
-
|
|
609
526
|
if (profile.email) {
|
|
610
527
|
emails.push(profile.email);
|
|
611
528
|
}
|
|
612
|
-
|
|
613
529
|
return emails;
|
|
614
530
|
}
|
|
615
|
-
|
|
616
531
|
getDisplayName(profile) {
|
|
617
532
|
return profile.name;
|
|
618
533
|
}
|
|
619
|
-
|
|
620
534
|
getFullName(profile) {
|
|
621
535
|
return {
|
|
622
536
|
givenName: profile.given_name,
|
|
623
537
|
familyName: profile.family_name
|
|
624
538
|
};
|
|
625
539
|
}
|
|
626
|
-
|
|
627
540
|
getDefaultScope(newScope) {
|
|
628
541
|
return this.getScope(undefined, newScope);
|
|
629
542
|
}
|
|
630
|
-
|
|
631
543
|
getScope(oldScope, newScope) {
|
|
632
544
|
return !oldScope ? newScope.split(' ') : [...oldScope, ...newScope.split(' ')].filter((item, i, ar) => ar.indexOf(item) === i);
|
|
633
545
|
}
|
|
634
|
-
|
|
635
546
|
}
|
|
636
547
|
|
|
637
548
|
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
638
549
|
// https://api.slack.com/methods/users.identity
|
|
550
|
+
|
|
639
551
|
class UserAccountSlackService {
|
|
640
552
|
constructor(scopeKeyToScope) {
|
|
641
|
-
this.scopeKeyToScope = {
|
|
553
|
+
this.scopeKeyToScope = {
|
|
554
|
+
...scopeKeyToScope,
|
|
642
555
|
login: 'identity.basic identity.email identity.avatar'
|
|
643
556
|
};
|
|
644
557
|
}
|
|
645
|
-
|
|
646
558
|
providerKey = 'google';
|
|
647
|
-
|
|
648
559
|
getProfile(tokens) {
|
|
649
560
|
return fetch(`https://slack.com/api/users.identity?token=${tokens.accessToken}`).then(response => response.json());
|
|
650
561
|
}
|
|
651
|
-
|
|
652
562
|
getId(profile) {
|
|
653
563
|
if (!profile || !profile.team || !profile.team.id || !profile.user || !profile.user.id) {
|
|
654
564
|
return null;
|
|
655
565
|
}
|
|
656
|
-
|
|
657
566
|
return `team:${profile.team.id};user:${profile.user.id}`;
|
|
658
567
|
}
|
|
659
|
-
|
|
660
568
|
getAccountName(profile) {
|
|
661
569
|
return profile.user.email;
|
|
662
570
|
}
|
|
663
|
-
|
|
664
571
|
getEmails(profile) {
|
|
665
572
|
return profile.user.email ? [profile.user.email] : [];
|
|
666
573
|
}
|
|
667
|
-
|
|
668
574
|
getDisplayName(profile) {
|
|
669
575
|
return profile.user.name;
|
|
670
576
|
}
|
|
671
|
-
|
|
672
577
|
getFullName() {
|
|
673
578
|
return null;
|
|
674
579
|
}
|
|
675
|
-
|
|
676
580
|
getDefaultScope(newScope) {
|
|
677
581
|
return this.getScope(undefined, newScope);
|
|
678
582
|
}
|
|
679
|
-
|
|
680
583
|
getScope(oldScope, newScope) {
|
|
681
584
|
return !oldScope ? newScope.split(' ') : [...oldScope, ...newScope.split(' ')].filter((item, i, ar) => ar.indexOf(item) === i);
|
|
682
585
|
}
|
|
683
|
-
|
|
684
586
|
}
|
|
685
587
|
|
|
686
588
|
const logger$2 = new Logger('alp:auth');
|
|
@@ -689,11 +591,12 @@ const authSocketIO = (app, usersManager, io) => {
|
|
|
689
591
|
const users = new Map();
|
|
690
592
|
io.users = users;
|
|
691
593
|
io.use(async (socket, next) => {
|
|
692
|
-
const handshakeData = socket.request;
|
|
693
|
-
|
|
594
|
+
const handshakeData = socket.request;
|
|
595
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
694
596
|
const token = getTokenFromRequest(handshakeData);
|
|
695
597
|
if (!token) return next();
|
|
696
|
-
const [connected, user] = await findConnectedAndUser(
|
|
598
|
+
const [connected, user] = await findConnectedAndUser(
|
|
599
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
697
600
|
handshakeData.headers['user-agent'], token);
|
|
698
601
|
if (!connected || !user) return next();
|
|
699
602
|
socket.user = user;
|
|
@@ -704,17 +607,15 @@ const authSocketIO = (app, usersManager, io) => {
|
|
|
704
607
|
};
|
|
705
608
|
|
|
706
609
|
const logger$1 = new Logger('alp:auth');
|
|
707
|
-
|
|
708
610
|
const getTokenFromReq = req => {
|
|
709
611
|
if (req.cookies) return req.cookies[COOKIE_NAME];
|
|
710
612
|
return getTokenFromRequest(req);
|
|
711
613
|
};
|
|
614
|
+
|
|
712
615
|
/*
|
|
713
616
|
* Not tested yet.
|
|
714
617
|
* @internal
|
|
715
618
|
*/
|
|
716
|
-
|
|
717
|
-
|
|
718
619
|
const createAuthApolloContext = (config, usersManager) => {
|
|
719
620
|
const findConnectedAndUser = createFindConnectedAndUser(config.get('authentication').get('secretKey'), usersManager, logger$1);
|
|
720
621
|
return async ({
|
|
@@ -726,14 +627,15 @@ const createAuthApolloContext = (config, usersManager) => {
|
|
|
726
627
|
user: connection.user
|
|
727
628
|
};
|
|
728
629
|
}
|
|
630
|
+
if (!req) return null;
|
|
729
631
|
|
|
730
|
-
|
|
731
|
-
|
|
632
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
732
633
|
const token = getTokenFromReq(req);
|
|
733
634
|
if (!token) return {
|
|
734
635
|
user: undefined
|
|
735
636
|
};
|
|
736
|
-
const [, user] = await findConnectedAndUser(
|
|
637
|
+
const [, user] = await findConnectedAndUser(
|
|
638
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
737
639
|
req.headers['user-agent'], token);
|
|
738
640
|
return {
|
|
739
641
|
user
|
|
@@ -763,16 +665,13 @@ function init({
|
|
|
763
665
|
defaultStrategy,
|
|
764
666
|
authHooks
|
|
765
667
|
});
|
|
766
|
-
|
|
767
668
|
app.context.setConnected = async function (connected, user) {
|
|
768
669
|
logger.debug('setConnected', {
|
|
769
670
|
connected
|
|
770
671
|
});
|
|
771
|
-
|
|
772
672
|
if (!connected) {
|
|
773
673
|
throw new Error('Illegal value for setConnected');
|
|
774
674
|
}
|
|
775
|
-
|
|
776
675
|
this.state.connected = connected;
|
|
777
676
|
this.state.user = user;
|
|
778
677
|
const token = await signPromisified({
|
|
@@ -782,14 +681,14 @@ function init({
|
|
|
782
681
|
algorithm: 'HS512',
|
|
783
682
|
audience: jwtAudience || this.request.headers['user-agent'],
|
|
784
683
|
expiresIn: '30 days'
|
|
785
|
-
});
|
|
684
|
+
});
|
|
786
685
|
|
|
686
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
787
687
|
this.cookies.set(COOKIE_NAME, token, {
|
|
788
688
|
httpOnly: true,
|
|
789
689
|
secure: this.config.get('allowHttps')
|
|
790
690
|
});
|
|
791
691
|
};
|
|
792
|
-
|
|
793
692
|
app.context.logout = function () {
|
|
794
693
|
delete this.state.connected;
|
|
795
694
|
delete this.state.user;
|
|
@@ -797,7 +696,6 @@ function init({
|
|
|
797
696
|
expires: new Date(1)
|
|
798
697
|
});
|
|
799
698
|
};
|
|
800
|
-
|
|
801
699
|
const getConnectedAndUser = createFindConnectedAndUser(app.config.get('authentication').get('secretKey'), usersManager, logger);
|
|
802
700
|
return {
|
|
803
701
|
routes: createRoutes(controller),
|
|
@@ -812,19 +710,16 @@ function init({
|
|
|
812
710
|
logger.debug('middleware', {
|
|
813
711
|
token
|
|
814
712
|
});
|
|
815
|
-
|
|
816
713
|
const setState = (connected, user) => {
|
|
817
714
|
ctx.state.connected = connected;
|
|
818
715
|
ctx.state.user = user;
|
|
819
716
|
ctx.sanitizedState.connected = connected;
|
|
820
717
|
ctx.sanitizedState.user = user && usersManager.sanitize(user);
|
|
821
718
|
};
|
|
822
|
-
|
|
823
719
|
const [connected, user] = await getConnectedAndUser(jwtAudience || userAgent, token);
|
|
824
720
|
logger.debug('middleware', {
|
|
825
721
|
connected
|
|
826
722
|
});
|
|
827
|
-
|
|
828
723
|
if (connected == null || user == null) {
|
|
829
724
|
if (token) ctx.cookies.set(COOKIE_NAME, '', {
|
|
830
725
|
expires: new Date(1)
|
|
@@ -832,7 +727,6 @@ function init({
|
|
|
832
727
|
setState(null, null);
|
|
833
728
|
return next();
|
|
834
729
|
}
|
|
835
|
-
|
|
836
730
|
setState(connected, user);
|
|
837
731
|
return next();
|
|
838
732
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-node14.mjs","sources":["../src/createAuthController.ts","../src/createRoutes.ts","../src/utils/generators.ts","../src/services/authentification/AuthenticationService.ts","../src/services/user/UserAccountsService.ts","../src/utils/cookies.ts","../src/utils/createFindConnectedAndUser.ts","../src/MongoUsersManager.ts","../src/services/user/UserAccountGoogleService.ts","../src/services/user/UserAccountSlackService.ts","../src/authSocketIO.ts","../src/authApolloContext.ts","../src/index.ts"],"sourcesContent":["import type { Context } from 'alp-node';\nimport 'alp-router';\nimport type { User, UserSanitized } from '../types.d';\nimport type MongoUsersManager from './MongoUsersManager';\nimport type {\n AuthenticationService,\n AccessResponseHooks,\n} from './services/authentification/AuthenticationService';\nimport type {\n AllowedStrategyKeys,\n AllowedMapParamsStrategy,\n} from './services/authentification/types';\n\nexport interface CreateAuthControllerParams<\n StrategyKeys extends AllowedStrategyKeys,\n U extends User = User,\n USanitized extends UserSanitized = UserSanitized,\n> {\n authenticationService: AuthenticationService<StrategyKeys, U, UserSanitized>;\n homeRouterKey?: string;\n usersManager: MongoUsersManager<U, USanitized>;\n defaultStrategy?: StrategyKeys;\n authHooks?: AuthHooks<StrategyKeys>;\n}\n\nexport interface AuthController {\n login: (ctx: Context) => Promise<void>;\n addScope: (ctx: Context) => Promise<void>;\n loginResponse: (ctx: Context) => Promise<void>;\n logout: (ctx: Context) => Promise<void>;\n}\n\ntype OptionalRecord<K extends keyof any, T> = { [P in K]?: T };\n\nexport interface AuthHooks<StrategyKeys extends AllowedStrategyKeys>\n extends AccessResponseHooks<StrategyKeys> {\n paramsForLogin?: <StrategyKey extends StrategyKeys>(\n strategy: StrategyKey,\n ctx: Context,\n ) => // eslint-disable-next-line @typescript-eslint/no-invalid-void-type\n | void\n | Promise<void>\n | OptionalRecord<AllowedMapParamsStrategy[StrategyKey], any>\n | Promise<OptionalRecord<AllowedMapParamsStrategy[StrategyKey], any>>;\n}\n\nexport function createAuthController<\n StrategyKeys extends AllowedStrategyKeys,\n U extends User = User,\n USanitized extends UserSanitized = UserSanitized,\n>({\n usersManager,\n authenticationService,\n homeRouterKey = '/',\n defaultStrategy,\n authHooks = {},\n}: CreateAuthControllerParams<StrategyKeys, U, USanitized>): AuthController {\n return {\n async login(ctx: Context): Promise<void> {\n const strategy: StrategyKeys = (ctx.namedParam('strategy') ||\n defaultStrategy) as StrategyKeys;\n if (!strategy) throw new Error('Strategy missing');\n const params =\n (authHooks.paramsForLogin &&\n (await authHooks.paramsForLogin(strategy, ctx))) ||\n {};\n await authenticationService.redirectAuthUrl(ctx, strategy, {}, params);\n },\n\n async addScope(ctx: Context): Promise<void> {\n if (ctx.state.connected) {\n await ctx.redirectTo(homeRouterKey);\n return;\n }\n\n const strategy: StrategyKeys = (ctx.namedParam('strategy') ||\n defaultStrategy) as StrategyKeys;\n if (!strategy) throw new Error('Strategy missing');\n const scopeKey = ctx.namedParam('scopeKey');\n if (!scopeKey) throw new Error('Scope missing');\n await authenticationService.redirectAuthUrl(ctx, strategy, { scopeKey });\n },\n\n async loginResponse(ctx: Context): Promise<void> {\n if (ctx.state.connected) {\n await ctx.redirectTo(homeRouterKey);\n return;\n }\n\n const strategy: StrategyKeys = ctx.namedParam('strategy') as StrategyKeys;\n ctx.assert(strategy);\n\n const connectedUser = await authenticationService.accessResponse(\n ctx,\n strategy,\n ctx.state.connected as boolean | undefined,\n {\n afterLoginSuccess: authHooks.afterLoginSuccess,\n afterScopeUpdate: authHooks.afterScopeUpdate,\n },\n );\n const keyPath = usersManager.store.keyPath;\n await ctx.setConnected(connectedUser[keyPath], connectedUser);\n await ctx.redirectTo(homeRouterKey);\n },\n\n async logout(ctx: Context): Promise<void> {\n ctx.logout();\n await ctx.redirectTo(homeRouterKey);\n },\n };\n}\n","import type { AuthController } from './createAuthController';\n\nexport interface AuthRoutes {\n login: [string, (segment: any) => void];\n addScope: [string, AuthController['addScope']];\n logout: [string, AuthController['logout']];\n}\n\nexport const createRoutes = (controller: AuthController): AuthRoutes => ({\n login: [\n '/login/:strategy?',\n (segment: any) => {\n segment.add('/response', controller.loginResponse, 'loginResponse');\n segment.defaultRoute(controller.login, 'login');\n },\n ],\n addScope: ['/auth/add-scope/:strategy/:scopeKey', controller.addScope],\n logout: ['/logout', controller.logout],\n});\n","import { randomBytes } from 'crypto';\nimport { promisify } from 'util';\n\nconst randomBytesPromisified = promisify(randomBytes);\n\nexport async function randomBase64(size: number): Promise<string> {\n const buffer = await randomBytesPromisified(size);\n return buffer.toString('base64');\n}\n\nexport async function randomHex(size: number): Promise<string> {\n const buffer = await randomBytesPromisified(size);\n return buffer.toString('hex');\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-argument */\n/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable camelcase, max-lines */\nimport { EventEmitter } from 'events';\nimport 'alp-router';\nimport type { Context, NodeConfig } from 'alp-types';\nimport { Logger } from 'nightingale-logger';\nimport type { OAuthClient } from 'simple-oauth2';\nimport type { AccountId, User, Account, UserSanitized } from '../../../types.d';\nimport { randomHex } from '../../utils/generators';\nimport type UserAccountsService from '../user/UserAccountsService';\nimport type { AllowedStrategyKeys, Tokens } from './types';\n\nconst logger = new Logger('alp:auth:authentication');\n\nexport interface GenerateAuthUrlOptions {\n accessType?: string;\n grantType?: string;\n includeGrantedScopes?: boolean;\n loginHint?: string;\n prompt?: string;\n redirectUri?: string;\n scope?: string;\n state?: string;\n}\n\nexport interface GetTokensOptions {\n code: string;\n redirectUri: string;\n}\n\nexport interface Strategy {\n type: string;\n}\n\nexport interface Oauth2Strategy<Params extends string> extends Strategy {\n oauth2: OAuthClient<Params>;\n}\n\nexport type Strategies<StrategyKeys extends AllowedStrategyKeys> = Record<\n StrategyKeys,\n Oauth2Strategy<any>\n>;\n\nexport interface AccessResponseHooks<StrategyKeys, U extends User = User> {\n afterLoginSuccess?: <StrategyKey extends StrategyKeys>(\n strategy: StrategyKey,\n connectedUser: U,\n ) => void | Promise<void>;\n\n afterScopeUpdate?: <StrategyKey extends StrategyKeys>(\n strategy: StrategyKey,\n scopeKey: string,\n account: Account,\n user: U,\n ) => void | Promise<void>;\n}\n\nexport class AuthenticationService<\n StrategyKeys extends AllowedStrategyKeys,\n U extends User = User,\n USanitized extends UserSanitized = UserSanitized,\n> extends EventEmitter {\n config: NodeConfig;\n\n strategies: Strategies<StrategyKeys>;\n\n userAccountsService: UserAccountsService<StrategyKeys, U, USanitized>;\n\n constructor(\n config: NodeConfig,\n strategies: Strategies<StrategyKeys>,\n userAccountsService: UserAccountsService<StrategyKeys, U, USanitized>,\n ) {\n super();\n this.config = config;\n this.strategies = strategies;\n this.userAccountsService = userAccountsService;\n }\n\n generateAuthUrl<T extends StrategyKeys>(strategy: T, params: any): string {\n logger.debug('generateAuthUrl', { strategy, params });\n const strategyInstance = this.strategies[strategy];\n switch (strategyInstance.type) {\n case 'oauth2':\n return strategyInstance.oauth2.authorizationCode.authorizeURL(params);\n default:\n throw new Error('Invalid strategy');\n }\n }\n\n async getTokens(\n strategy: StrategyKeys,\n options: GetTokensOptions,\n ): Promise<Tokens> {\n logger.debug('getTokens', { strategy, options });\n const strategyInstance = this.strategies[strategy];\n switch (strategyInstance.type) {\n case 'oauth2': {\n const result = await strategyInstance.oauth2.authorizationCode.getToken(\n {\n code: options.code,\n redirect_uri: options.redirectUri,\n },\n );\n if (!result) return result;\n return {\n accessToken: result.access_token,\n refreshToken: result.refresh_token,\n tokenType: result.token_type,\n expiresIn: result.expires_in,\n expireDate: (() => {\n const d = new Date();\n d.setTime(d.getTime() + result.expires_in * 1000);\n return d;\n })(),\n idToken: result.id_token,\n };\n // return strategyInstance.accessToken.create(result);\n }\n\n default:\n throw new Error('Invalid stategy');\n }\n }\n\n async refreshToken(\n strategy: StrategyKeys,\n tokensParam: { refreshToken: string },\n ): Promise<Tokens> {\n logger.debug('refreshToken', { strategy });\n if (!tokensParam.refreshToken) {\n throw new Error('Missing refresh token');\n }\n const strategyInstance = this.strategies[strategy];\n switch (strategyInstance.type) {\n case 'oauth2': {\n const token = strategyInstance.oauth2.accessToken.create({\n refresh_token: tokensParam.refreshToken,\n });\n const result = await token.refresh();\n const tokens = result.token;\n return {\n accessToken: tokens.access_token,\n tokenType: tokens.token_type,\n expiresIn: tokens.expires_in,\n expireDate: (() => {\n const d = new Date();\n d.setTime(d.getTime() + tokens.expires_in * 1000);\n return d;\n })(),\n idToken: tokens.id_token,\n };\n }\n\n default:\n throw new Error('Invalid stategy');\n }\n }\n\n redirectUri(ctx: Context, strategy: string): string {\n const host = `http${this.config.get('allowHttps') ? 's' : ''}://${\n ctx.request.host\n }`;\n return `${host}${ctx.urlGenerator('loginResponse', { strategy })}`;\n }\n\n async redirectAuthUrl(\n ctx: Context,\n strategy: StrategyKeys,\n {\n refreshToken,\n scopeKey,\n user,\n accountId,\n }: {\n refreshToken?: string | undefined;\n scopeKey?: string | undefined;\n user?: U;\n accountId?: AccountId;\n },\n params?: any,\n ): Promise<void> {\n logger.debug('redirectAuthUrl', { strategy, scopeKey, refreshToken });\n const state = await randomHex(8);\n const isLoginAccess = !scopeKey || scopeKey === 'login';\n const scope = this.userAccountsService.getScope(\n strategy,\n scopeKey || 'login',\n user,\n accountId,\n );\n\n if (!scope) {\n throw new Error('Invalid empty scope');\n }\n\n ctx.cookies.set(\n `auth_${strategy}_${state}`,\n JSON.stringify({\n scopeKey,\n scope,\n isLoginAccess,\n }),\n {\n maxAge: 10 * 60 * 1000,\n httpOnly: true,\n secure: this.config.get('allowHttps'),\n },\n );\n const redirectUri = this.generateAuthUrl(strategy, {\n redirect_uri: this.redirectUri(ctx, strategy),\n scope,\n state,\n access_type: refreshToken ? 'offline' : 'online',\n ...params,\n });\n\n return ctx.redirect(redirectUri);\n }\n\n async accessResponse<StrategyKey extends StrategyKeys>(\n ctx: any,\n strategy: StrategyKey,\n isConnected: undefined | boolean,\n hooks: AccessResponseHooks<StrategyKeys, U>,\n ): Promise<U> {\n if (ctx.query.error) {\n const error: any = new Error(ctx.query.error);\n error.status = 403;\n error.expose = true;\n throw error;\n }\n\n const code = ctx.query.code;\n const state = ctx.query.state;\n const cookieName = `auth_${strategy}_${state as string}`;\n let cookie = ctx.cookies.get(cookieName);\n ctx.cookies.set(cookieName, '', { expires: new Date(1) });\n if (!cookie) {\n throw new Error('No cookie for this state');\n }\n\n cookie = JSON.parse(cookie);\n if (!cookie || !cookie.scope) {\n throw new Error('Unexpected cookie value');\n }\n\n if (!cookie.isLoginAccess) {\n if (!isConnected) {\n throw new Error('You are not connected');\n }\n }\n\n const tokens: Tokens = await this.getTokens(strategy, {\n code,\n redirectUri: this.redirectUri(ctx, strategy),\n });\n\n if (cookie.isLoginAccess) {\n const user = await this.userAccountsService.findOrCreateFromStrategy(\n strategy,\n tokens,\n cookie.scope,\n cookie.scopeKey,\n );\n\n if (hooks.afterLoginSuccess) {\n await hooks.afterLoginSuccess(strategy, user);\n }\n\n return user;\n }\n\n const connectedUser = ctx.state.user;\n const { account, user } = await this.userAccountsService.update(\n connectedUser,\n strategy,\n tokens,\n cookie.scope,\n cookie.scopeKey,\n );\n\n if (hooks.afterScopeUpdate) {\n await hooks.afterScopeUpdate(strategy, cookie.scopeKey, account, user);\n }\n\n return connectedUser;\n }\n\n refreshAccountTokens(user: U, account: Account): Promise<boolean> {\n if (\n account.tokenExpireDate &&\n account.tokenExpireDate.getTime() > Date.now()\n ) {\n return Promise.resolve(false);\n }\n return this.refreshToken(account.provider as StrategyKeys, {\n // accessToken: account.accessToken,\n refreshToken: account.refreshToken!,\n }).then((tokens: Tokens) => {\n if (!tokens) {\n // serviceGoogle.updateFields({ accessToken:null, refreshToken:null, status: .OUTDATED });\n return false;\n }\n account.accessToken = tokens.accessToken;\n account.tokenExpireDate = tokens.expireDate;\n return this.userAccountsService\n .updateAccount(user, account)\n .then(() => true);\n });\n }\n}\n","/* eslint-disable @typescript-eslint/no-shadow */\nimport { EventEmitter } from 'events';\nimport { Logger } from 'nightingale-logger';\nimport type { AccountId, User, Account, UserSanitized } from '../../../types.d';\nimport type MongoUsersManager from '../../MongoUsersManager';\nimport type { AllowedStrategyKeys } from '../authentification/types';\nimport type { AccountService, TokensObject } from './types';\n\nconst logger = new Logger('alp:auth:userAccounts');\n\nexport const STATUSES = {\n VALIDATED: 'validated',\n DELETED: 'deleted',\n};\n\nexport default class UserAccountsService<\n StrategyKeys extends AllowedStrategyKeys,\n U extends User = User,\n USanitized extends UserSanitized = UserSanitized,\n> extends EventEmitter {\n private readonly strategyToService: Record<StrategyKeys, AccountService<any>>;\n\n usersManager: MongoUsersManager<U, USanitized>;\n\n constructor(\n usersManager: MongoUsersManager<U, USanitized>,\n strategyToService: Record<StrategyKeys, AccountService<any>>,\n ) {\n super();\n this.usersManager = usersManager;\n this.strategyToService = strategyToService;\n }\n\n getScope(\n strategy: StrategyKeys,\n scopeKey: string,\n user?: U,\n accountId?: AccountId,\n ): string {\n logger.debug('getScope', { strategy, userId: user?._id });\n const service = this.strategyToService[strategy];\n if (!service) {\n throw new Error('Strategy not supported');\n }\n\n const newScope = service.scopeKeyToScope[scopeKey];\n if (!user || !accountId) {\n return newScope;\n }\n const account = user.accounts.find(\n (account) =>\n account.provider === strategy && account.accountId === accountId,\n );\n\n if (!account) {\n throw new Error('Could not found associated account');\n }\n return service.getScope(account.scope, newScope).join(' ');\n }\n\n async update(\n user: U,\n strategy: StrategyKeys,\n tokens: TokensObject,\n scope: string,\n subservice: string,\n ): Promise<{ user: U; account: U['accounts'][number] }> {\n const service = this.strategyToService[strategy];\n const profile = await service.getProfile(tokens);\n const accountId = service.getId(profile);\n const account = user.accounts.find(\n (account) =>\n account.provider === strategy && account.accountId === accountId,\n );\n if (!account) {\n // TODO check if already exists in other user => merge\n // TODO else add a new account in this user\n throw new Error('Could not found associated account');\n }\n account.status = 'valid';\n account.accessToken = tokens.accessToken;\n if (tokens.refreshToken) {\n account.refreshToken = tokens.refreshToken;\n }\n if (tokens.expireDate) {\n account.tokenExpireDate = tokens.expireDate;\n }\n account.scope = service.getScope(account.scope, scope);\n account.subservices = account.subservices || [];\n if (subservice && !account.subservices.includes(subservice)) {\n account.subservices.push(subservice);\n }\n\n await this.usersManager.replaceOne(user);\n return { user, account };\n }\n\n async findOrCreateFromStrategy(\n strategy: StrategyKeys,\n tokens: TokensObject,\n scope: string,\n subservice: string,\n ): Promise<U> {\n const service = this.strategyToService[strategy];\n if (!service) throw new Error('Strategy not supported');\n\n const profile = await service.getProfile(tokens);\n const accountId = service.getId(profile);\n if (!accountId) throw new Error('Invalid profile: no id found');\n\n const emails = service.getEmails(profile);\n\n let user: Partial<U> | undefined =\n await this.usersManager.findOneByAccountOrEmails({\n provider: service.providerKey,\n accountId,\n emails,\n });\n\n logger.info(!user ? 'create user' : 'existing user', { emails, user });\n\n if (!user) {\n user = {};\n }\n\n Object.assign(user, {\n displayName: service.getDisplayName(profile),\n fullName: service.getFullName(profile),\n status: STATUSES.VALIDATED,\n });\n\n if (!user.accounts) user.accounts = [];\n\n let account: Partial<Account> | undefined = user.accounts.find(\n (account: Account) =>\n account.provider === strategy && account.accountId === accountId,\n );\n\n if (!account) {\n account = { provider: strategy, accountId };\n // @ts-expect-error well...\n user.accounts.push(account);\n }\n\n account.name = service.getAccountName(profile);\n account.status = 'valid';\n account.profile = profile;\n account.accessToken = tokens.accessToken;\n if (tokens.refreshToken) {\n account.refreshToken = tokens.refreshToken;\n }\n if (tokens.expireDate) {\n account.tokenExpireDate = tokens.expireDate;\n }\n account.scope = service.getScope(account.scope, scope);\n\n if (!account.subservices) account.subservices = [];\n if (subservice && !account.subservices.includes(subservice)) {\n account.subservices.push(subservice);\n }\n\n if (!user.emails) user.emails = [];\n const userEmails = user.emails;\n emails.forEach((email: string) => {\n if (!userEmails.includes(email)) {\n userEmails.push(email);\n }\n });\n\n user.emailDomains = [\n // eslint-disable-next-line unicorn/no-array-reduce\n ...user.emails.reduce(\n (domains: Set<string>, email: string) =>\n domains.add(email.split('@', 2)[1]),\n new Set<string>(),\n ),\n ];\n\n const keyPath = this.usersManager.store.keyPath;\n\n if (user[keyPath]) {\n await this.usersManager.replaceOne(user as U);\n } else {\n await this.usersManager.insertOne(user as U);\n }\n\n return user as U;\n }\n\n async updateAccount(user: U, account: Account): Promise<U> {\n await this.usersManager.updateAccount(user, account);\n return user;\n }\n}\n","import type { IncomingMessage } from 'http';\nimport type { Option } from 'cookies';\nimport Cookies from 'cookies';\n\nexport const COOKIE_NAME = 'connectedUser';\n\nexport const getTokenFromRequest = (\n req: IncomingMessage,\n options?: Pick<Option, Exclude<keyof Option, 'secure'>>,\n): string | undefined => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n const cookies = new Cookies(req, null as unknown as any, {\n ...options,\n secure: true,\n });\n\n return cookies.get(COOKIE_NAME);\n};\n","import { promisify } from 'util';\nimport type {\n GetPublicKeyOrSecret,\n Secret,\n VerifyCallback,\n VerifyOptions,\n} from 'jsonwebtoken';\nimport jsonwebtoken from 'jsonwebtoken';\nimport type { Logger } from 'nightingale-logger';\nimport type { User, UserSanitized } from '../../types.d';\nimport type MongoUsersManager from '../MongoUsersManager';\n\ntype Verify = (\n token: string,\n secretOrPublicKey: Secret | GetPublicKeyOrSecret,\n options?: VerifyOptions,\n callback?: VerifyCallback,\n) => void;\n\nconst verifyPromisified = promisify<\n Parameters<Verify>[0],\n Parameters<Verify>[1],\n Parameters<Verify>[2],\n Parameters<VerifyCallback>[1]\n>(jsonwebtoken.verify as Verify);\n\nconst createDecodeJWT =\n (secretKey: string) =>\n async (token: string, jwtAudience: string): Promise<string | undefined> => {\n const result = await verifyPromisified(token, secretKey, {\n algorithms: ['HS512'],\n audience: jwtAudience,\n });\n return (result as any)?.connected as string | undefined;\n };\n\nexport type FindConnectedAndUser<U extends User> = (\n jwtAudience?: string,\n token?: string,\n) => Promise<[null | undefined | U['_id'], null | undefined | U]>;\n\nexport const createFindConnectedAndUser = <\n U extends User,\n USanitized extends UserSanitized,\n>(\n secretKey: string,\n usersManager: MongoUsersManager<U, USanitized>,\n logger: Logger,\n): FindConnectedAndUser<U> => {\n const decodeJwt = createDecodeJWT(secretKey);\n\n const findConnectedAndUser: FindConnectedAndUser<U> = async (\n jwtAudience,\n token,\n ) => {\n if (!token || !jwtAudience) return [null, null];\n\n let connected;\n try {\n connected = await decodeJwt(token, jwtAudience);\n } catch (err: unknown) {\n logger.debug('failed to verify authentification', { err });\n }\n\n if (connected == null) return [null, null];\n\n const user = await usersManager.findConnected(connected);\n\n return [connected, user];\n };\n\n return findConnectedAndUser;\n};\n","import type { MongoInsertType, MongoStore, Update } from 'liwi-mongo';\nimport type { User, Account, UserSanitized } from '../types.d';\n\nexport default class MongoUsersManager<\n U extends User = User,\n USanitized extends UserSanitized = UserSanitized,\n> {\n store: MongoStore<U>;\n\n constructor(store: MongoStore<U>) {\n this.store = store;\n }\n\n findConnected(connected: string): Promise<U | undefined> {\n return this.store.findByKey(connected);\n }\n\n insertOne(user: MongoInsertType<U>): Promise<any> {\n return this.store.insertOne(user);\n }\n\n replaceOne(user: U): Promise<any> {\n return this.store.replaceOne(user);\n }\n\n sanitize(user: U): USanitized {\n return this.sanitizeBaseUser(user) as USanitized;\n }\n\n findOneByAccountOrEmails({\n accountId,\n emails,\n provider,\n }: {\n accountId: string | number;\n emails?: string[];\n provider: string;\n }): Promise<U | undefined> {\n let query: any = {\n 'accounts.provider': provider,\n 'accounts.accountId': accountId,\n };\n\n if (emails && emails.length > 0) {\n query = {\n $or: [\n query,\n {\n emails: { $in: emails },\n },\n ],\n };\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n return this.store.findOne(query);\n }\n\n updateAccount(user: U, account: Account): Promise<U> {\n const accountIndex = user.accounts.indexOf(account);\n if (accountIndex === -1) {\n throw new Error('Invalid account');\n }\n\n return this.store.partialUpdateOne(user, {\n $set: {\n [`accounts.${accountIndex}`]: account,\n },\n } as Update<U>);\n }\n\n protected sanitizeBaseUser(user: U): UserSanitized {\n return {\n _id: user._id,\n created: user.created,\n updated: user.updated,\n displayName: user.displayName,\n fullName: user.fullName,\n status: user.status,\n emails: user.emails,\n emailDomains: user.emailDomains,\n accounts: user.accounts.map((account: Account) => ({\n provider: account.provider,\n accountId: account.accountId,\n name: account.name,\n status: account.status,\n profile: account.profile,\n })),\n };\n }\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-argument */\n/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\nimport { fetch } from 'alp-node';\nimport type { Tokens } from '../authentification/types';\nimport type { AccountService, FullName } from './types';\n\nexport default class UserAccountGoogleService<ScopeKeys extends 'login'>\n implements AccountService<ScopeKeys>\n{\n scopeKeyToScope: Record<ScopeKeys, string>;\n\n constructor(scopeKeyToScope: Record<Exclude<'login', ScopeKeys>, string>) {\n this.scopeKeyToScope = {\n ...scopeKeyToScope,\n login: 'openid profile email',\n };\n }\n\n providerKey = 'google';\n\n getProfile(tokens: Tokens): Promise<any> {\n return fetch(\n `https://www.googleapis.com/oauth2/v1/userinfo?access_token=${tokens.accessToken}`,\n ).then((response) => response.json());\n }\n\n getId(profile: any): any {\n return profile.id;\n }\n\n getAccountName(profile: any): string | null | undefined {\n return profile.email;\n }\n\n getEmails(profile: any): string[] {\n const emails: string[] = [];\n\n if (profile.email) {\n emails.push(profile.email);\n }\n\n return emails;\n }\n\n getDisplayName(profile: any): string | null | undefined {\n return profile.name;\n }\n\n getFullName(profile: any): FullName {\n return {\n givenName: profile.given_name,\n familyName: profile.family_name,\n };\n }\n\n getDefaultScope(newScope: string): string[] {\n return this.getScope(undefined, newScope);\n }\n\n getScope(oldScope: string[] | undefined, newScope: string): string[] {\n return !oldScope\n ? newScope.split(' ')\n : [...oldScope, ...newScope.split(' ')].filter(\n (item, i, ar) => ar.indexOf(item) === i,\n );\n }\n}\n","/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\nimport { fetch } from 'alp-node';\nimport type { Tokens } from '../authentification/types';\nimport type { AccountService, FullName } from './types';\n\n// https://api.slack.com/methods/users.identity\n\nexport default class UserAccountSlackService<ScopeKeys extends 'login'>\n implements AccountService<ScopeKeys>\n{\n scopeKeyToScope: Record<ScopeKeys, string>;\n\n constructor(scopeKeyToScope: Record<Exclude<'login', ScopeKeys>, string>) {\n this.scopeKeyToScope = {\n ...scopeKeyToScope,\n login: 'identity.basic identity.email identity.avatar',\n };\n }\n\n providerKey = 'google';\n\n getProfile(tokens: Tokens): Promise<any> {\n return fetch(\n `https://slack.com/api/users.identity?token=${tokens.accessToken}`,\n ).then((response) => response.json());\n }\n\n getId(profile: any): string | null {\n if (\n !profile ||\n !profile.team ||\n !profile.team.id ||\n !profile.user ||\n !profile.user.id\n ) {\n return null;\n }\n return `team:${profile.team.id as string};user:${\n profile.user.id as string\n }`;\n }\n\n getAccountName(profile: any): string | null | undefined {\n return profile.user.email;\n }\n\n getEmails(profile: any): string[] {\n return profile.user.email ? [profile.user.email] : [];\n }\n\n getDisplayName(profile: any): string | null | undefined {\n return profile.user.name;\n }\n\n getFullName(profile: any): FullName | null {\n return null;\n }\n\n getDefaultScope(newScope: string): string[] {\n return this.getScope(undefined, newScope);\n }\n\n getScope(oldScope: string[] | undefined, newScope: string): string[] {\n return !oldScope\n ? newScope.split(' ')\n : [...oldScope, ...newScope.split(' ')].filter(\n (item, i, ar) => ar.indexOf(item) === i,\n );\n }\n}\n","import type { NodeApplication } from 'alp-types';\nimport type { Option } from 'cookies';\nimport { Logger } from 'nightingale-logger';\nimport type { User } from '../types.d';\nimport type MongoUsersManager from './MongoUsersManager';\nimport { getTokenFromRequest } from './utils/cookies';\nimport { createFindConnectedAndUser } from './utils/createFindConnectedAndUser';\n\nconst logger = new Logger('alp:auth');\n\nexport const authSocketIO = <U extends User = User>(\n app: NodeApplication,\n usersManager: MongoUsersManager<U>,\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n io: any,\n options?: Pick<Option, Exclude<keyof Option, 'secure'>>,\n): void => {\n const findConnectedAndUser = createFindConnectedAndUser(\n app.config.get<Map<string, string>>('authentication').get('secretKey')!,\n usersManager,\n logger,\n );\n\n const users = new Map();\n io.users = users;\n\n io.use(async (socket: any, next: any) => {\n const handshakeData = socket.request;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n const token = getTokenFromRequest(handshakeData);\n\n if (!token) return next();\n\n const [connected, user] = await findConnectedAndUser(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n handshakeData.headers['user-agent'],\n token,\n );\n\n if (!connected || !user) return next();\n\n socket.user = user;\n users.set(socket.client.id, user);\n\n socket.on('disconnected', () => users.delete(socket.client.id));\n\n await next();\n });\n};\n","import type { IncomingMessage } from 'http';\nimport type { NodeConfig } from 'alp-types';\nimport { Logger } from 'nightingale-logger';\nimport type { User } from '../types.d';\nimport type MongoUsersManager from './MongoUsersManager';\nimport { getTokenFromRequest, COOKIE_NAME } from './utils/cookies';\nimport { createFindConnectedAndUser } from './utils/createFindConnectedAndUser';\n\nconst logger = new Logger('alp:auth');\n\nconst getTokenFromReq = (\n req: IncomingMessage & { cookies?: Record<string, string> },\n): string | undefined => {\n if (req.cookies) return req.cookies[COOKIE_NAME];\n return getTokenFromRequest(req);\n};\n\n/*\n * Not tested yet.\n * @internal\n */\nexport const createAuthApolloContext = <U extends User = User>(\n config: NodeConfig,\n usersManager: MongoUsersManager<U>,\n): any => {\n const findConnectedAndUser = createFindConnectedAndUser(\n config.get<Map<string, string>>('authentication').get('secretKey')!,\n usersManager,\n logger,\n );\n\n return async ({ req, connection }: { req: any; connection: any }) => {\n if (connection?.user) {\n return { user: connection.user };\n }\n\n if (!req) return null;\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n const token = getTokenFromReq(req);\n\n if (!token) return { user: undefined };\n\n const [, user] = await findConnectedAndUser(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n req.headers['user-agent'],\n token,\n );\n\n return { user };\n };\n};\n","import type { IncomingMessage } from 'http';\nimport { promisify } from 'util';\nimport type { Context } from 'alp-node';\nimport type { ContextState, NodeApplication } from 'alp-types';\nimport jsonwebtoken from 'jsonwebtoken';\nimport { Logger } from 'nightingale-logger';\nimport type { User, UserSanitized } from '../types.d';\nimport type MongoUsersManager from './MongoUsersManager';\nimport type {\n AuthController as AuthControllerType,\n AuthHooks,\n} from './createAuthController';\nimport { createAuthController } from './createAuthController';\nimport type { AuthRoutes as AuthRoutesType } from './createRoutes';\nimport { createRoutes } from './createRoutes';\nimport type { Strategies } from './services/authentification/AuthenticationService';\nimport { AuthenticationService } from './services/authentification/AuthenticationService';\nimport type { AllowedStrategyKeys } from './services/authentification/types';\nimport UserAccountsService from './services/user/UserAccountsService';\nimport type { AccountService } from './services/user/types';\nimport { getTokenFromRequest, COOKIE_NAME } from './utils/cookies';\nimport { createFindConnectedAndUser } from './utils/createFindConnectedAndUser';\n\nexport { default as MongoUsersManager } from './MongoUsersManager';\nexport { default as UserAccountGoogleService } from './services/user/UserAccountGoogleService';\nexport { default as UserAccountSlackService } from './services/user/UserAccountSlackService';\nexport { authSocketIO } from './authSocketIO';\nexport { createAuthApolloContext } from './authApolloContext';\nexport { STATUSES } from './services/user/UserAccountsService';\n\ndeclare module 'alp-types' {\n // eslint-disable-next-line @typescript-eslint/no-shadow\n interface ContextState {\n connected: NonNullable<ContextState['user']>['_id'] | null | undefined;\n user: User | null | undefined;\n }\n\n interface ContextSanitizedState {\n connected:\n | NonNullable<ContextSanitizedState['user']>['_id']\n | null\n | undefined;\n user: UserSanitized | null | undefined;\n }\n\n interface BaseContext {\n setConnected: (\n connected: NonNullable<ContextState['user']>['_id'],\n user: NonNullable<ContextState['user']>,\n ) => Promise<void>;\n logout: () => void;\n }\n}\n\nconst logger = new Logger('alp:auth');\n\nconst signPromisified: any = promisify(jsonwebtoken.sign);\n\nexport type AuthController = AuthControllerType;\nexport type AuthRoutes = AuthRoutesType;\nexport { AuthenticationService } from './services/authentification/AuthenticationService';\n\nexport default function init<\n StrategyKeys extends AllowedStrategyKeys = 'google',\n U extends User = User,\n USanitized extends UserSanitized = UserSanitized,\n>({\n homeRouterKey,\n usersManager,\n strategies,\n defaultStrategy,\n strategyToService,\n authHooks,\n jwtAudience,\n}: {\n homeRouterKey?: string;\n usersManager: MongoUsersManager<U, USanitized>;\n strategies: Strategies<StrategyKeys>;\n defaultStrategy?: StrategyKeys;\n strategyToService: Record<StrategyKeys, AccountService<any>>;\n authHooks?: AuthHooks<StrategyKeys>;\n jwtAudience?: string;\n}) {\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n return (app: NodeApplication) => {\n const userAccountsService = new UserAccountsService(\n usersManager,\n strategyToService,\n );\n\n const authenticationService = new AuthenticationService(\n app.config,\n strategies,\n userAccountsService,\n );\n\n const controller = createAuthController({\n usersManager,\n authenticationService,\n homeRouterKey,\n defaultStrategy,\n authHooks,\n });\n\n app.context.setConnected = async function (\n this: Context,\n connected: NonNullable<ContextState['user']>['_id'],\n user: NonNullable<ContextState['user']>,\n ): Promise<void> {\n logger.debug('setConnected', { connected });\n if (!connected) {\n throw new Error('Illegal value for setConnected');\n }\n\n this.state.connected = connected;\n this.state.user = user;\n\n const token = await signPromisified(\n { connected, time: Date.now() },\n this.config\n .get<Map<string, unknown>>('authentication')\n .get('secretKey'),\n {\n algorithm: 'HS512',\n audience: jwtAudience || this.request.headers['user-agent'],\n expiresIn: '30 days',\n },\n );\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n this.cookies.set(COOKIE_NAME, token, {\n httpOnly: true,\n secure: this.config.get('allowHttps'),\n });\n };\n\n app.context.logout = function (this: Context): void {\n delete this.state.connected;\n delete this.state.user;\n this.cookies.set(COOKIE_NAME, '', { expires: new Date(1) });\n };\n\n const getConnectedAndUser = createFindConnectedAndUser(\n app.config\n .get<Map<string, unknown>>('authentication')\n .get('secretKey') as string,\n usersManager,\n logger,\n );\n\n return {\n routes: createRoutes(controller),\n\n getConnectedAndUserFromRequest: (\n req: IncomingMessage,\n ): ReturnType<typeof getConnectedAndUser> => {\n const token = getTokenFromRequest(req);\n return getConnectedAndUser(\n jwtAudience || req.headers['user-agent'],\n token,\n );\n },\n getConnectedAndUser,\n\n middleware: async <T>(\n ctx: Context,\n next: () => T | Promise<T>,\n ): Promise<T> => {\n const token = ctx.cookies.get(COOKIE_NAME);\n const userAgent = ctx.request.headers['user-agent'];\n logger.debug('middleware', { token });\n\n const setState = (\n connected: U['_id'] | null | undefined,\n user: U | null | undefined,\n ): void => {\n ctx.state.connected = connected;\n ctx.state.user = user;\n ctx.sanitizedState.connected = connected;\n ctx.sanitizedState.user = user && usersManager.sanitize(user);\n };\n\n const [connected, user] = await getConnectedAndUser(\n jwtAudience || userAgent,\n token,\n );\n logger.debug('middleware', { connected });\n\n if (connected == null || user == null) {\n if (token) ctx.cookies.set(COOKIE_NAME, '', { expires: new Date(1) });\n setState(null, null);\n return next();\n }\n\n setState(connected, user);\n return next();\n },\n };\n };\n}\n"],"names":["createAuthController","usersManager","authenticationService","homeRouterKey","defaultStrategy","authHooks","login","ctx","strategy","namedParam","Error","params","paramsForLogin","redirectAuthUrl","addScope","state","connected","redirectTo","scopeKey","loginResponse","assert","connectedUser","accessResponse","afterLoginSuccess","afterScopeUpdate","keyPath","store","setConnected","logout","createRoutes","controller","segment","add","defaultRoute","randomBytesPromisified","promisify","randomBytes","randomHex","size","buffer","toString","logger","Logger","AuthenticationService","EventEmitter","constructor","config","strategies","userAccountsService","generateAuthUrl","debug","strategyInstance","type","oauth2","authorizationCode","authorizeURL","getTokens","options","result","getToken","code","redirect_uri","redirectUri","accessToken","access_token","refreshToken","refresh_token","tokenType","token_type","expiresIn","expires_in","expireDate","d","Date","setTime","getTime","idToken","id_token","tokensParam","token","create","refresh","tokens","host","get","request","urlGenerator","user","accountId","scope","getScope","cookies","set","JSON","stringify","isLoginAccess","maxAge","httpOnly","secure","access_type","redirect","isConnected","hooks","query","error","status","expose","cookieName","cookie","expires","parse","findOrCreateFromStrategy","account","update","refreshAccountTokens","tokenExpireDate","now","Promise","resolve","provider","then","updateAccount","STATUSES","VALIDATED","DELETED","UserAccountsService","strategyToService","userId","_id","service","newScope","scopeKeyToScope","accounts","find","join","subservice","profile","getProfile","getId","subservices","includes","push","replaceOne","emails","getEmails","findOneByAccountOrEmails","providerKey","info","Object","assign","displayName","getDisplayName","fullName","getFullName","name","getAccountName","userEmails","forEach","email","emailDomains","reduce","domains","split","Set","insertOne","COOKIE_NAME","getTokenFromRequest","req","Cookies","verifyPromisified","jsonwebtoken","verify","createDecodeJWT","secretKey","jwtAudience","algorithms","audience","createFindConnectedAndUser","decodeJwt","err","findConnected","MongoUsersManager","findByKey","sanitize","sanitizeBaseUser","length","$or","$in","findOne","accountIndex","indexOf","partialUpdateOne","$set","created","updated","map","UserAccountGoogleService","fetch","response","json","id","givenName","given_name","familyName","family_name","getDefaultScope","undefined","oldScope","filter","item","i","ar","UserAccountSlackService","team","authSocketIO","app","io","findConnectedAndUser","users","Map","use","socket","next","handshakeData","headers","client","on","delete","getTokenFromReq","createAuthApolloContext","connection","signPromisified","sign","init","context","time","algorithm","getConnectedAndUser","routes","getConnectedAndUserFromRequest","middleware","userAgent","setState","sanitizedState"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-node14.mjs","sources":["../src/createAuthController.ts","../src/createRoutes.ts","../src/utils/generators.ts","../src/services/authentification/AuthenticationService.ts","../src/services/user/UserAccountsService.ts","../src/utils/cookies.ts","../src/utils/createFindConnectedAndUser.ts","../src/MongoUsersManager.ts","../src/services/user/UserAccountGoogleService.ts","../src/services/user/UserAccountSlackService.ts","../src/authSocketIO.ts","../src/authApolloContext.ts","../src/index.ts"],"sourcesContent":["import type { Context } from 'alp-node';\nimport 'alp-router';\nimport type { User, UserSanitized } from '../types.d';\nimport type MongoUsersManager from './MongoUsersManager';\nimport type {\n AuthenticationService,\n AccessResponseHooks,\n} from './services/authentification/AuthenticationService';\nimport type {\n AllowedStrategyKeys,\n AllowedMapParamsStrategy,\n} from './services/authentification/types';\n\nexport interface CreateAuthControllerParams<\n StrategyKeys extends AllowedStrategyKeys,\n U extends User = User,\n USanitized extends UserSanitized = UserSanitized,\n> {\n authenticationService: AuthenticationService<StrategyKeys, U, UserSanitized>;\n homeRouterKey?: string;\n usersManager: MongoUsersManager<U, USanitized>;\n defaultStrategy?: StrategyKeys;\n authHooks?: AuthHooks<StrategyKeys>;\n}\n\nexport interface AuthController {\n login: (ctx: Context) => Promise<void>;\n addScope: (ctx: Context) => Promise<void>;\n loginResponse: (ctx: Context) => Promise<void>;\n logout: (ctx: Context) => Promise<void>;\n}\n\ntype OptionalRecord<K extends keyof any, T> = { [P in K]?: T };\n\nexport interface AuthHooks<StrategyKeys extends AllowedStrategyKeys>\n extends AccessResponseHooks<StrategyKeys> {\n paramsForLogin?: <StrategyKey extends StrategyKeys>(\n strategy: StrategyKey,\n ctx: Context,\n ) => // eslint-disable-next-line @typescript-eslint/no-invalid-void-type\n | void\n | Promise<void>\n | OptionalRecord<AllowedMapParamsStrategy[StrategyKey], any>\n | Promise<OptionalRecord<AllowedMapParamsStrategy[StrategyKey], any>>;\n}\n\nexport function createAuthController<\n StrategyKeys extends AllowedStrategyKeys,\n U extends User = User,\n USanitized extends UserSanitized = UserSanitized,\n>({\n usersManager,\n authenticationService,\n homeRouterKey = '/',\n defaultStrategy,\n authHooks = {},\n}: CreateAuthControllerParams<StrategyKeys, U, USanitized>): AuthController {\n return {\n async login(ctx: Context): Promise<void> {\n const strategy: StrategyKeys = (ctx.namedParam('strategy') ||\n defaultStrategy) as StrategyKeys;\n if (!strategy) throw new Error('Strategy missing');\n const params =\n (authHooks.paramsForLogin &&\n (await authHooks.paramsForLogin(strategy, ctx))) ||\n {};\n await authenticationService.redirectAuthUrl(ctx, strategy, {}, params);\n },\n\n async addScope(ctx: Context): Promise<void> {\n if (ctx.state.connected) {\n await ctx.redirectTo(homeRouterKey);\n return;\n }\n\n const strategy: StrategyKeys = (ctx.namedParam('strategy') ||\n defaultStrategy) as StrategyKeys;\n if (!strategy) throw new Error('Strategy missing');\n const scopeKey = ctx.namedParam('scopeKey');\n if (!scopeKey) throw new Error('Scope missing');\n await authenticationService.redirectAuthUrl(ctx, strategy, { scopeKey });\n },\n\n async loginResponse(ctx: Context): Promise<void> {\n if (ctx.state.connected) {\n await ctx.redirectTo(homeRouterKey);\n return;\n }\n\n const strategy: StrategyKeys = ctx.namedParam('strategy') as StrategyKeys;\n ctx.assert(strategy);\n\n const connectedUser = await authenticationService.accessResponse(\n ctx,\n strategy,\n ctx.state.connected as boolean | undefined,\n {\n afterLoginSuccess: authHooks.afterLoginSuccess,\n afterScopeUpdate: authHooks.afterScopeUpdate,\n },\n );\n const keyPath = usersManager.store.keyPath;\n await ctx.setConnected(connectedUser[keyPath], connectedUser);\n await ctx.redirectTo(homeRouterKey);\n },\n\n async logout(ctx: Context): Promise<void> {\n ctx.logout();\n await ctx.redirectTo(homeRouterKey);\n },\n };\n}\n","import type { AuthController } from './createAuthController';\n\nexport interface AuthRoutes {\n login: [string, (segment: any) => void];\n addScope: [string, AuthController['addScope']];\n logout: [string, AuthController['logout']];\n}\n\nexport const createRoutes = (controller: AuthController): AuthRoutes => ({\n login: [\n '/login/:strategy?',\n (segment: any) => {\n segment.add('/response', controller.loginResponse, 'loginResponse');\n segment.defaultRoute(controller.login, 'login');\n },\n ],\n addScope: ['/auth/add-scope/:strategy/:scopeKey', controller.addScope],\n logout: ['/logout', controller.logout],\n});\n","import { randomBytes } from 'crypto';\nimport { promisify } from 'util';\n\nconst randomBytesPromisified = promisify(randomBytes);\n\nexport async function randomBase64(size: number): Promise<string> {\n const buffer = await randomBytesPromisified(size);\n return buffer.toString('base64');\n}\n\nexport async function randomHex(size: number): Promise<string> {\n const buffer = await randomBytesPromisified(size);\n return buffer.toString('hex');\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-argument */\n/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable camelcase, max-lines */\nimport { EventEmitter } from 'events';\nimport 'alp-router';\nimport type { Context, NodeConfig } from 'alp-types';\nimport { Logger } from 'nightingale-logger';\nimport type { OAuthClient } from 'simple-oauth2';\nimport type { AccountId, User, Account, UserSanitized } from '../../../types.d';\nimport { randomHex } from '../../utils/generators';\nimport type UserAccountsService from '../user/UserAccountsService';\nimport type { AllowedStrategyKeys, Tokens } from './types';\n\nconst logger = new Logger('alp:auth:authentication');\n\nexport interface GenerateAuthUrlOptions {\n accessType?: string;\n grantType?: string;\n includeGrantedScopes?: boolean;\n loginHint?: string;\n prompt?: string;\n redirectUri?: string;\n scope?: string;\n state?: string;\n}\n\nexport interface GetTokensOptions {\n code: string;\n redirectUri: string;\n}\n\nexport interface Strategy {\n type: string;\n}\n\nexport interface Oauth2Strategy<Params extends string> extends Strategy {\n oauth2: OAuthClient<Params>;\n}\n\nexport type Strategies<StrategyKeys extends AllowedStrategyKeys> = Record<\n StrategyKeys,\n Oauth2Strategy<any>\n>;\n\nexport interface AccessResponseHooks<StrategyKeys, U extends User = User> {\n afterLoginSuccess?: <StrategyKey extends StrategyKeys>(\n strategy: StrategyKey,\n connectedUser: U,\n ) => void | Promise<void>;\n\n afterScopeUpdate?: <StrategyKey extends StrategyKeys>(\n strategy: StrategyKey,\n scopeKey: string,\n account: Account,\n user: U,\n ) => void | Promise<void>;\n}\n\nexport class AuthenticationService<\n StrategyKeys extends AllowedStrategyKeys,\n U extends User = User,\n USanitized extends UserSanitized = UserSanitized,\n> extends EventEmitter {\n config: NodeConfig;\n\n strategies: Strategies<StrategyKeys>;\n\n userAccountsService: UserAccountsService<StrategyKeys, U, USanitized>;\n\n constructor(\n config: NodeConfig,\n strategies: Strategies<StrategyKeys>,\n userAccountsService: UserAccountsService<StrategyKeys, U, USanitized>,\n ) {\n super();\n this.config = config;\n this.strategies = strategies;\n this.userAccountsService = userAccountsService;\n }\n\n generateAuthUrl<T extends StrategyKeys>(strategy: T, params: any): string {\n logger.debug('generateAuthUrl', { strategy, params });\n const strategyInstance = this.strategies[strategy];\n switch (strategyInstance.type) {\n case 'oauth2':\n return strategyInstance.oauth2.authorizationCode.authorizeURL(params);\n default:\n throw new Error('Invalid strategy');\n }\n }\n\n async getTokens(\n strategy: StrategyKeys,\n options: GetTokensOptions,\n ): Promise<Tokens> {\n logger.debug('getTokens', { strategy, options });\n const strategyInstance = this.strategies[strategy];\n switch (strategyInstance.type) {\n case 'oauth2': {\n const result = await strategyInstance.oauth2.authorizationCode.getToken(\n {\n code: options.code,\n redirect_uri: options.redirectUri,\n },\n );\n if (!result) return result;\n return {\n accessToken: result.access_token,\n refreshToken: result.refresh_token,\n tokenType: result.token_type,\n expiresIn: result.expires_in,\n expireDate: (() => {\n const d = new Date();\n d.setTime(d.getTime() + result.expires_in * 1000);\n return d;\n })(),\n idToken: result.id_token,\n };\n // return strategyInstance.accessToken.create(result);\n }\n\n default:\n throw new Error('Invalid stategy');\n }\n }\n\n async refreshToken(\n strategy: StrategyKeys,\n tokensParam: { refreshToken: string },\n ): Promise<Tokens> {\n logger.debug('refreshToken', { strategy });\n if (!tokensParam.refreshToken) {\n throw new Error('Missing refresh token');\n }\n const strategyInstance = this.strategies[strategy];\n switch (strategyInstance.type) {\n case 'oauth2': {\n const token = strategyInstance.oauth2.accessToken.create({\n refresh_token: tokensParam.refreshToken,\n });\n const result = await token.refresh();\n const tokens = result.token;\n return {\n accessToken: tokens.access_token,\n tokenType: tokens.token_type,\n expiresIn: tokens.expires_in,\n expireDate: (() => {\n const d = new Date();\n d.setTime(d.getTime() + tokens.expires_in * 1000);\n return d;\n })(),\n idToken: tokens.id_token,\n };\n }\n\n default:\n throw new Error('Invalid stategy');\n }\n }\n\n redirectUri(ctx: Context, strategy: string): string {\n const host = `http${this.config.get('allowHttps') ? 's' : ''}://${\n ctx.request.host\n }`;\n return `${host}${ctx.urlGenerator('loginResponse', { strategy })}`;\n }\n\n async redirectAuthUrl(\n ctx: Context,\n strategy: StrategyKeys,\n {\n refreshToken,\n scopeKey,\n user,\n accountId,\n }: {\n refreshToken?: string | undefined;\n scopeKey?: string | undefined;\n user?: U;\n accountId?: AccountId;\n },\n params?: any,\n ): Promise<void> {\n logger.debug('redirectAuthUrl', { strategy, scopeKey, refreshToken });\n const state = await randomHex(8);\n const isLoginAccess = !scopeKey || scopeKey === 'login';\n const scope = this.userAccountsService.getScope(\n strategy,\n scopeKey || 'login',\n user,\n accountId,\n );\n\n if (!scope) {\n throw new Error('Invalid empty scope');\n }\n\n ctx.cookies.set(\n `auth_${strategy}_${state}`,\n JSON.stringify({\n scopeKey,\n scope,\n isLoginAccess,\n }),\n {\n maxAge: 10 * 60 * 1000,\n httpOnly: true,\n secure: this.config.get('allowHttps'),\n },\n );\n const redirectUri = this.generateAuthUrl(strategy, {\n redirect_uri: this.redirectUri(ctx, strategy),\n scope,\n state,\n access_type: refreshToken ? 'offline' : 'online',\n ...params,\n });\n\n return ctx.redirect(redirectUri);\n }\n\n async accessResponse<StrategyKey extends StrategyKeys>(\n ctx: any,\n strategy: StrategyKey,\n isConnected: undefined | boolean,\n hooks: AccessResponseHooks<StrategyKeys, U>,\n ): Promise<U> {\n if (ctx.query.error) {\n const error: any = new Error(ctx.query.error);\n error.status = 403;\n error.expose = true;\n throw error;\n }\n\n const code = ctx.query.code;\n const state = ctx.query.state;\n const cookieName = `auth_${strategy}_${state as string}`;\n let cookie = ctx.cookies.get(cookieName);\n ctx.cookies.set(cookieName, '', { expires: new Date(1) });\n if (!cookie) {\n throw new Error('No cookie for this state');\n }\n\n cookie = JSON.parse(cookie);\n if (!cookie || !cookie.scope) {\n throw new Error('Unexpected cookie value');\n }\n\n if (!cookie.isLoginAccess) {\n if (!isConnected) {\n throw new Error('You are not connected');\n }\n }\n\n const tokens: Tokens = await this.getTokens(strategy, {\n code,\n redirectUri: this.redirectUri(ctx, strategy),\n });\n\n if (cookie.isLoginAccess) {\n const user = await this.userAccountsService.findOrCreateFromStrategy(\n strategy,\n tokens,\n cookie.scope,\n cookie.scopeKey,\n );\n\n if (hooks.afterLoginSuccess) {\n await hooks.afterLoginSuccess(strategy, user);\n }\n\n return user;\n }\n\n const connectedUser = ctx.state.user;\n const { account, user } = await this.userAccountsService.update(\n connectedUser,\n strategy,\n tokens,\n cookie.scope,\n cookie.scopeKey,\n );\n\n if (hooks.afterScopeUpdate) {\n await hooks.afterScopeUpdate(strategy, cookie.scopeKey, account, user);\n }\n\n return connectedUser;\n }\n\n refreshAccountTokens(user: U, account: Account): Promise<boolean> {\n if (\n account.tokenExpireDate &&\n account.tokenExpireDate.getTime() > Date.now()\n ) {\n return Promise.resolve(false);\n }\n return this.refreshToken(account.provider as StrategyKeys, {\n // accessToken: account.accessToken,\n refreshToken: account.refreshToken!,\n }).then((tokens: Tokens) => {\n if (!tokens) {\n // serviceGoogle.updateFields({ accessToken:null, refreshToken:null, status: .OUTDATED });\n return false;\n }\n account.accessToken = tokens.accessToken;\n account.tokenExpireDate = tokens.expireDate;\n return this.userAccountsService\n .updateAccount(user, account)\n .then(() => true);\n });\n }\n}\n","/* eslint-disable @typescript-eslint/no-shadow */\nimport { EventEmitter } from 'events';\nimport { Logger } from 'nightingale-logger';\nimport type { AccountId, User, Account, UserSanitized } from '../../../types.d';\nimport type MongoUsersManager from '../../MongoUsersManager';\nimport type { AllowedStrategyKeys } from '../authentification/types';\nimport type { AccountService, TokensObject } from './types';\n\nconst logger = new Logger('alp:auth:userAccounts');\n\nexport const STATUSES = {\n VALIDATED: 'validated',\n DELETED: 'deleted',\n};\n\nexport default class UserAccountsService<\n StrategyKeys extends AllowedStrategyKeys,\n U extends User = User,\n USanitized extends UserSanitized = UserSanitized,\n> extends EventEmitter {\n private readonly strategyToService: Record<StrategyKeys, AccountService<any>>;\n\n usersManager: MongoUsersManager<U, USanitized>;\n\n constructor(\n usersManager: MongoUsersManager<U, USanitized>,\n strategyToService: Record<StrategyKeys, AccountService<any>>,\n ) {\n super();\n this.usersManager = usersManager;\n this.strategyToService = strategyToService;\n }\n\n getScope(\n strategy: StrategyKeys,\n scopeKey: string,\n user?: U,\n accountId?: AccountId,\n ): string {\n logger.debug('getScope', { strategy, userId: user?._id });\n const service = this.strategyToService[strategy];\n if (!service) {\n throw new Error('Strategy not supported');\n }\n\n const newScope = service.scopeKeyToScope[scopeKey];\n if (!user || !accountId) {\n return newScope;\n }\n const account = user.accounts.find(\n (account) =>\n account.provider === strategy && account.accountId === accountId,\n );\n\n if (!account) {\n throw new Error('Could not found associated account');\n }\n return service.getScope(account.scope, newScope).join(' ');\n }\n\n async update(\n user: U,\n strategy: StrategyKeys,\n tokens: TokensObject,\n scope: string,\n subservice: string,\n ): Promise<{ user: U; account: U['accounts'][number] }> {\n const service = this.strategyToService[strategy];\n const profile = await service.getProfile(tokens);\n const accountId = service.getId(profile);\n const account = user.accounts.find(\n (account) =>\n account.provider === strategy && account.accountId === accountId,\n );\n if (!account) {\n // TODO check if already exists in other user => merge\n // TODO else add a new account in this user\n throw new Error('Could not found associated account');\n }\n account.status = 'valid';\n account.accessToken = tokens.accessToken;\n if (tokens.refreshToken) {\n account.refreshToken = tokens.refreshToken;\n }\n if (tokens.expireDate) {\n account.tokenExpireDate = tokens.expireDate;\n }\n account.scope = service.getScope(account.scope, scope);\n account.subservices = account.subservices || [];\n if (subservice && !account.subservices.includes(subservice)) {\n account.subservices.push(subservice);\n }\n\n await this.usersManager.replaceOne(user);\n return { user, account };\n }\n\n async findOrCreateFromStrategy(\n strategy: StrategyKeys,\n tokens: TokensObject,\n scope: string,\n subservice: string,\n ): Promise<U> {\n const service = this.strategyToService[strategy];\n if (!service) throw new Error('Strategy not supported');\n\n const profile = await service.getProfile(tokens);\n const accountId = service.getId(profile);\n if (!accountId) throw new Error('Invalid profile: no id found');\n\n const emails = service.getEmails(profile);\n\n let user: Partial<U> | undefined =\n await this.usersManager.findOneByAccountOrEmails({\n provider: service.providerKey,\n accountId,\n emails,\n });\n\n logger.info(!user ? 'create user' : 'existing user', { emails, user });\n\n if (!user) {\n user = {};\n }\n\n Object.assign(user, {\n displayName: service.getDisplayName(profile),\n fullName: service.getFullName(profile),\n status: STATUSES.VALIDATED,\n });\n\n if (!user.accounts) user.accounts = [];\n\n let account: Partial<Account> | undefined = user.accounts.find(\n (account: Account) =>\n account.provider === strategy && account.accountId === accountId,\n );\n\n if (!account) {\n account = { provider: strategy, accountId };\n // @ts-expect-error well...\n user.accounts.push(account);\n }\n\n account.name = service.getAccountName(profile);\n account.status = 'valid';\n account.profile = profile;\n account.accessToken = tokens.accessToken;\n if (tokens.refreshToken) {\n account.refreshToken = tokens.refreshToken;\n }\n if (tokens.expireDate) {\n account.tokenExpireDate = tokens.expireDate;\n }\n account.scope = service.getScope(account.scope, scope);\n\n if (!account.subservices) account.subservices = [];\n if (subservice && !account.subservices.includes(subservice)) {\n account.subservices.push(subservice);\n }\n\n if (!user.emails) user.emails = [];\n const userEmails = user.emails;\n emails.forEach((email: string) => {\n if (!userEmails.includes(email)) {\n userEmails.push(email);\n }\n });\n\n user.emailDomains = [\n // eslint-disable-next-line unicorn/no-array-reduce\n ...user.emails.reduce(\n (domains: Set<string>, email: string) =>\n domains.add(email.split('@', 2)[1]),\n new Set<string>(),\n ),\n ];\n\n const keyPath = this.usersManager.store.keyPath;\n\n if (user[keyPath]) {\n await this.usersManager.replaceOne(user as U);\n } else {\n await this.usersManager.insertOne(user as U);\n }\n\n return user as U;\n }\n\n async updateAccount(user: U, account: Account): Promise<U> {\n await this.usersManager.updateAccount(user, account);\n return user;\n }\n}\n","import type { IncomingMessage } from 'http';\nimport type { Option } from 'cookies';\nimport Cookies from 'cookies';\n\nexport const COOKIE_NAME = 'connectedUser';\n\nexport const getTokenFromRequest = (\n req: IncomingMessage,\n options?: Pick<Option, Exclude<keyof Option, 'secure'>>,\n): string | undefined => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n const cookies = new Cookies(req, null as unknown as any, {\n ...options,\n secure: true,\n });\n\n return cookies.get(COOKIE_NAME);\n};\n","import { promisify } from 'util';\nimport type {\n GetPublicKeyOrSecret,\n Secret,\n VerifyCallback,\n VerifyOptions,\n} from 'jsonwebtoken';\nimport jsonwebtoken from 'jsonwebtoken';\nimport type { Logger } from 'nightingale-logger';\nimport type { User, UserSanitized } from '../../types.d';\nimport type MongoUsersManager from '../MongoUsersManager';\n\ntype Verify = (\n token: string,\n secretOrPublicKey: Secret | GetPublicKeyOrSecret,\n options?: VerifyOptions,\n callback?: VerifyCallback,\n) => void;\n\nconst verifyPromisified = promisify<\n Parameters<Verify>[0],\n Parameters<Verify>[1],\n Parameters<Verify>[2],\n Parameters<VerifyCallback>[1]\n>(jsonwebtoken.verify as Verify);\n\nconst createDecodeJWT =\n (secretKey: string) =>\n async (token: string, jwtAudience: string): Promise<string | undefined> => {\n const result = await verifyPromisified(token, secretKey, {\n algorithms: ['HS512'],\n audience: jwtAudience,\n });\n return (result as any)?.connected as string | undefined;\n };\n\nexport type FindConnectedAndUser<U extends User> = (\n jwtAudience?: string,\n token?: string,\n) => Promise<[null | undefined | U['_id'], null | undefined | U]>;\n\nexport const createFindConnectedAndUser = <\n U extends User,\n USanitized extends UserSanitized,\n>(\n secretKey: string,\n usersManager: MongoUsersManager<U, USanitized>,\n logger: Logger,\n): FindConnectedAndUser<U> => {\n const decodeJwt = createDecodeJWT(secretKey);\n\n const findConnectedAndUser: FindConnectedAndUser<U> = async (\n jwtAudience,\n token,\n ) => {\n if (!token || !jwtAudience) return [null, null];\n\n let connected;\n try {\n connected = await decodeJwt(token, jwtAudience);\n } catch (err: unknown) {\n logger.debug('failed to verify authentification', { err });\n }\n\n if (connected == null) return [null, null];\n\n const user = await usersManager.findConnected(connected);\n\n return [connected, user];\n };\n\n return findConnectedAndUser;\n};\n","import type { MongoInsertType, MongoStore, Update } from 'liwi-mongo';\nimport type { User, Account, UserSanitized } from '../types.d';\n\nexport default class MongoUsersManager<\n U extends User = User,\n USanitized extends UserSanitized = UserSanitized,\n> {\n store: MongoStore<U>;\n\n constructor(store: MongoStore<U>) {\n this.store = store;\n }\n\n findConnected(connected: string): Promise<U | undefined> {\n return this.store.findByKey(connected);\n }\n\n insertOne(user: MongoInsertType<U>): Promise<any> {\n return this.store.insertOne(user);\n }\n\n replaceOne(user: U): Promise<any> {\n return this.store.replaceOne(user);\n }\n\n sanitize(user: U): USanitized {\n return this.sanitizeBaseUser(user) as USanitized;\n }\n\n findOneByAccountOrEmails({\n accountId,\n emails,\n provider,\n }: {\n accountId: string | number;\n emails?: string[];\n provider: string;\n }): Promise<U | undefined> {\n let query: any = {\n 'accounts.provider': provider,\n 'accounts.accountId': accountId,\n };\n\n if (emails && emails.length > 0) {\n query = {\n $or: [\n query,\n {\n emails: { $in: emails },\n },\n ],\n };\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n return this.store.findOne(query);\n }\n\n updateAccount(user: U, account: Account): Promise<U> {\n const accountIndex = user.accounts.indexOf(account);\n if (accountIndex === -1) {\n throw new Error('Invalid account');\n }\n\n return this.store.partialUpdateOne(user, {\n $set: {\n [`accounts.${accountIndex}`]: account,\n },\n } as Update<U>);\n }\n\n protected sanitizeBaseUser(user: U): UserSanitized {\n return {\n _id: user._id,\n created: user.created,\n updated: user.updated,\n displayName: user.displayName,\n fullName: user.fullName,\n status: user.status,\n emails: user.emails,\n emailDomains: user.emailDomains,\n accounts: user.accounts.map((account: Account) => ({\n provider: account.provider,\n accountId: account.accountId,\n name: account.name,\n status: account.status,\n profile: account.profile,\n })),\n };\n }\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-argument */\n/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\nimport { fetch } from 'alp-node';\nimport type { Tokens } from '../authentification/types';\nimport type { AccountService, FullName } from './types';\n\nexport default class UserAccountGoogleService<ScopeKeys extends 'login'>\n implements AccountService<ScopeKeys>\n{\n scopeKeyToScope: Record<ScopeKeys, string>;\n\n constructor(scopeKeyToScope: Record<Exclude<'login', ScopeKeys>, string>) {\n this.scopeKeyToScope = {\n ...scopeKeyToScope,\n login: 'openid profile email',\n };\n }\n\n providerKey = 'google';\n\n getProfile(tokens: Tokens): Promise<any> {\n return fetch(\n `https://www.googleapis.com/oauth2/v1/userinfo?access_token=${tokens.accessToken}`,\n ).then((response) => response.json());\n }\n\n getId(profile: any): any {\n return profile.id;\n }\n\n getAccountName(profile: any): string | null | undefined {\n return profile.email;\n }\n\n getEmails(profile: any): string[] {\n const emails: string[] = [];\n\n if (profile.email) {\n emails.push(profile.email);\n }\n\n return emails;\n }\n\n getDisplayName(profile: any): string | null | undefined {\n return profile.name;\n }\n\n getFullName(profile: any): FullName {\n return {\n givenName: profile.given_name,\n familyName: profile.family_name,\n };\n }\n\n getDefaultScope(newScope: string): string[] {\n return this.getScope(undefined, newScope);\n }\n\n getScope(oldScope: string[] | undefined, newScope: string): string[] {\n return !oldScope\n ? newScope.split(' ')\n : [...oldScope, ...newScope.split(' ')].filter(\n (item, i, ar) => ar.indexOf(item) === i,\n );\n }\n}\n","/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\nimport { fetch } from 'alp-node';\nimport type { Tokens } from '../authentification/types';\nimport type { AccountService, FullName } from './types';\n\n// https://api.slack.com/methods/users.identity\n\nexport default class UserAccountSlackService<ScopeKeys extends 'login'>\n implements AccountService<ScopeKeys>\n{\n scopeKeyToScope: Record<ScopeKeys, string>;\n\n constructor(scopeKeyToScope: Record<Exclude<'login', ScopeKeys>, string>) {\n this.scopeKeyToScope = {\n ...scopeKeyToScope,\n login: 'identity.basic identity.email identity.avatar',\n };\n }\n\n providerKey = 'google';\n\n getProfile(tokens: Tokens): Promise<any> {\n return fetch(\n `https://slack.com/api/users.identity?token=${tokens.accessToken}`,\n ).then((response) => response.json());\n }\n\n getId(profile: any): string | null {\n if (\n !profile ||\n !profile.team ||\n !profile.team.id ||\n !profile.user ||\n !profile.user.id\n ) {\n return null;\n }\n return `team:${profile.team.id as string};user:${\n profile.user.id as string\n }`;\n }\n\n getAccountName(profile: any): string | null | undefined {\n return profile.user.email;\n }\n\n getEmails(profile: any): string[] {\n return profile.user.email ? [profile.user.email] : [];\n }\n\n getDisplayName(profile: any): string | null | undefined {\n return profile.user.name;\n }\n\n getFullName(profile: any): FullName | null {\n return null;\n }\n\n getDefaultScope(newScope: string): string[] {\n return this.getScope(undefined, newScope);\n }\n\n getScope(oldScope: string[] | undefined, newScope: string): string[] {\n return !oldScope\n ? newScope.split(' ')\n : [...oldScope, ...newScope.split(' ')].filter(\n (item, i, ar) => ar.indexOf(item) === i,\n );\n }\n}\n","import type { NodeApplication } from 'alp-types';\nimport type { Option } from 'cookies';\nimport { Logger } from 'nightingale-logger';\nimport type { User } from '../types.d';\nimport type MongoUsersManager from './MongoUsersManager';\nimport { getTokenFromRequest } from './utils/cookies';\nimport { createFindConnectedAndUser } from './utils/createFindConnectedAndUser';\n\nconst logger = new Logger('alp:auth');\n\nexport const authSocketIO = <U extends User = User>(\n app: NodeApplication,\n usersManager: MongoUsersManager<U>,\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n io: any,\n options?: Pick<Option, Exclude<keyof Option, 'secure'>>,\n): void => {\n const findConnectedAndUser = createFindConnectedAndUser(\n app.config.get<Map<string, string>>('authentication').get('secretKey')!,\n usersManager,\n logger,\n );\n\n const users = new Map();\n io.users = users;\n\n io.use(async (socket: any, next: any) => {\n const handshakeData = socket.request;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n const token = getTokenFromRequest(handshakeData);\n\n if (!token) return next();\n\n const [connected, user] = await findConnectedAndUser(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n handshakeData.headers['user-agent'],\n token,\n );\n\n if (!connected || !user) return next();\n\n socket.user = user;\n users.set(socket.client.id, user);\n\n socket.on('disconnected', () => users.delete(socket.client.id));\n\n await next();\n });\n};\n","import type { IncomingMessage } from 'http';\nimport type { NodeConfig } from 'alp-types';\nimport { Logger } from 'nightingale-logger';\nimport type { User } from '../types.d';\nimport type MongoUsersManager from './MongoUsersManager';\nimport { getTokenFromRequest, COOKIE_NAME } from './utils/cookies';\nimport { createFindConnectedAndUser } from './utils/createFindConnectedAndUser';\n\nconst logger = new Logger('alp:auth');\n\nconst getTokenFromReq = (\n req: IncomingMessage & { cookies?: Record<string, string> },\n): string | undefined => {\n if (req.cookies) return req.cookies[COOKIE_NAME];\n return getTokenFromRequest(req);\n};\n\n/*\n * Not tested yet.\n * @internal\n */\nexport const createAuthApolloContext = <U extends User = User>(\n config: NodeConfig,\n usersManager: MongoUsersManager<U>,\n): any => {\n const findConnectedAndUser = createFindConnectedAndUser(\n config.get<Map<string, string>>('authentication').get('secretKey')!,\n usersManager,\n logger,\n );\n\n return async ({ req, connection }: { req: any; connection: any }) => {\n if (connection?.user) {\n return { user: connection.user };\n }\n\n if (!req) return null;\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n const token = getTokenFromReq(req);\n\n if (!token) return { user: undefined };\n\n const [, user] = await findConnectedAndUser(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n req.headers['user-agent'],\n token,\n );\n\n return { user };\n };\n};\n","import type { IncomingMessage } from 'http';\nimport { promisify } from 'util';\nimport type { Context } from 'alp-node';\nimport type { ContextState, NodeApplication } from 'alp-types';\nimport jsonwebtoken from 'jsonwebtoken';\nimport { Logger } from 'nightingale-logger';\nimport type { User, UserSanitized } from '../types.d';\nimport type MongoUsersManager from './MongoUsersManager';\nimport type {\n AuthController as AuthControllerType,\n AuthHooks,\n} from './createAuthController';\nimport { createAuthController } from './createAuthController';\nimport type { AuthRoutes as AuthRoutesType } from './createRoutes';\nimport { createRoutes } from './createRoutes';\nimport type { Strategies } from './services/authentification/AuthenticationService';\nimport { AuthenticationService } from './services/authentification/AuthenticationService';\nimport type { AllowedStrategyKeys } from './services/authentification/types';\nimport UserAccountsService from './services/user/UserAccountsService';\nimport type { AccountService } from './services/user/types';\nimport { getTokenFromRequest, COOKIE_NAME } from './utils/cookies';\nimport { createFindConnectedAndUser } from './utils/createFindConnectedAndUser';\n\nexport { default as MongoUsersManager } from './MongoUsersManager';\nexport { default as UserAccountGoogleService } from './services/user/UserAccountGoogleService';\nexport { default as UserAccountSlackService } from './services/user/UserAccountSlackService';\nexport { authSocketIO } from './authSocketIO';\nexport { createAuthApolloContext } from './authApolloContext';\nexport { STATUSES } from './services/user/UserAccountsService';\n\ndeclare module 'alp-types' {\n // eslint-disable-next-line @typescript-eslint/no-shadow\n interface ContextState {\n connected: NonNullable<ContextState['user']>['_id'] | null | undefined;\n user: User | null | undefined;\n }\n\n interface ContextSanitizedState {\n connected:\n | NonNullable<ContextSanitizedState['user']>['_id']\n | null\n | undefined;\n user: UserSanitized | null | undefined;\n }\n\n interface BaseContext {\n setConnected: (\n connected: NonNullable<ContextState['user']>['_id'],\n user: NonNullable<ContextState['user']>,\n ) => Promise<void>;\n logout: () => void;\n }\n}\n\nconst logger = new Logger('alp:auth');\n\nconst signPromisified: any = promisify(jsonwebtoken.sign);\n\nexport type AuthController = AuthControllerType;\nexport type AuthRoutes = AuthRoutesType;\nexport { AuthenticationService } from './services/authentification/AuthenticationService';\n\nexport default function init<\n StrategyKeys extends AllowedStrategyKeys = 'google',\n U extends User = User,\n USanitized extends UserSanitized = UserSanitized,\n>({\n homeRouterKey,\n usersManager,\n strategies,\n defaultStrategy,\n strategyToService,\n authHooks,\n jwtAudience,\n}: {\n homeRouterKey?: string;\n usersManager: MongoUsersManager<U, USanitized>;\n strategies: Strategies<StrategyKeys>;\n defaultStrategy?: StrategyKeys;\n strategyToService: Record<StrategyKeys, AccountService<any>>;\n authHooks?: AuthHooks<StrategyKeys>;\n jwtAudience?: string;\n}) {\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n return (app: NodeApplication) => {\n const userAccountsService = new UserAccountsService(\n usersManager,\n strategyToService,\n );\n\n const authenticationService = new AuthenticationService(\n app.config,\n strategies,\n userAccountsService,\n );\n\n const controller = createAuthController({\n usersManager,\n authenticationService,\n homeRouterKey,\n defaultStrategy,\n authHooks,\n });\n\n app.context.setConnected = async function (\n this: Context,\n connected: NonNullable<ContextState['user']>['_id'],\n user: NonNullable<ContextState['user']>,\n ): Promise<void> {\n logger.debug('setConnected', { connected });\n if (!connected) {\n throw new Error('Illegal value for setConnected');\n }\n\n this.state.connected = connected;\n this.state.user = user;\n\n const token = await signPromisified(\n { connected, time: Date.now() },\n this.config\n .get<Map<string, unknown>>('authentication')\n .get('secretKey'),\n {\n algorithm: 'HS512',\n audience: jwtAudience || this.request.headers['user-agent'],\n expiresIn: '30 days',\n },\n );\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n this.cookies.set(COOKIE_NAME, token, {\n httpOnly: true,\n secure: this.config.get('allowHttps'),\n });\n };\n\n app.context.logout = function (this: Context): void {\n delete this.state.connected;\n delete this.state.user;\n this.cookies.set(COOKIE_NAME, '', { expires: new Date(1) });\n };\n\n const getConnectedAndUser = createFindConnectedAndUser(\n app.config\n .get<Map<string, unknown>>('authentication')\n .get('secretKey') as string,\n usersManager,\n logger,\n );\n\n return {\n routes: createRoutes(controller),\n\n getConnectedAndUserFromRequest: (\n req: IncomingMessage,\n ): ReturnType<typeof getConnectedAndUser> => {\n const token = getTokenFromRequest(req);\n return getConnectedAndUser(\n jwtAudience || req.headers['user-agent'],\n token,\n );\n },\n getConnectedAndUser,\n\n middleware: async <T>(\n ctx: Context,\n next: () => T | Promise<T>,\n ): Promise<T> => {\n const token = ctx.cookies.get(COOKIE_NAME);\n const userAgent = ctx.request.headers['user-agent'];\n logger.debug('middleware', { token });\n\n const setState = (\n connected: U['_id'] | null | undefined,\n user: U | null | undefined,\n ): void => {\n ctx.state.connected = connected;\n ctx.state.user = user;\n ctx.sanitizedState.connected = connected;\n ctx.sanitizedState.user = user && usersManager.sanitize(user);\n };\n\n const [connected, user] = await getConnectedAndUser(\n jwtAudience || userAgent,\n token,\n );\n logger.debug('middleware', { connected });\n\n if (connected == null || user == null) {\n if (token) ctx.cookies.set(COOKIE_NAME, '', { expires: new Date(1) });\n setState(null, null);\n return next();\n }\n\n setState(connected, user);\n return next();\n },\n };\n };\n}\n"],"names":["createAuthController","usersManager","authenticationService","homeRouterKey","defaultStrategy","authHooks","login","ctx","strategy","namedParam","Error","params","paramsForLogin","redirectAuthUrl","addScope","state","connected","redirectTo","scopeKey","loginResponse","assert","connectedUser","accessResponse","afterLoginSuccess","afterScopeUpdate","keyPath","store","setConnected","logout","createRoutes","controller","segment","add","defaultRoute","randomBytesPromisified","promisify","randomBytes","randomHex","size","buffer","toString","logger","Logger","AuthenticationService","EventEmitter","constructor","config","strategies","userAccountsService","generateAuthUrl","debug","strategyInstance","type","oauth2","authorizationCode","authorizeURL","getTokens","options","result","getToken","code","redirect_uri","redirectUri","accessToken","access_token","refreshToken","refresh_token","tokenType","token_type","expiresIn","expires_in","expireDate","d","Date","setTime","getTime","idToken","id_token","tokensParam","token","create","refresh","tokens","host","get","request","urlGenerator","user","accountId","scope","getScope","cookies","set","JSON","stringify","isLoginAccess","maxAge","httpOnly","secure","access_type","redirect","isConnected","hooks","query","error","status","expose","cookieName","cookie","expires","parse","findOrCreateFromStrategy","account","update","refreshAccountTokens","tokenExpireDate","now","Promise","resolve","provider","then","updateAccount","STATUSES","VALIDATED","DELETED","UserAccountsService","strategyToService","userId","_id","service","newScope","scopeKeyToScope","accounts","find","join","subservice","profile","getProfile","getId","subservices","includes","push","replaceOne","emails","getEmails","findOneByAccountOrEmails","providerKey","info","Object","assign","displayName","getDisplayName","fullName","getFullName","name","getAccountName","userEmails","forEach","email","emailDomains","reduce","domains","split","Set","insertOne","COOKIE_NAME","getTokenFromRequest","req","Cookies","verifyPromisified","jsonwebtoken","verify","createDecodeJWT","secretKey","jwtAudience","algorithms","audience","createFindConnectedAndUser","decodeJwt","err","findConnected","MongoUsersManager","findByKey","sanitize","sanitizeBaseUser","length","$or","$in","findOne","accountIndex","indexOf","partialUpdateOne","$set","created","updated","map","UserAccountGoogleService","fetch","response","json","id","givenName","given_name","familyName","family_name","getDefaultScope","undefined","oldScope","filter","item","i","ar","UserAccountSlackService","team","authSocketIO","app","io","findConnectedAndUser","users","Map","use","socket","next","handshakeData","headers","client","on","delete","getTokenFromReq","createAuthApolloContext","connection","signPromisified","sign","init","context","time","algorithm","getConnectedAndUser","routes","getConnectedAndUserFromRequest","middleware","userAgent","setState","sanitizedState"],"mappings":"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"}
|
package/dist/utils/cookies.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IncomingMessage } from 'http';
|
|
2
2
|
import type { Option } from 'cookies';
|
|
3
3
|
export declare const COOKIE_NAME = "connectedUser";
|
|
4
|
-
export declare const getTokenFromRequest: (req: IncomingMessage, options?: Pick<Option,
|
|
4
|
+
export declare const getTokenFromRequest: (req: IncomingMessage, options?: Pick<Option, Exclude<keyof Option, 'secure'>>) => string | undefined;
|
|
5
5
|
//# sourceMappingURL=cookies.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../src/utils/cookies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAGtC,eAAO,MAAM,WAAW,kBAAkB,CAAC;AAE3C,eAAO,MAAM,mBAAmB,QACzB,eAAe,
|
|
1
|
+
{"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../src/utils/cookies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAGtC,eAAO,MAAM,WAAW,kBAAkB,CAAC;AAE3C,eAAO,MAAM,mBAAmB,QACzB,eAAe,YACV,KAAK,MAAM,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,CAAC,CAAC,KACtD,MAAM,GAAG,SAQX,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "alp-node-auth",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.1.1",
|
|
4
4
|
"description": "authentication with alp",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"alp"
|
|
@@ -46,16 +46,12 @@
|
|
|
46
46
|
"build": "yarn clean:build && rollup --config rollup.config.mjs && yarn run build:definitions",
|
|
47
47
|
"build:definitions": "tsc -p tsconfig.build.json",
|
|
48
48
|
"clean": "yarn clean:build",
|
|
49
|
-
"clean:build": "
|
|
49
|
+
"clean:build": "pob-babel-clean-out dist",
|
|
50
50
|
"lint": "yarn run lint:eslint",
|
|
51
51
|
"lint:eslint": "cd ../.. && yarn run eslint --report-unused-disable-directives --resolve-plugins-relative-to . --quiet packages/alp-node-auth",
|
|
52
52
|
"watch": "yarn clean:build && rollup --config rollup.config.mjs --watch"
|
|
53
53
|
},
|
|
54
|
-
"prettier":
|
|
55
|
-
"trailingComma": "all",
|
|
56
|
-
"singleQuote": true,
|
|
57
|
-
"arrowParens": "always"
|
|
58
|
-
},
|
|
54
|
+
"prettier": "@pob/root/prettier-config",
|
|
59
55
|
"pob": {
|
|
60
56
|
"babelEnvs": [
|
|
61
57
|
{
|
|
@@ -81,7 +77,9 @@
|
|
|
81
77
|
"peerDependencies": {
|
|
82
78
|
"alp-node": "^4.0.2",
|
|
83
79
|
"alp-router": "^5.1.0",
|
|
84
|
-
"liwi-mongo": "^8.0.1"
|
|
80
|
+
"liwi-mongo": "^8.0.1 || ^9.0.0",
|
|
81
|
+
"react": "^18.1.0",
|
|
82
|
+
"router-segments": "^5.0.0"
|
|
85
83
|
},
|
|
86
84
|
"dependencies": {
|
|
87
85
|
"@types/jsonwebtoken": "^8.5.1",
|
|
@@ -93,12 +91,14 @@
|
|
|
93
91
|
"simple-oauth2": "^2.2.1"
|
|
94
92
|
},
|
|
95
93
|
"devDependencies": {
|
|
96
|
-
"@babel/core": "7.
|
|
97
|
-
"alp-node": "4.1
|
|
98
|
-
"alp-router": "5.1
|
|
99
|
-
"liwi-mongo": "
|
|
100
|
-
"pob-babel": "
|
|
101
|
-
"
|
|
94
|
+
"@babel/core": "7.19.3",
|
|
95
|
+
"alp-node": "4.2.1",
|
|
96
|
+
"alp-router": "5.2.1",
|
|
97
|
+
"liwi-mongo": "9.1.0",
|
|
98
|
+
"pob-babel": "34.2.0",
|
|
99
|
+
"react": "18.1.0",
|
|
100
|
+
"router-segments": "5.0.0",
|
|
101
|
+
"typescript": "4.8.4"
|
|
102
102
|
},
|
|
103
|
-
"gitHead": "
|
|
103
|
+
"gitHead": "37573847487da0689917f2667f5c810f0136eab7"
|
|
104
104
|
}
|
package/src/.eslintrc.json
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
"plugins": ["@typescript-eslint"],
|
|
8
8
|
"extends": [
|
|
9
9
|
"@pob/eslint-config-typescript",
|
|
10
|
-
"@pob/eslint-config-typescript/node"
|
|
10
|
+
"@pob/eslint-config-typescript/node",
|
|
11
|
+
"@pob/eslint-config-typescript-react"
|
|
11
12
|
],
|
|
12
13
|
"ignorePatterns": ["*.d.ts"],
|
|
13
14
|
"rules": {
|
|
@@ -18,7 +19,7 @@
|
|
|
18
19
|
},
|
|
19
20
|
"overrides": [
|
|
20
21
|
{
|
|
21
|
-
"files": ["**/*.test.ts", "__tests__/**/*.ts"],
|
|
22
|
+
"files": ["**/*.test.{ts,tsx}", "__tests__/**/*.{ts,tsx}"],
|
|
22
23
|
"extends": ["@pob/eslint-config-typescript/test"],
|
|
23
24
|
"env": {
|
|
24
25
|
"jest": true
|
package/rollup.config.mjs
DELETED