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
package/src/index.ts CHANGED
@@ -1,44 +1,42 @@
1
- /* eslint-disable max-lines */
2
- import type { IncomingMessage } from 'node:http';
3
- import { promisify } from 'node:util';
4
- import type { Context, ContextState, NodeApplication } from 'alp-node';
5
- import jsonwebtoken from 'jsonwebtoken';
6
- import { Logger } from 'nightingale-logger';
7
- import type MongoUsersManager from './MongoUsersManager';
1
+ import type { IncomingMessage } from "node:http";
2
+ import { promisify } from "node:util";
3
+ import type { Context, ContextState, NodeApplication } from "alp-node";
4
+ import jsonwebtoken from "jsonwebtoken";
5
+ import { Logger } from "nightingale-logger";
6
+ import type MongoUsersManager from "./MongoUsersManager";
8
7
  import type {
9
8
  AuthController as AuthControllerType,
10
9
  AuthHooks,
11
- } from './createAuthController';
12
- import { createAuthController } from './createAuthController';
13
- import type { AuthRoutes as AuthRoutesType } from './createRoutes';
14
- import { createRoutes } from './createRoutes';
15
- import type { Strategies } from './services/authentification/AuthenticationService';
16
- import { AuthenticationService } from './services/authentification/AuthenticationService';
17
- import type { AllowedStrategyKeys } from './services/authentification/types';
18
- import UserAccountsService from './services/user/UserAccountsService';
19
- import type { AccountService } from './services/user/types';
20
- import type { User, UserSanitized } from './types';
10
+ } from "./createAuthController";
11
+ import { createAuthController } from "./createAuthController";
12
+ import type { AuthRoutes as AuthRoutesType } from "./createRoutes";
13
+ import { createRoutes } from "./createRoutes";
14
+ import type { Strategies } from "./services/authentification/AuthenticationService";
15
+ import { AuthenticationService } from "./services/authentification/AuthenticationService";
16
+ import type { AllowedStrategyKeys } from "./services/authentification/types";
17
+ import UserAccountsService from "./services/user/UserAccountsService";
18
+ import type { AccountService } from "./services/user/types";
19
+ import type { User, UserSanitized } from "./types";
21
20
  import {
22
- getTokenFromRequest,
23
- COOKIE_NAME_TOKEN,
24
21
  COOKIE_NAME_STATE,
25
- } from './utils/cookies';
26
- import { createFindLoggedInUser } from './utils/createFindLoggedInUser';
22
+ COOKIE_NAME_TOKEN,
23
+ getTokenFromRequest,
24
+ } from "./utils/cookies";
25
+ import { createFindLoggedInUser } from "./utils/createFindLoggedInUser";
27
26
 
28
- export { default as MongoUsersManager } from './MongoUsersManager';
29
- export { default as UserAccountGoogleService } from './services/user/UserAccountGoogleService';
30
- export { default as UserAccountSlackService } from './services/user/UserAccountSlackService';
31
- export { authSocketIO } from './authSocketIO';
32
- export { createAuthApolloContext } from './authApolloContext';
33
- export { STATUSES } from './services/user/UserAccountsService';
27
+ export { default as MongoUsersManager } from "./MongoUsersManager";
28
+ export { default as UserAccountGoogleService } from "./services/user/UserAccountGoogleService";
29
+ export { default as UserAccountSlackService } from "./services/user/UserAccountSlackService";
30
+ export { authSocketIO } from "./authSocketIO";
31
+ export { createAuthApolloContext } from "./authApolloContext";
32
+ export { STATUSES } from "./services/user/UserAccountsService";
34
33
 
35
- export * from './types';
34
+ export type * from "./types";
36
35
 
