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