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 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
@@ -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, "keys"> | undefined) => void;
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,iDAEN,IAgCF,CAAC"}
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"}
@@ -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
- }; // return strategyInstance.accessToken.create(result);
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
- }; // @ts-expect-error well...
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 = [// eslint-disable-next-line unicorn/no-array-reduce
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, { ...options,
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
- } // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
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 = { ...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 = { ...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; // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
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( // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
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
- if (!req) return null; // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
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( // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
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
- }); // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
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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"}
@@ -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, "keys"> | undefined) => string | undefined;
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,iDAEnB,MAAM,GAAG,SAQX,CAAC"}
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.0.8",
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": "rm -Rf dist",
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.17.5",
97
- "alp-node": "4.1.4",
98
- "alp-router": "5.1.6",
99
- "liwi-mongo": "8.3.1",
100
- "pob-babel": "32.2.0",
101
- "typescript": "4.6.2"
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": "81644a1b75145fc792fadce0c04096aea046994b"
103
+ "gitHead": "37573847487da0689917f2667f5c810f0136eab7"
104
104
  }
@@ -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
@@ -1,5 +0,0 @@
1
- import createRollupConfig from 'pob-babel/createRollupConfig.js';
2
-
3
- export default createRollupConfig({
4
- cwd: new URL('.', import.meta.url).pathname,
5
- });
@@ -1,7 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
-
4
- "compilerOptions": {
5
- "noEmit": true
6
- }
7
- }