alp-node-auth 7.2.2 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +1 -1
  3. package/dist/definitions/MongoUsersManager.d.ts +4 -2
  4. package/dist/definitions/MongoUsersManager.d.ts.map +1 -1
  5. package/dist/definitions/authApolloContext.d.ts +2 -2
  6. package/dist/definitions/authApolloContext.d.ts.map +1 -1
  7. package/dist/definitions/authSocketIO.d.ts +2 -2
  8. package/dist/definitions/authSocketIO.d.ts.map +1 -1
  9. package/dist/definitions/createAuthController.d.ts +2 -2
  10. package/dist/definitions/createAuthController.d.ts.map +1 -1
  11. package/dist/definitions/index.d.ts +10 -9
  12. package/dist/definitions/index.d.ts.map +1 -1
  13. package/dist/definitions/services/authentification/AuthenticationService.d.ts +6 -12
  14. package/dist/definitions/services/authentification/AuthenticationService.d.ts.map +1 -1
  15. package/dist/definitions/services/authentification/types.d.ts +2 -2
  16. package/dist/definitions/services/authentification/types.d.ts.map +1 -1
  17. package/dist/definitions/services/user/UserAccountSlackService.d.ts.map +1 -1
  18. package/dist/definitions/services/user/UserAccountsService.d.ts +2 -2
  19. package/dist/definitions/services/user/UserAccountsService.d.ts.map +1 -1
  20. package/dist/definitions/services/user/types.d.ts +2 -2
  21. package/dist/definitions/services/user/types.d.ts.map +1 -1
  22. package/dist/definitions/types.d.ts +42 -0
  23. package/dist/definitions/types.d.ts.map +1 -0
  24. package/dist/definitions/utils/cookies.d.ts +3 -2
  25. package/dist/definitions/utils/cookies.d.ts.map +1 -1
  26. package/dist/definitions/utils/createFindLoggedInUser.d.ts +6 -0
  27. package/dist/definitions/utils/createFindLoggedInUser.d.ts.map +1 -0
  28. package/dist/{index-node16.mjs → index-node18.mjs} +125 -80
  29. package/dist/index-node18.mjs.map +1 -0
  30. package/package.json +67 -30
  31. package/src/MongoUsersManager.ts +8 -2
  32. package/src/authApolloContext.ts +10 -10
  33. package/src/authSocketIO.ts +9 -8
  34. package/src/createAuthController.ts +10 -9
  35. package/src/index.ts +74 -46
  36. package/src/services/authentification/AuthenticationService.ts +30 -33
  37. package/src/services/authentification/types.ts +2 -2
  38. package/src/services/user/UserAccountGoogleService.ts +1 -1
  39. package/src/services/user/UserAccountSlackService.ts +2 -8
  40. package/src/services/user/UserAccountsService.ts +10 -5
  41. package/src/services/user/types.ts +2 -2
  42. package/{types.d.ts → src/types.ts} +2 -3
  43. package/src/utils/cookies.ts +8 -3
  44. package/src/utils/{createFindConnectedAndUser.ts → createFindLoggedInUser.ts} +19 -20
  45. package/src/utils/generators.ts +2 -2
  46. package/strategies/dropbox.js +22 -12
  47. package/strategies/facebook.js +22 -12
  48. package/strategies/foursquare.js +22 -12
  49. package/strategies/github.js +22 -12
  50. package/strategies/google.js +23 -12
  51. package/strategies/slack.js +22 -12
  52. package/strategies/strategies.d.ts +9 -4
  53. package/dist/definitions/utils/createFindConnectedAndUser.d.ts +0 -6
  54. package/dist/definitions/utils/createFindConnectedAndUser.d.ts.map +0 -1
  55. package/dist/index-node16.mjs.map +0 -1
@@ -1,11 +1,10 @@
1
- import { promisify } from 'util';
1
+ import { promisify } from 'node:util';
2
2
  import jsonwebtoken from 'jsonwebtoken';
3
3
  import { Logger } from 'nightingale-logger';
4
4
  import 'alp-router';
5
- import { EventEmitter } from 'events';
6
- import { randomBytes } from 'crypto';
5
+ import { EventEmitter } from 'node:events';
6
+ import { randomBytes } from 'node:crypto';
7
7
  import Cookies from 'cookies';
8
- import { fetch } from 'alp-node';
9
8
 