37
- declare module 'alp-node' {
38
- // eslint-disable-next-line @typescript-eslint/no-shadow
36
+ declare module "alp-node" {
39
37
  interface ContextState {
40
38
  loggedInUserId:
41
- | NonNullable<ContextState['loggedInUser']>['_id']
39
+ | NonNullable<ContextState["loggedInUser"]>["_id"]
42
40
  | null
43
41
  | undefined;
44
42
  loggedInUser: User | null | undefined;
@@ -46,7 +44,7 @@ declare module 'alp-node' {
46
44
 
47
45
  interface ContextSanitizedState {
48
46
  loggedInUserId:
49
- | NonNullable<ContextSanitizedState['loggedInUser']>['_id']
47
+ | NonNullable<ContextSanitizedState["loggedInUser"]>["_id"]
50
48
  | null
51
49
  | undefined;
52
50
  loggedInUser: UserSanitized | null | undefined;
@@ -54,23 +52,23 @@ declare module 'alp-node' {
54
52
 
55
53
  interface BaseContext {
56
54
  setLoggedIn: (
57
- loggedInUserId: NonNullable<ContextState['loggedInUserId']>,
58
- loggedInUser: NonNullable<ContextState['loggedInUser']>,
55
+ loggedInUserId: NonNullable<ContextState["loggedInUserId"]>,
56
+ loggedInUser: NonNullable<ContextState["loggedInUser"]>,
59
57
  ) => Promise<void>;
60
58
  logout: () => void;
61
59
  }
62
60
  }
63
61
 
64
- const logger = new Logger('alp:auth');
62
+ const logger = new Logger("alp:auth");
65
63
 
66
64
  const signPromisified: any = promisify(jsonwebtoken.sign);
67
65
 
68
66
  export type AuthController = AuthControllerType;
69
67
  export type AuthRoutes = AuthRoutesType;
70
- export { AuthenticationService } from './services/authentification/AuthenticationService';
68
+ export { AuthenticationService } from "./services/authentification/AuthenticationService";
71
69
 
72
70
  export default function init<
73
- StrategyKeys extends AllowedStrategyKeys = 'google',
71
+ StrategyKeys extends AllowedStrategyKeys = "google",
74
72
  U extends User = User,
75
73
  USanitized extends UserSanitized = UserSanitized,
76
74
  >({
@@ -111,14 +109,14 @@ export default function init<
111
109
  authHooks,
112
110
  });
113
111
 
114
- app.context.setLoggedIn = async function (
112
+ app.context.setLoggedIn = async function setLoggedIn(
115
113
  this: Context,
116
- loggedInUserId: NonNullable<ContextState['loggedInUser']>['_id'],
117
- loggedInUser: NonNullable<ContextState['loggedInUser']>,
114
+ loggedInUserId: NonNullable<ContextState["loggedInUser"]>["_id"],
115
+ loggedInUser: NonNullable<ContextState["loggedInUser"]>,
118
116
  ): Promise<void> {
119
- logger.debug('setLoggedIn', { loggedInUser });
117
+ logger.debug("setLoggedIn", { loggedInUser });
120
118
  if (!loggedInUserId) {
121
- throw new Error('Illegal value for setLoggedIn');
119
+ throw new Error("Illegal value for setLoggedIn");
122
120
  }
123
121
 
124
122
  this.state.loggedInUserId = loggedInUserId;
@@ -127,12 +125,12 @@ export default function init<
127
125
  const token = await signPromisified(
128
126
  { loggedInUserId, time: Date.now() },
129
127
  this.config
130
- .get<Map<string, unknown>>('authentication')
131
- .get('secretKey'),
128
+ .get<Map<string, unknown>>("authentication")
129
+ .get("secretKey"),
132
130
  {
133
- algorithm: 'HS512',
134
- audience: jwtAudience || this.request.headers['user-agent'],
135
- expiresIn: '30 days',
131
+ algorithm: "HS512",
132
+ audience: jwtAudience || this.request.headers["user-agent"],
133
+ expiresIn: "30 days",
136
134
  },
137
135
  );
138
136
 
@@ -142,10 +140,9 @@ export default function init<
142
140
  return date.getTime();
143
141
  };
144
142
 
145
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
146
143
  this.cookies.set(COOKIE_NAME_TOKEN, token, {
147
144
  httpOnly: true,
148
- secure: this.config.get('allowHttps'),
145
+ secure: this.config.get("allowHttps"),
149
146
  });
150
147
 
151
148
  this.cookies.set(
@@ -153,22 +150,20 @@ export default function init<
153
150
  JSON.stringify({ loggedInUserId, expiresIn: calcExpiresTime() }),
154
151
  {
155
152
  httpOnly: false,
156
- secure: this.config.get('allowHttps'),
153
+ secure: this.config.get("allowHttps"),
157
154
  },
158
155
  );
159
156
  };
160
157
 
161
- app.context.logout = function (this: Context): void {
158
+ app.context.logout = function logout(this: Context): void {
162
159
  delete this.state.loggedInUserId;
163
160
  delete this.state.loggedInUser;
164
- this.cookies.set(COOKIE_NAME_TOKEN, '', { expires: new Date(1) });
165
- this.cookies.set(COOKIE_NAME_STATE, '', { expires: new Date(1) });
161
+ this.cookies.set(COOKIE_NAME_TOKEN, "", { expires: new Date(1) });
162
+ this.cookies.set(COOKIE_NAME_STATE, "", { expires: new Date(1) });
166
163
  };
167
164
 
168
165
  const findLoggedInUser = createFindLoggedInUser(
169
- app.config
170
- .get<Map<string, unknown>>('authentication')
171
- .get('secretKey') as string,
166
+ app.config.get<{ secretKey: string }>("authentication").secretKey,
172
167
  usersManager,
173
168
  logger,
174
169
  );
@@ -180,7 +175,7 @@ export default function init<
180
175
  ): ReturnType<typeof findLoggedInUser> => {
181
176
  const token = getTokenFromRequest(req);
182
177
  return findLoggedInUser(
183
- jwtAudience || req.headers['user-agent'],
178
+ jwtAudience || req.headers["user-agent"],
184
179
  token,
185
180
  );
186
181
  },
@@ -190,11 +185,11 @@ export default function init<
190
185
  next: () => Promise<T> | T,
191
186
  ): Promise<T> => {
192
187
  const token = ctx.cookies.get(COOKIE_NAME_TOKEN);
193
- const userAgent = ctx.request.headers['user-agent'];
194
- logger.debug('middleware', { token });
188
+ const userAgent = ctx.request.headers["user-agent"];
189
+ logger.debug("middleware", { token });
195
190
 
196
191
  const setState = (
197
- loggedInUserId: U['_id'] | null | undefined,
192
+ loggedInUserId: U["_id"] | null | undefined,
198
193
  loggedInUser: U | null | undefined,
199
194
  ): void => {
200
195
  ctx.state.loggedInUserId = loggedInUserId;
@@ -208,12 +203,12 @@ export default function init<
208
203
  jwtAudience || userAgent,
209
204
  token,
210
205
  );
211
- logger.debug('middleware', { loggedInUserId });
206
+ logger.debug("middleware", { loggedInUserId });
212
207
 
213
208
  if (loggedInUserId == null || loggedInUser == null) {
214
209
  if (token) {
215
- ctx.cookies.set(COOKIE_NAME_TOKEN, '', { expires: new Date(1) });
216
- ctx.cookies.set(COOKIE_NAME_STATE, '', { expires: new Date(1) });
210
+ ctx.cookies.set(COOKIE_NAME_TOKEN, "", { expires: new Date(1) });
211
+ ctx.cookies.set(COOKIE_NAME_STATE, "", { expires: new Date(1) });
217
212
  }
218
213
  setState(null, null);
219
214
  return next();
@@ -1,17 +1,17 @@
1
1
  /* eslint-disable @typescript-eslint/no-unsafe-argument */
2
2
  /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
3
3
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
4
- /* eslint-disable camelcase, max-lines */
5
- import { EventEmitter } from 'node:events';
6
- import type { Context, NodeConfig } from 'alp-node';
7
- import { Logger } from 'nightingale-logger';
8
- import type { Strategy as Oauth2Strategy } from '../../../strategies/strategies.d';
9
- import type { AccountId, User, Account, UserSanitized } from '../../types';
10
- import { randomHex } from '../../utils/generators';
11
- import type UserAccountsService from '../user/UserAccountsService';
12
- import type { AllowedStrategyKeys, Tokens } from './types';
13
-
14
- const logger = new Logger('alp:auth:authentication');
4
+ /* eslint-disable camelcase */
5
+ import { EventEmitter } from "node:events";
6
+ import type { Context, NodeConfig } from "alp-node";
7
+ import { Logger } from "nightingale-logger";
8
+ import type { Strategy as Oauth2Strategy } from "../../../strategies/strategies.d";
9
+ import type { Account, AccountId, User, UserSanitized } from "../../types";
10
+ import { randomHex } from "../../utils/generators";
11
+ import type UserAccountsService from "../user/UserAccountsService";
12
+ import type { AllowedStrategyKeys, Tokens } from "./types";
13
+
14
+ const logger = new Logger("alp:auth:authentication");
15
15
 
16
16
  export interface GenerateAuthUrlOptions {
17
17
  accessType?: string;
@@ -72,13 +72,13 @@ export class AuthenticationService<
72
72
  }
73
73
 
74
74
  generateAuthUrl<T extends StrategyKeys>(strategy: T, params: any): string {
75
- logger.debug('generateAuthUrl', { strategy, params });
75
+ logger.debug("generateAuthUrl", { strategy, params });
76
76
  const strategyInstance = this.strategies[strategy];
77
77
  switch (strategyInstance.type) {
78
- case 'oauth2':
78
+ case "oauth2":
79
79
  return strategyInstance.oauth2.authorizationCode.authorizeURL(params);
80
80
  default:
81
- throw new Error('Invalid strategy');
81
+ throw new Error("Invalid strategy");
82
82
  }
83
83
  }
84
84
 
@@ -86,10 +86,10 @@ export class AuthenticationService<
86
86
  strategy: StrategyKeys,
87
87
  options: GetTokensOptions,
88
88
  ): Promise<Tokens> {
89
- logger.debug('getTokens', { strategy, options });
89
+ logger.debug("getTokens", { strategy, options });
90
90
  const strategyInstance = this.strategies[strategy];
91
91
  switch (strategyInstance.type) {
92
- case 'oauth2': {
92
+ case "oauth2": {
93
93
  const result = await strategyInstance.oauth2.authorizationCode.getToken(
94
94
  {
95
95
  code: options.code,
@@ -116,7 +116,7 @@ export class AuthenticationService<
116
116
  }
117
117
 
118
118
  default:
119
- throw new Error('Invalid stategy');
119
+ throw new Error("Invalid stategy");
120
120
  }
121
121
  }
122
122
 
@@ -124,13 +124,13 @@ export class AuthenticationService<
124
124
  strategy: StrategyKeys,
125
125
  tokensParam: { refreshToken: string },
126
126
  ): Promise<Tokens> {
127
- logger.debug('refreshToken', { strategy });
127
+ logger.debug("refreshToken", { strategy });
128
128
  if (!tokensParam.refreshToken) {
129
- throw new Error('Missing refresh token');
129
+ throw new Error("Missing refresh token");
130
130
  }
131
131
  const strategyInstance = this.strategies[strategy];
132
132
  switch (strategyInstance.type) {
133
- case 'oauth2': {
133
+ case "oauth2": {
134
134
  const token = strategyInstance.oauth2.clientCredentials.createToken({
135
135
  refresh_token: tokensParam.refreshToken,
136
136
  });
@@ -151,15 +151,15 @@ export class AuthenticationService<
151
151
  }
152
152
 
153
153
  default:
154
- throw new Error('Invalid stategy');
154
+ throw new Error("Invalid stategy");
155
155
  }
156
156
  }
157
157
 
158
158
  redirectUri(ctx: Context, strategy: string): string {
159
- const host = `http${this.config.get('allowHttps') ? 's' : ''}://${
159
+ const host = `http${this.config.get("allowHttps") ? "s" : ""}://${
160
160
  ctx.request.host
161
161
  }`;
162
- return `${host}${ctx.urlGenerator('authResponse', {
162
+ return `${host}${ctx.urlGenerator("authResponse", {
163
163
  strategy,
164
164
  })}`;
165
165
  }
@@ -180,18 +180,18 @@ export class AuthenticationService<
180
180
  },
181
181
  params?: any,
182
182
  ): Promise<void> {
183
- logger.debug('redirectAuthUrl', { strategy, scopeKey, refreshToken });
183
+ logger.debug("redirectAuthUrl", { strategy, scopeKey, refreshToken });
184
184
  const state = await randomHex(8);
185
- const isLoginAccess = !scopeKey || scopeKey === 'login';
185
+ const isLoginAccess = !scopeKey || scopeKey === "login";
186
186
  const scope = this.userAccountsService.getScope(
187
187
  strategy,
188
- scopeKey || 'login',
188
+ scopeKey || "login",
189
189
  user,
190
190
  accountId,
191
191
  );
192
192
 
193
193
  if (!scope) {
194
- throw new Error('Invalid empty scope');
194
+ throw new Error("Invalid empty scope");
195
195
  }
196
196
 
197
197
  ctx.cookies.set(
@@ -204,14 +204,14 @@ export class AuthenticationService<
204
204
  {
205
205
  maxAge: 10 * 60 * 1000,
206
206
  httpOnly: true,
207
- secure: this.config.get('allowHttps'),
207
+ secure: this.config.get("allowHttps"),
208
208
  },
209
209
  );
210
210
  const redirectUri = this.generateAuthUrl(strategy, {
211
211
  redirect_uri: this.redirectUri(ctx, strategy),
212
212
  scope,
213
213
  state,
214
- access_type: refreshToken ? 'offline' : 'online',
214
+ access_type: refreshToken ? "offline" : "online",
215
215
  ...params,
216
216
  });
217
217
 
@@ -224,29 +224,29 @@ export class AuthenticationService<
224
224
  isLoggedIn: boolean,
225
225
  hooks: AccessResponseHooks<StrategyKeys, U>,
226
226
  ): Promise<U> {
227
- const errorParam = ctx.params.queryParam('error').notEmpty();
227
+ const errorParam = ctx.params.queryParam("error").notEmpty();
228
228
  if (errorParam.isValid()) {
229
- ctx.throw(errorParam.value, 403);
229
+ ctx.throw(403, errorParam.value);
230
230
  }
231
231
 
232
- const code = ctx.validParams.queryParam('code').notEmpty().value;
233
- const state = ctx.validParams.queryParam('state').notEmpty().value;
232
+ const code = ctx.validParams.queryParam("code").notEmpty().value;
233
+ const state = ctx.validParams.queryParam("state").notEmpty().value;
234
234
 
235
235
  const cookieName = `auth_${strategy}_${state}`;
236
236
  const cookie = ctx.cookies.get(cookieName);
237
- ctx.cookies.set(cookieName, '', { expires: new Date(1) });
237
+ ctx.cookies.set(cookieName, "", { expires: new Date(1) });
238
238
  if (!cookie) {
239
- throw new Error('No cookie for this state');
239
+ throw new Error("No cookie for this state");
240
240
  }
241
241
 
242
242
  const parsedCookie = JSON.parse(cookie);
243
243
  if (!parsedCookie?.scope) {
244
- throw new Error('Unexpected cookie value');
244
+ throw new Error("Unexpected cookie value");
245
245
  }
246
246
 
247
247
  if (!parsedCookie.isLoginAccess) {
248
248
  if (!isLoggedIn) {
249
- throw new Error('You are not connected');
249
+ throw new Error("You are not connected");
250
250
  }
251
251
  }
252
252
 
@@ -1,11 +1,11 @@
1
1
  export type GoogleParams =
2
- | 'access_type'
3
- | 'include_granted_scopes'
4
- | 'login_hint'
5
- | 'prompt';
6
- export type SlackParams = 'client_id' | 'team';
2
+ | "access_type"
3
+ | "include_granted_scopes"
4
+ | "login_hint"
5
+ | "prompt";
6
+ export type SlackParams = "client_id" | "team";
7
7
 
8
- export type AllowedStrategyKeys = 'google' | 'slack';
8
+ export type AllowedStrategyKeys = "google" | "slack";
9
9
 
10
10
  export interface AllowedMapParamsStrategy {
11
11
  google: GoogleParams;
@@ -1,22 +1,21 @@
1
- /* eslint-disable @typescript-eslint/class-methods-use-this */
2
1
  /* eslint-disable @typescript-eslint/no-unsafe-argument */
3
2
  /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
4
- import type { Tokens } from '../authentification/types';
5
- import type { AccountService, FullName } from './types';
3
+ import type { Tokens } from "../authentification/types";
4
+ import type { AccountService, FullName } from "./types";
6
5
 
7
- export default class UserAccountGoogleService<ScopeKeys extends 'login'>
6
+ export default class UserAccountGoogleService<ScopeKeys extends "login">
8
7
  implements AccountService<ScopeKeys>
9
8
  {
10
9
  scopeKeyToScope: Record<ScopeKeys, string>;
11
10
 
12
- constructor(scopeKeyToScope: Record<Exclude<'login', ScopeKeys>, string>) {
11
+ constructor(scopeKeyToScope: Record<Exclude<"login", ScopeKeys>, string>) {
13
12
  this.scopeKeyToScope = {
14
13
  ...scopeKeyToScope,
15
- login: 'openid profile email',
14
+ login: "openid profile email",
16
15
  };
17
16
  }
18
17
 
19
- providerKey = 'google';
18
+ providerKey = "google";
20
19
 
21
20
  getProfile(tokens: Tokens): Promise<any> {
22
21
  return fetch(
@@ -59,8 +58,8 @@ export default class UserAccountGoogleService<ScopeKeys extends 'login'>
59
58
 
60
59
  getScope(oldScope: string[] | undefined, newScope: string): string[] {
61
60
  return !oldScope
62
- ? newScope.split(' ')
63
- : [...oldScope, ...newScope.split(' ')].filter(
61
+ ? newScope.split(" ")
62
+ : [...oldScope, ...newScope.split(" ")].filter(
64
63
  (item, i, ar) => ar.indexOf(item) === i,
65
64
  );
66
65
  }
@@ -1,23 +1,22 @@
1
- /* eslint-disable @typescript-eslint/class-methods-use-this */
2
1
  /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
3
- import type { Tokens } from '../authentification/types';
4
- import type { AccountService, FullName } from './types';
2
+ import type { Tokens } from "../authentification/types";
3
+ import type { AccountService, FullName } from "./types";
5
4
 
6
5
  // https://api.slack.com/methods/users.identity
7
6
 
8
- export default class UserAccountSlackService<ScopeKeys extends 'login'>
7
+ export default class UserAccountSlackService<ScopeKeys extends "login">
9
8
  implements AccountService<ScopeKeys>
10
9
  {
11
10
  scopeKeyToScope: Record<ScopeKeys, string>;
12
11
 
13
- constructor(scopeKeyToScope: Record<Exclude<'login', ScopeKeys>, string>) {
12
+ constructor(scopeKeyToScope: Record<Exclude<"login", ScopeKeys>, string>) {
14
13
  this.scopeKeyToScope = {
15
14
  ...scopeKeyToScope,
16
- login: 'identity.basic identity.email identity.avatar',
15
+ login: "identity.basic identity.email identity.avatar",
17
16
  };
18
17
  }
19
18
 
20
- providerKey = 'google';
19
+ providerKey = "google";
21
20
 
22
21
  getProfile(tokens: Tokens): Promise<any> {
23
22
  return fetch(
@@ -56,8 +55,8 @@ export default class UserAccountSlackService<ScopeKeys extends 'login'>
56
55
 
57
56
  getScope(oldScope: string[] | undefined, newScope: string): string[] {
58
57
  return !oldScope
59
- ? newScope.split(' ')
60
- : [...oldScope, ...newScope.split(' ')].filter(
58
+ ? newScope.split(" ")
59
+ : [...oldScope, ...newScope.split(" ")].filter(
61
60
  (item, i, ar) => ar.indexOf(item) === i,
62
61
  );
63
62
  }
@@ -1,16 +1,15 @@
1
- /* eslint-disable @typescript-eslint/no-shadow */
2
- import { EventEmitter } from 'node:events';
3
- import { Logger } from 'nightingale-logger';
4
- import type MongoUsersManager from '../../MongoUsersManager';
5
- import type { AccountId, User, Account, UserSanitized } from '../../types';
6
- import type { AllowedStrategyKeys } from '../authentification/types';
7
- import type { AccountService, TokensObject } from './types';
1
+ import { EventEmitter } from "node:events";
2
+ import { Logger } from "nightingale-logger";
3
+ import type MongoUsersManager from "../../MongoUsersManager";
4
+ import type { Account, AccountId, User, UserSanitized } from "../../types";
5
+ import type { AllowedStrategyKeys } from "../authentification/types";
6
+ import type { AccountService, TokensObject } from "./types";
8
7
 
9
- const logger = new Logger('alp:auth:userAccounts');
8
+ const logger = new Logger("alp:auth:userAccounts");
10
9
 
11
10
  export const STATUSES = {
12
- VALIDATED: 'validated',
13
- DELETED: 'deleted',
11
+ VALIDATED: "validated",
12
+ DELETED: "deleted",
14
13
  };
15
14
 
16
15
  export default class UserAccountsService<
@@ -38,13 +37,13 @@ export default class UserAccountsService<
38
37
  user?: U,
39
38
  accountId?: AccountId,
40
39
  ): string {
41
- logger.debug('getScope', { strategy, userId: user?._id });
40
+ logger.debug("getScope", { strategy, userId: user?._id });
42
41
  const service = this.strategyToService[strategy];
43
42
  if (!service) {
44
- throw new Error('Strategy not supported');
43
+ throw new Error("Strategy not supported");
45
44
  }
46
45
 
47
- const newScope = service.scopeKeyToScope[scopeKey];
46
+ const newScope = service.scopeKeyToScope[scopeKey]!;
48
47
  if (!user || !accountId) {
49
48
  return newScope;
50
49
  }
@@ -54,9 +53,9 @@ export default class UserAccountsService<
54
53
  );
55
54
 
56
55
  if (!account) {
57
- throw new Error('Could not found associated account');
56
+ throw new Error("Could not found associated account");
58
57
  }
59
- return service.getScope(account.scope, newScope).join(' ');
58
+ return service.getScope(account.scope, newScope).join(" ");
60
59
  }
61
60
 
62
61
  async update(
@@ -65,7 +64,7 @@ export default class UserAccountsService<
65
64
  tokens: TokensObject,
66
65
  scope: string,
67
66
  subservice: string,
68
- ): Promise<{ user: U; account: U['accounts'][number] }> {
67
+ ): Promise<{ user: U; account: U["accounts"][number] }> {
69
68
  const service = this.strategyToService[strategy];
70
69
  const profile = await service.getProfile(tokens);
71
70
  const accountId = service.getId(profile);
@@ -76,9 +75,9 @@ export default class UserAccountsService<
76
75
  if (!account) {
77
76
  // TODO check if already exists in other user => merge
78
77
  // TODO else add a new account in this user
79
- throw new Error('Could not found associated account');
78
+ throw new Error("Could not found associated account");
80
79
  }
81
- account.status = 'valid';
80
+ account.status = "valid";
82
81
  account.accessToken = tokens.accessToken;
83
82
  if (tokens.refreshToken) {
84
83
  account.refreshToken = tokens.refreshToken;
@@ -103,11 +102,11 @@ export default class UserAccountsService<
103
102
  subservice: string,
104
103
  ): Promise<U> {
105
104
  const service = this.strategyToService[strategy];
106
- if (!service) throw new Error('Strategy not supported');
105
+ if (!service) throw new Error("Strategy not supported");
107
106
 
108
107
  const profile = await service.getProfile(tokens);
109
108
  const accountId = service.getId(profile);
110
- if (!accountId) throw new Error('Invalid profile: no id found');
109
+ if (!accountId) throw new Error("Invalid profile: no id found");
111
110
 
112
111
  const emails = service.getEmails(profile);
113
112
 
@@ -118,7 +117,7 @@ export default class UserAccountsService<
118
117
  emails,
119
118
  });
120
119
 
121
- logger.info(!user ? 'create user' : 'existing user', {
120
+ logger.info(!user ? "create user" : "existing user", {
122
121
  userId: user?._id,
123
122
  accountId,
124
123
  /*emails , user*/
@@ -143,12 +142,11 @@ export default class UserAccountsService<
143
142
 
144
143
  if (!account) {
145
144
  account = { provider: strategy, accountId };
146
- // @ts-expect-error well...
147
- user.accounts.push(account);
145
+ user.accounts.push(account as Account);
148
146
  }
149
147
 
150
148
  account.name = service.getAccountName(profile);
151
- account.status = 'valid';
149
+ account.status = "valid";
152
150
  account.profile = profile;
153
151
  account.accessToken = tokens.accessToken;
154
152
  if (tokens.refreshToken) {
@@ -176,7 +174,7 @@ export default class UserAccountsService<
176
174
  // eslint-disable-next-line unicorn/no-array-reduce
177
175
  ...user.emails.reduce(
178
176
  (domains: Set<string>, email: string) =>
179
- domains.add(email.split('@', 2)[1]),
177
+ domains.add(email.split("@", 2)[1]!),
180
178
  new Set<string>(),
181
179
  ),
182
180
  ];
@@ -12,7 +12,7 @@ export interface TokensObject {
12
12
  idToken: string;
13
13
  }
14
14
 
15
- export interface AccountService<ScopeKeys extends 'login'> {
15
+ export interface AccountService<ScopeKeys extends "login"> {
16
16
  scopeKeyToScope: Record<ScopeKeys, string>;
17
17
  providerKey: string;
18
18
 
package/src/types.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { MongoBaseModel } from 'liwi-mongo';
1
+ import type { MongoBaseModel } from "liwi-mongo";
2
2
 
3
3
  export interface UserName {
4
4
  familyName: string;