alp-node-auth 10.0.0 → 12.0.0

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