10
9
  function createAuthController({
11
10
  usersManager,
@@ -26,7 +25,7 @@ function createAuthController({
26
25
  * The user must already be connected
27
26
  */
28
27
  async addScope(ctx) {
29
- if (!ctx.state.connected) {
28
+ if (!ctx.state.loggedInUser) {
30
29
  await ctx.redirectTo(homeRouterKey);
31
30
  return;
32
31
  }
@@ -41,12 +40,12 @@ function createAuthController({
41
40
  async response(ctx) {
42
41
  const strategy = ctx.namedParam('strategy');
43
42
  ctx.assert(strategy);
44
- const connectedUser = await authenticationService.accessResponse(ctx, strategy, ctx.state.connected, {
43
+ const loggedInUser = await authenticationService.accessResponse(ctx, strategy, !!ctx.state.loggedInUser, {
45
44
  afterLoginSuccess: authHooks.afterLoginSuccess,
46
45
  afterScopeUpdate: authHooks.afterScopeUpdate
47
46
  });
48
47
  const keyPath = usersManager.store.keyPath;
49
- await ctx.setConnected(connectedUser[keyPath], connectedUser);
48
+ await ctx.setLoggedIn(loggedInUser[keyPath], loggedInUser);
50
49
  await ctx.redirectTo(homeRouterKey);
51
50
  },
52
51
  async logout(ctx) {
@@ -72,6 +71,9 @@ async function randomHex(size) {
72
71
  }
73
72
 
74
73
  /* eslint-disable @typescript-eslint/no-unsafe-argument */
74
+ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
75
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
76
+ /* eslint-disable camelcase, max-lines */
75
77
  const logger$4 = new Logger('alp:auth:authentication');
76
78
  class AuthenticationService extends EventEmitter {
77
79
  constructor(config, strategies, userAccountsService) {
@@ -107,17 +109,19 @@ class AuthenticationService extends EventEmitter {
107
109
  redirect_uri: options.redirectUri
108
110
  });
109
111
  if (!result) return result;
112
+ const tokens = result.token;
110
113
  return {
111
- accessToken: result.access_token,
112
- refreshToken: result.refresh_token,
113
- tokenType: result.token_type,
114
- expiresIn: result.expires_in,
114
+ accessToken: tokens.access_token,
115
+ refreshToken: tokens.refresh_token,
116
+ tokenType: tokens.token_type,
117
+ expiresIn: tokens.expires_in,
115
118
  expireDate: (() => {
119
+ if (tokens.expires_in == null) return null;
116
120
  const d = new Date();
117
- d.setTime(d.getTime() + result.expires_in * 1000);
121
+ d.setTime(d.getTime() + tokens.expires_in * 1000);
118
122
  return d;
119
123
  })(),
120
- idToken: result.id_token
124
+ idToken: tokens.id_token
121
125
  };
122
126
  // return strategyInstance.accessToken.create(result);
123
127
  }
@@ -137,7 +141,7 @@ class AuthenticationService extends EventEmitter {
137
141
  switch (strategyInstance.type) {
138
142
  case 'oauth2':
139
143
  {
140
- const token = strategyInstance.oauth2.accessToken.create({
144
+ const token = strategyInstance.oauth2.clientCredentials.createToken({
141
145
  refresh_token: tokensParam.refreshToken
142
146
  });
143
147
  const result = await token.refresh();
@@ -147,6 +151,7 @@ class AuthenticationService extends EventEmitter {
147
151
  tokenType: tokens.token_type,
148
152
  expiresIn: tokens.expires_in,
149
153
  expireDate: (() => {
154
+ if (tokens.expires_in == null) return null;
150
155
  const d = new Date();
151
156
  d.setTime(d.getTime() + tokens.expires_in * 1000);
152
157
  return d;
@@ -198,7 +203,7 @@ class AuthenticationService extends EventEmitter {
198
203
  });
199
204
  return ctx.redirect(redirectUri);
200
205
  }
201
- async accessResponse(ctx, strategy, isConnected, hooks) {
206
+ async accessResponse(ctx, strategy, isLoggedIn, hooks) {
202
207
  if (ctx.query.error) {
203
208
  const error = new Error(ctx.query.error);
204
209
  error.status = 403;
@@ -216,11 +221,11 @@ class AuthenticationService extends EventEmitter {
216
221
  throw new Error('No cookie for this state');
217
222
  }
218
223
  cookie = JSON.parse(cookie);
219
- if (!cookie || !cookie.scope) {
224
+ if (!cookie?.scope) {
220
225
  throw new Error('Unexpected cookie value');
221
226
  }
222
227
  if (!cookie.isLoginAccess) {
223
- if (!isConnected) {
228
+ if (!isLoggedIn) {
224
229
  throw new Error('You are not connected');
225
230
  }
226
231
  }
@@ -235,15 +240,15 @@ class AuthenticationService extends EventEmitter {
235
240
  }
236
241
  return user;
237
242
  }
238
- const connectedUser = ctx.state.user;
243
+ const loggedInUser = ctx.state.loggedInUser;
239
244
  const {
240
245
  account,
241
246
  user
242
- } = await this.userAccountsService.update(connectedUser, strategy, tokens, cookie.scope, cookie.scopeKey);
247
+ } = await this.userAccountsService.update(loggedInUser, strategy, tokens, cookie.scope, cookie.scopeKey);
243
248
  if (hooks.afterScopeUpdate) {
244
249
  await hooks.afterScopeUpdate(strategy, cookie.scopeKey, account, user);
245
250
  }
246
- return connectedUser;
251
+ return loggedInUser;
247
252
  }
248
253
  refreshAccountTokens(user, account) {
249
254
  if (account.tokenExpireDate && account.tokenExpireDate.getTime() > Date.now()) {
@@ -310,7 +315,7 @@ class UserAccountsService extends EventEmitter {
310
315
  if (tokens.refreshToken) {
311
316
  account.refreshToken = tokens.refreshToken;
312
317
  }
313
- if (tokens.expireDate) {
318
+ if (tokens.expireDate !== undefined) {
314
319
  account.tokenExpireDate = tokens.expireDate;
315
320
  }
316
321
  account.scope = service.getScope(account.scope, scope);
@@ -337,9 +342,11 @@ class UserAccountsService extends EventEmitter {
337
342
  emails
338
343
  });
339
344
  logger$3.info(!user ? 'create user' : 'existing user', {
340
- emails,
341
- user
345
+ userId: user?._id,
346
+ accountId
347
+ /*emails , user*/
342
348
  });
349
+
343
350
  if (!user) {
344
351
  user = {};
345
352
  }
@@ -365,7 +372,7 @@ class UserAccountsService extends EventEmitter {
365
372
  if (tokens.refreshToken) {
366
373
  account.refreshToken = tokens.refreshToken;
367
374
  }
368
- if (tokens.expireDate) {
375
+ if (tokens.expireDate !== undefined) {
369
376
  account.tokenExpireDate = tokens.expireDate;
370
377
  }
371
378
  account.scope = service.getScope(account.scope, scope);
@@ -397,14 +404,19 @@ class UserAccountsService extends EventEmitter {
397
404
  }
398
405
  }
399
406
 
400
- const COOKIE_NAME = 'connectedUser';
407
+ const COOKIE_NAME_TOKEN = 'loggedInUserToken';
408
+ const COOKIE_NAME_STATE = 'loggedInUserState';
401
409
  const getTokenFromRequest = (req, options) => {
410
+ if (req.headers.authorization?.startsWith('Bearer ')) {
411
+ return req.headers.authorization.slice(7);
412
+ }
413
+
402
414
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
403
415
  const cookies = new Cookies(req, null, {
404
416
  ...options,
405
417
  secure: true
406
418
  });
407
- return cookies.get(COOKIE_NAME);
419
+ return cookies.get(COOKIE_NAME_TOKEN);
408
420
  };
409
421
 
410
422
  const verifyPromisified = promisify(jsonwebtoken.verify);
@@ -413,23 +425,24 @@ const createDecodeJWT = secretKey => async (token, jwtAudience) => {
413
425
  algorithms: ['HS512'],
414
426
  audience: jwtAudience
415
427
  });
416
- return result?.connected;
428
+ return result?.loggedInUserId;
417
429
  };
418
- const createFindConnectedAndUser = (secretKey, usersManager, logger) => {
430
+ const createFindLoggedInUser = (secretKey, usersManager, logger) => {
419
431
  const decodeJwt = createDecodeJWT(secretKey);
420
432
  return async (jwtAudience, token) => {
421
433
  if (!token || !jwtAudience) return [null, null];
422
- let connected;
434
+ let loggedInUserId;
423
435
  try {
424
- connected = await decodeJwt(token, jwtAudience);
425
- } catch (err) {
436
+ loggedInUserId = await decodeJwt(token, jwtAudience);
437
+ } catch (error) {
426
438
  logger.debug('failed to verify authentification', {
427
- err
439
+ err: error
428
440
  });
429
441
  }
430
- if (connected == null) return [null, null];
431
- const user = await usersManager.findConnected(connected);
432
- return [connected, user];
442
+ if (loggedInUserId == null) return [null, null];
443
+ const loggedInUser = await usersManager.findById(loggedInUserId);
444
+ if (!loggedInUser) return [null, null];
445
+ return [loggedInUserId, loggedInUser];
433
446
  };
434
447
  };
435
448
 
@@ -437,9 +450,14 @@ class MongoUsersManager {
437
450
  constructor(store) {
438
451
  this.store = store;
439
452
  }
453
+
454
+ /** @deprecated use findById instead */
440
455
  findConnected(connected) {
441
456
  return this.store.findByKey(connected);
442
457
  }
458
+ findById(userId) {
459
+ return this.store.findByKey(userId);
460
+ }
443
461
  insertOne(user) {
444
462
  return this.store.insertOne(user);
445
463
  }
@@ -482,6 +500,8 @@ class MongoUsersManager {
482
500
  }
483
501
  });
484
502
  }
503
+
504
+ // eslint-disable-next-line @typescript-eslint/class-methods-use-this
485
505
  sanitizeBaseUser(user) {
486
506
  return {
487
507
  _id: user._id,
@@ -503,7 +523,10 @@ class MongoUsersManager {
503
523
  }
504
524
  }
505
525
 
526
+ /* eslint-disable @typescript-eslint/class-methods-use-this */
506
527
  /* eslint-disable @typescript-eslint/no-unsafe-argument */
528
+ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
529
+
507
530
  class UserAccountGoogleService {
508
531
  constructor(scopeKeyToScope) {
509
532
  this.scopeKeyToScope = {
@@ -545,7 +568,9 @@ class UserAccountGoogleService {
545
568
  }
546
569
  }
547
570
 
571
+ /* eslint-disable @typescript-eslint/class-methods-use-this */
548
572
  /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
573
+
549
574
  // https://api.slack.com/methods/users.identity
550
575
 
551
576
  class UserAccountSlackService {
@@ -560,7 +585,7 @@ class UserAccountSlackService {
560
585
  return fetch(`https://slack.com/api/users.identity?token=${tokens.accessToken}`).then(response => response.json());
561
586
  }
562
587
  getId(profile) {
563
- if (!profile || !profile.team || !profile.team.id || !profile.user || !profile.user.id) {
588
+ if (!profile?.team?.id || !profile.user?.id) {
564
589
  return null;
565
590
  }
566
591
  return `team:${profile.team.id};user:${profile.user.id}`;
@@ -586,8 +611,8 @@ class UserAccountSlackService {
586
611
  }
587
612
 
588
613
  const logger$2 = new Logger('alp:auth');
589
- const authSocketIO = (app, usersManager, io) => {
590
- const findConnectedAndUser = createFindConnectedAndUser(app.config.get('authentication').get('secretKey'), usersManager, logger$2);
614
+ const authSocketIO = (app, usersManager, io, jwtAudience) => {
615
+ const findLoggedInUser = createFindLoggedInUser(app.config.get('authentication').get('secretKey'), usersManager, logger$2);
591
616
  const users = new Map();
592
617
  io.users = users;
593
618
  io.use(async (socket, next) => {
@@ -595,12 +620,12 @@ const authSocketIO = (app, usersManager, io) => {
595
620
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
596
621
  const token = getTokenFromRequest(handshakeData);
597
622
  if (!token) return next();
598
- const [connected, user] = await findConnectedAndUser(
623
+ const [loggedInUserId, loggedInUser] = await findLoggedInUser(
599
624
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
600
- handshakeData.headers['user-agent'], token);
601
- if (!connected || !user) return next();
602
- socket.user = user;
603
- users.set(socket.client.id, user);
625
+ jwtAudience || handshakeData.headers['user-agent'], token);
626
+ if (!loggedInUserId || !loggedInUser) return next();
627
+ socket.user = loggedInUser;
628
+ users.set(socket.client.id, loggedInUser);
604
629
  socket.on('disconnected', () => users.delete(socket.client.id));
605
630
  await next();
606
631
  });
@@ -608,7 +633,7 @@ const authSocketIO = (app, usersManager, io) => {
608
633
 
609
634
  const logger$1 = new Logger('alp:auth');
610
635
  const getTokenFromReq = req => {
611
- if (req.cookies) return req.cookies[COOKIE_NAME];
636
+ if (req.cookies) return req.cookies[COOKIE_NAME_TOKEN];
612
637
  return getTokenFromRequest(req);
613
638
  };
614
639
 
@@ -617,14 +642,14 @@ const getTokenFromReq = req => {
617
642
  * @internal
618
643
  */
619
644
  const createAuthApolloContext = (config, usersManager) => {
620
- const findConnectedAndUser = createFindConnectedAndUser(config.get('authentication').get('secretKey'), usersManager, logger$1);
645
+ const findLoggedInUser = createFindLoggedInUser(config.get('authentication').get('secretKey'), usersManager, logger$1);
621
646
  return async ({
622
647
  req,
623
648
  connection
624
649
  }) => {
625
- if (connection?.user) {
650
+ if (connection?.loggedInUser) {
626
651
  return {
627
- user: connection.user
652
+ user: connection.loggedInUser
628
653
  };
629
654
  }
630
655
  if (!req) return null;
@@ -634,15 +659,17 @@ const createAuthApolloContext = (config, usersManager) => {
634
659
  if (!token) return {
635
660
  user: undefined
636
661
  };
637
- const [, user] = await findConnectedAndUser(
662
+ const [, loggedInUser] = await findLoggedInUser(
638
663
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
639
664
  req.headers['user-agent'], token);
640
665
  return {
641
- user
666
+ user: loggedInUser
642
667
  };
643
668
  };
644
669
  };
645
670
 
671
+ /* eslint-disable max-lines */
672
+
646
673
  const logger = new Logger('alp:auth');
647
674
  const signPromisified = promisify(jsonwebtoken.sign);
648
675
  function init({
@@ -665,69 +692,87 @@ function init({
665
692
  defaultStrategy,
666
693
  authHooks
667
694
  });
668
- app.context.setConnected = async function (connected, user) {
669
- logger.debug('setConnected', {
670
- connected
695
+ app.context.setLoggedIn = async function (loggedInUserId, loggedInUser) {
696
+ logger.debug('setLoggedIn', {
697
+ loggedInUser
671
698
  });
672
- if (!connected) {
673
- throw new Error('Illegal value for setConnected');
699
+ if (!loggedInUserId) {
700
+ throw new Error('Illegal value for setLoggedIn');
674
701
  }
675
- this.state.connected = connected;
676
- this.state.user = user;
702
+ this.state.loggedInUserId = loggedInUserId;
703
+ this.state.loggedInUser = loggedInUser;
677
704
  const token = await signPromisified({
678
- connected,
705
+ loggedInUserId,
679
706
  time: Date.now()
680
707
  }, this.config.get('authentication').get('secretKey'), {
681
708
  algorithm: 'HS512',
682
709
  audience: jwtAudience || this.request.headers['user-agent'],
683
710
  expiresIn: '30 days'
684
711
  });
685
-
686
712
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
687
- this.cookies.set(COOKIE_NAME, token, {
713
+ this.cookies.set(COOKIE_NAME_TOKEN, token, {
688
714
  httpOnly: true,
689
715
  secure: this.config.get('allowHttps')
690
716
  });
717
+ this.cookies.set(COOKIE_NAME_STATE, JSON.stringify({
718
+ loggedInUserId,
719
+ expiresIn: (() => {
720
+ const date = new Date();
721
+ date.setDate(date.getDate() + 30);
722
+ return date.getTime();
723
+ })()
724
+ }), {
725
+ httpOnly: false,
726
+ secure: this.config.get('allowHttps')
727
+ });
691
728
  };
692
729
  app.context.logout = function () {
693
- delete this.state.connected;
694
- delete this.state.user;
695
- this.cookies.set(COOKIE_NAME, '', {
730
+ delete this.state.loggedInUserId;
731
+ delete this.state.loggedInUser;
732
+ this.cookies.set(COOKIE_NAME_TOKEN, '', {
733
+ expires: new Date(1)
734
+ });
735
+ this.cookies.set(COOKIE_NAME_STATE, '', {
696
736
  expires: new Date(1)
697
737
  });
698
738
  };
699
- const getConnectedAndUser = createFindConnectedAndUser(app.config.get('authentication').get('secretKey'), usersManager, logger);
739
+ const findLoggedInUser = createFindLoggedInUser(app.config.get('authentication').get('secretKey'), usersManager, logger);
700
740
  return {
701
741
  routes: createRoutes(controller),
702
- getConnectedAndUserFromRequest: req => {
742
+ findLoggedInUserFromRequest: req => {
703
743
  const token = getTokenFromRequest(req);
704
- return getConnectedAndUser(jwtAudience || req.headers['user-agent'], token);
744
+ return findLoggedInUser(jwtAudience || req.headers['user-agent'], token);
705
745
  },
706
- getConnectedAndUser,
746
+ findLoggedInUser,
707
747
  middleware: async (ctx, next) => {
708
- const token = ctx.cookies.get(COOKIE_NAME);
748
+ const token = ctx.cookies.get(COOKIE_NAME_TOKEN);
709
749
  const userAgent = ctx.request.headers['user-agent'];
710
750
  logger.debug('middleware', {
711
751
  token
712
752
  });
713
- const setState = (connected, user) => {
714
- ctx.state.connected = connected;
715
- ctx.state.user = user;
716
- ctx.sanitizedState.connected = connected;
717
- ctx.sanitizedState.user = user && usersManager.sanitize(user);
753
+ const setState = (loggedInUserId, loggedInUser) => {
754
+ ctx.state.loggedInUserId = loggedInUserId;
755
+ ctx.state.user = loggedInUser;
756
+ ctx.sanitizedState.loggedInUserId = loggedInUserId;
757
+ ctx.sanitizedState.loggedInUser = loggedInUser && usersManager.sanitize(loggedInUser);
718
758
  };
719
- const [connected, user] = await getConnectedAndUser(jwtAudience || userAgent, token);
759
+ const [loggedInUserId, loggedInUser] = await findLoggedInUser(jwtAudience || userAgent, token);
720
760
  logger.debug('middleware', {
721
- connected
761
+ loggedInUserId
722
762
  });
723
- if (connected == null || user == null) {
724
- if (token) ctx.cookies.set(COOKIE_NAME, '', {
725
- expires: new Date(1)
726
- });
763
+ if (loggedInUserId == null || loggedInUser == null) {
764
+ if (token) {
765
+ ctx.cookies.set(COOKIE_NAME_TOKEN, '', {
766
+ expires: new Date(1)
767
+ });
768
+ ctx.cookies.set(COOKIE_NAME_STATE, '', {
769
+ expires: new Date(1)
770
+ });
771
+ }
727
772
  setState(null, null);
728
773
  return next();
729
774
  }
730
- setState(connected, user);
775
+ setState(loggedInUserId, loggedInUser);
731
776
  return next();
732
777
  }
733
778
  };
@@ -735,4 +780,4 @@ function init({
735
780
  }
736
781
 
737
782
  export { AuthenticationService, MongoUsersManager, STATUSES, UserAccountGoogleService, UserAccountSlackService, authSocketIO, createAuthApolloContext, init as default };
738
- //# sourceMappingURL=index-node16.mjs.map
783
+ //# sourceMappingURL=index-node18.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-node18.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/createFindLoggedInUser.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 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';\nimport type { User, UserSanitized } from './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 response: (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 ) =>\n | OptionalRecord<AllowedMapParamsStrategy[StrategyKey], any>\n | Promise<OptionalRecord<AllowedMapParamsStrategy[StrategyKey], any>>\n | Promise<void>\n // eslint-disable-next-line @typescript-eslint/no-invalid-void-type\n | void;\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 /**\n * Add scope in existing\n * The user must already be connected\n */\n async addScope(ctx: Context): Promise<void> {\n if (!ctx.state.loggedInUser) {\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 response(ctx: Context): Promise<void> {\n const strategy: StrategyKeys = ctx.namedParam('strategy') as StrategyKeys;\n ctx.assert(strategy);\n\n const loggedInUser = await authenticationService.accessResponse(\n ctx,\n strategy,\n !!ctx.state.loggedInUser,\n {\n afterLoginSuccess: authHooks.afterLoginSuccess,\n afterScopeUpdate: authHooks.afterScopeUpdate,\n },\n );\n const keyPath = usersManager.store.keyPath;\n await ctx.setLoggedIn(loggedInUser[keyPath], loggedInUser);\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.response, 'authResponse');\n segment.defaultRoute(controller.login, 'login');\n },\n ],\n addScope: ['/add-scope/:strategy/:scopeKey', controller.addScope],\n logout: ['/logout', controller.logout],\n});\n","import { randomBytes } from 'node:crypto';\nimport { promisify } from 'node: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 'node:events';\nimport 'alp-router';\nimport type { Context, NodeConfig } from 'alp-types';\nimport { Logger } from 'nightingale-logger';\nimport type { Strategy as Oauth2Strategy } from '../../../strategies/strategies.d';\nimport type { AccountId, User, Account, UserSanitized } from '../../types';\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 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 loggedInUser: U,\n ) => Promise<void> | void;\n\n afterScopeUpdate?: <StrategyKey extends StrategyKeys>(\n strategy: StrategyKey,\n scopeKey: string,\n account: Account,\n user: U,\n ) => Promise<void> | void;\n}\n\nexport class AuthenticationService<\n StrategyKeys extends AllowedStrategyKeys,\n U extends User = User,\n USanitized extends UserSanitized = UserSanitized,\n // eslint-disable-next-line unicorn/prefer-event-target\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 const tokens = result.token;\n\n return {\n accessToken: tokens.access_token as string,\n refreshToken: tokens.refresh_token as string,\n tokenType: tokens.token_type as string,\n expiresIn: tokens.expires_in as number,\n expireDate: (() => {\n if (tokens.expires_in == null) return null;\n const d = new Date();\n d.setTime(d.getTime() + (tokens.expires_in as number) * 1000);\n return d;\n })(),\n idToken: tokens.id_token as string,\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.clientCredentials.createToken({\n refresh_token: tokensParam.refreshToken,\n });\n const result = await token.refresh();\n const tokens = result.token;\n return {\n accessToken: tokens.access_token as string,\n tokenType: tokens.token_type as string,\n expiresIn: tokens.expires_in as number,\n expireDate: (() => {\n if (tokens.expires_in == null) return null;\n const d = new Date();\n d.setTime(d.getTime() + (tokens.expires_in as number) * 1000);\n return d;\n })(),\n idToken: tokens.id_token as string,\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('authResponse', {\n strategy,\n })}`;\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: Context,\n strategy: StrategyKey,\n isLoggedIn: 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?.scope) {\n throw new Error('Unexpected cookie value');\n }\n\n if (!cookie.isLoginAccess) {\n if (!isLoggedIn) {\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 loggedInUser = ctx.state.loggedInUser as U;\n const { account, user } = await this.userAccountsService.update(\n loggedInUser,\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 loggedInUser;\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 'node:events';\nimport { Logger } from 'nightingale-logger';\nimport type MongoUsersManager from '../../MongoUsersManager';\nimport type { AccountId, User, Account, UserSanitized } from '../../types';\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 // eslint-disable-next-line unicorn/prefer-event-target\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 !== undefined) {\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', {\n userId: user?._id,\n accountId,\n /*emails , user*/\n });\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 !== undefined) {\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 'node:http';\nimport type { Option } from 'cookies';\nimport Cookies from 'cookies';\n\nexport const COOKIE_NAME_TOKEN = 'loggedInUserToken';\nexport const COOKIE_NAME_STATE = 'loggedInUserState';\n\nexport const getTokenFromRequest = (\n req: IncomingMessage,\n options?: Pick<Option, Exclude<keyof Option, 'secure'>>,\n): string | undefined => {\n if (req.headers.authorization?.startsWith('Bearer ')) {\n return req.headers.authorization.slice('Bearer '.length);\n }\n\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_TOKEN);\n};\n","import { promisify } from 'node: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 MongoUsersManager from '../MongoUsersManager';\nimport type { User, UserSanitized } from '../types';\n\ntype Verify = (\n token: string,\n secretOrPublicKey: GetPublicKeyOrSecret | Secret,\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)?.loggedInUserId as string | undefined;\n };\n\nexport type FindLoggedInUser<U extends User> = (\n jwtAudience?: string,\n token?: string,\n) => Promise<[U['_id'] | null | undefined, U | null | undefined]>;\n\nexport const createFindLoggedInUser = <\n U extends User,\n USanitized extends UserSanitized,\n>(\n secretKey: string,\n usersManager: MongoUsersManager<U, USanitized>,\n logger: Logger,\n): FindLoggedInUser<U> => {\n const decodeJwt = createDecodeJWT(secretKey);\n\n const findLoggedInUser: FindLoggedInUser<U> = async (jwtAudience, token) => {\n if (!token || !jwtAudience) return [null, null];\n\n let loggedInUserId;\n try {\n loggedInUserId = await decodeJwt(token, jwtAudience);\n } catch (error: unknown) {\n logger.debug('failed to verify authentification', { err: error });\n }\n\n if (loggedInUserId == null) return [null, null];\n\n const loggedInUser = await usersManager.findById(loggedInUserId);\n\n if (!loggedInUser) return [null, null];\n\n return [loggedInUserId, loggedInUser];\n };\n\n return findLoggedInUser;\n};\n","import type { MongoInsertType, MongoStore, Update } from 'liwi-mongo';\nimport type { User, Account, UserSanitized } from './types';\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 /** @deprecated use findById instead */\n findConnected(connected: string): Promise<U | undefined> {\n return this.store.findByKey(connected);\n }\n\n findById(userId: string): Promise<U | undefined> {\n return this.store.findByKey(userId);\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: number | string;\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 // eslint-disable-next-line @typescript-eslint/class-methods-use-this\n 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/class-methods-use-this */\n/* eslint-disable @typescript-eslint/no-unsafe-argument */\n/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\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/class-methods-use-this */\n/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\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 (!profile?.team?.id || !profile.user?.id) {\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 { Logger } from 'nightingale-logger';\nimport type MongoUsersManager from './MongoUsersManager';\nimport type { User } from './types';\nimport { getTokenFromRequest } from './utils/cookies';\nimport { createFindLoggedInUser } from './utils/createFindLoggedInUser';\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 jwtAudience?: string,\n): void => {\n const findLoggedInUser = createFindLoggedInUser(\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 [loggedInUserId, loggedInUser] = await findLoggedInUser(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n jwtAudience || handshakeData.headers['user-agent'],\n token,\n );\n\n if (!loggedInUserId || !loggedInUser) return next();\n\n socket.user = loggedInUser;\n users.set(socket.client.id, loggedInUser);\n\n socket.on('disconnected', () => users.delete(socket.client.id));\n\n await next();\n });\n};\n","import type { IncomingMessage } from 'node:http';\nimport type { NodeConfig } from 'alp-types';\nimport { Logger } from 'nightingale-logger';\nimport type MongoUsersManager from './MongoUsersManager';\nimport type { User } from './types';\nimport { getTokenFromRequest, COOKIE_NAME_TOKEN } from './utils/cookies';\nimport { createFindLoggedInUser } from './utils/createFindLoggedInUser';\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_TOKEN];\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 findLoggedInUser = createFindLoggedInUser(\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?.loggedInUser) {\n return { user: connection.loggedInUser };\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 [, loggedInUser] = await findLoggedInUser(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n req.headers['user-agent'],\n token,\n );\n\n return { user: loggedInUser };\n };\n};\n","/* eslint-disable max-lines */\nimport type { IncomingMessage } from 'node:http';\nimport { promisify } from 'node: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 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 type { User, UserSanitized } from './types';\nimport {\n getTokenFromRequest,\n COOKIE_NAME_TOKEN,\n COOKIE_NAME_STATE,\n} from './utils/cookies';\nimport { createFindLoggedInUser } from './utils/createFindLoggedInUser';\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\nexport * from './types';\n\ndeclare module 'alp-types' {\n // eslint-disable-next-line @typescript-eslint/no-shadow\n interface ContextState {\n loggedInUserId:\n | NonNullable<ContextState['loggedInUser']>['_id']\n | null\n | undefined;\n loggedInUser: User | null | undefined;\n }\n\n interface ContextSanitizedState {\n loggedInUserId:\n | NonNullable<ContextSanitizedState['loggedInUser']>['_id']\n | null\n | undefined;\n loggedInUser: UserSanitized | null | undefined;\n }\n\n interface BaseContext {\n setLoggedIn: (\n loggedInUserId: NonNullable<ContextState['loggedInUserId']>,\n loggedInUser: NonNullable<ContextState['loggedInUser']>,\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.setLoggedIn = async function (\n this: Context,\n loggedInUserId: NonNullable<ContextState['loggedInUser']>['_id'],\n loggedInUser: NonNullable<ContextState['loggedInUser']>,\n ): Promise<void> {\n logger.debug('setLoggedIn', { loggedInUser });\n if (!loggedInUserId) {\n throw new Error('Illegal value for setLoggedIn');\n }\n\n this.state.loggedInUserId = loggedInUserId;\n this.state.loggedInUser = loggedInUser;\n\n const token = await signPromisified(\n { loggedInUserId, 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 const calcExpiresTime = (): number => {\n const date = new Date();\n date.setDate(date.getDate() + 30);\n return date.getTime();\n };\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n this.cookies.set(COOKIE_NAME_TOKEN, token, {\n httpOnly: true,\n secure: this.config.get('allowHttps'),\n });\n\n this.cookies.set(\n COOKIE_NAME_STATE,\n JSON.stringify({ loggedInUserId, expiresIn: calcExpiresTime() }),\n {\n httpOnly: false,\n secure: this.config.get('allowHttps'),\n },\n );\n };\n\n app.context.logout = function (this: Context): void {\n delete this.state.loggedInUserId;\n delete this.state.loggedInUser;\n this.cookies.set(COOKIE_NAME_TOKEN, '', { expires: new Date(1) });\n this.cookies.set(COOKIE_NAME_STATE, '', { expires: new Date(1) });\n };\n\n const findLoggedInUser = createFindLoggedInUser(\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 findLoggedInUserFromRequest: (\n req: IncomingMessage,\n ): ReturnType<typeof findLoggedInUser> => {\n const token = getTokenFromRequest(req);\n return findLoggedInUser(\n jwtAudience || req.headers['user-agent'],\n token,\n );\n },\n findLoggedInUser,\n middleware: async <T>(\n ctx: Context,\n next: () => Promise<T> | T,\n ): Promise<T> => {\n const token = ctx.cookies.get(COOKIE_NAME_TOKEN);\n const userAgent = ctx.request.headers['user-agent'];\n logger.debug('middleware', { token });\n\n const setState = (\n loggedInUserId: U['_id'] | null | undefined,\n loggedInUser: U | null | undefined,\n ): void => {\n ctx.state.loggedInUserId = loggedInUserId;\n ctx.state.user = loggedInUser;\n ctx.sanitizedState.loggedInUserId = loggedInUserId;\n ctx.sanitizedState.loggedInUser =\n loggedInUser && usersManager.sanitize(loggedInUser);\n };\n\n const [loggedInUserId, loggedInUser] = await findLoggedInUser(\n jwtAudience || userAgent,\n token,\n );\n logger.debug('middleware', { loggedInUserId });\n\n if (loggedInUserId == null || loggedInUser == null) {\n if (token) {\n ctx.cookies.set(COOKIE_NAME_TOKEN, '', { expires: new Date(1) });\n ctx.cookies.set(COOKIE_NAME_STATE, '', { expires: new Date(1) });\n }\n setState(null, null);\n return next();\n }\n\n setState(loggedInUserId, loggedInUser);\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","loggedInUser","redirectTo","scopeKey","response","assert","accessResponse","afterLoginSuccess","afterScopeUpdate","keyPath","store","setLoggedIn","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","tokens","token","accessToken","access_token","refreshToken","refresh_token","tokenType","token_type","expiresIn","expires_in","expireDate","d","Date","setTime","getTime","idToken","id_token","tokensParam","clientCredentials","createToken","refresh","host","get","request","urlGenerator","user","accountId","scope","getScope","cookies","set","JSON","stringify","isLoginAccess","maxAge","httpOnly","secure","access_type","redirect","isLoggedIn","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","undefined","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_TOKEN","COOKIE_NAME_STATE","getTokenFromRequest","req","headers","authorization","startsWith","slice","Cookies","verifyPromisified","jsonwebtoken","verify","createDecodeJWT","secretKey","jwtAudience","algorithms","audience","loggedInUserId","createFindLoggedInUser","decodeJwt","err","findById","MongoUsersManager","findConnected","connected","findByKey","sanitize","sanitizeBaseUser","length","$or","$in","findOne","accountIndex","indexOf","partialUpdateOne","$set","created","updated","map","UserAccountGoogleService","fetch","json","id","givenName","given_name","familyName","family_name","getDefaultScope","oldScope","filter","item","i","ar","UserAccountSlackService","team","authSocketIO","app","io","findLoggedInUser","users","Map","use","socket","next","handshakeData","client","on","delete","getTokenFromReq","createAuthApolloContext","connection","signPromisified","sign","init","context","time","algorithm","date","setDate","getDate","routes","findLoggedInUserFromRequest","middleware","userAgent","setState","sanitizedState"],"mappings":"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"}