alp-node-auth 9.3.0 → 11.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 (59) 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 -26
  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 -2
  18. package/dist/definitions/services/authentification/types.d.ts.map +1 -1
  19. package/dist/definitions/services/user/UserAccountGoogleService.d.ts +4 -4
  20. package/dist/definitions/services/user/UserAccountGoogleService.d.ts.map +1 -1
  21. package/dist/definitions/services/user/UserAccountSlackService.d.ts +4 -4
  22. package/dist/definitions/services/user/UserAccountSlackService.d.ts.map +1 -1
  23. package/dist/definitions/services/user/UserAccountsService.d.ts +6 -7
  24. package/dist/definitions/services/user/UserAccountsService.d.ts.map +1 -1
  25. package/dist/definitions/services/user/types.d.ts +1 -1
  26. package/dist/definitions/types.d.ts +1 -1
  27. package/dist/definitions/utils/cookies.d.ts +3 -4
  28. package/dist/definitions/utils/cookies.d.ts.map +1 -1
  29. package/dist/definitions/utils/createFindLoggedInUser.d.ts +4 -4
  30. package/dist/definitions/utils/createFindLoggedInUser.d.ts.map +1 -1
  31. package/dist/{index-node18.mjs → index-node20.mjs} +115 -124
  32. package/dist/index-node20.mjs.map +1 -0
  33. package/package.json +24 -26
  34. package/src/MongoUsersManager.ts +5 -6
  35. package/src/authApolloContext.ts +10 -10
  36. package/src/authSocketIO.ts +10 -10
  37. package/src/createAuthController.ts +22 -20
  38. package/src/createRoutes.ts +8 -8
  39. package/src/index.ts +58 -64
  40. package/src/services/authentification/AuthenticationService.ts +56 -53
  41. package/src/services/authentification/types.ts +7 -2
  42. package/src/services/user/UserAccountGoogleService.ts +9 -9
  43. package/src/services/user/UserAccountSlackService.ts +9 -9
  44. package/src/services/user/UserAccountsService.ts +23 -25
  45. package/src/services/user/types.ts +1 -1
  46. package/src/types.ts +1 -1
  47. package/src/utils/cookies.ts +8 -8
  48. package/src/utils/createFindLoggedInUser.ts +9 -9
  49. package/src/utils/generators.ts +4 -4
  50. package/strategies/dropbox.js +7 -7
  51. package/strategies/facebook.js +7 -7
  52. package/strategies/foursquare.js +7 -7
  53. package/strategies/github.js +7 -7
  54. package/strategies/google.js +7 -7
  55. package/strategies/slack.js +7 -7
  56. package/strategies/strategies.d.ts +8 -3
  57. package/dist/index-node18.mjs.map +0 -1
  58. package/src/.eslintrc.json +0 -38
  59. package/strategies/.eslintrc.json +0 -3
@@ -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;
@@ -1,16 +1,16 @@
1
- import type { IncomingMessage } from 'node:http';
2
- import type { Option } from 'cookies';
3
- import Cookies from 'cookies';
1
+ import type { IncomingMessage } from "node:http";
2
+ import type { Option } from "cookies";
3
+ import Cookies from "cookies";
4
4
 
5
- export const COOKIE_NAME_TOKEN = 'loggedInUserToken';
6
- export const COOKIE_NAME_STATE = 'loggedInUserState';
5
+ export const COOKIE_NAME_TOKEN = "loggedInUserToken";
6
+ export const COOKIE_NAME_STATE = "loggedInUserState";
7
7
 
8
8
  export const getTokenFromRequest = (
9
9
  req: IncomingMessage,
10
- options?: Pick<Option, Exclude<keyof Option, 'secure'>>,
10
+ options?: Pick<Option, Exclude<keyof Option, "secure">>,
11
11
  ): string | undefined => {
12
- if (req.headers.authorization?.startsWith('Bearer ')) {
13
- return req.headers.authorization.slice('Bearer '.length);
12
+ if (req.headers.authorization?.startsWith("Bearer ")) {
13
+ return req.headers.authorization.slice("Bearer ".length);
14
14
  }
15
15
 
16
16
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
@@ -1,14 +1,14 @@
1
- import { promisify } from 'node:util';
1
+ import { promisify } from "node:util";
2
2
  import type {
3
3
  GetPublicKeyOrSecret,
4
4
  Secret,
5
5
  VerifyCallback,
6
6
  VerifyOptions,
7
- } from 'jsonwebtoken';
8
- import jsonwebtoken from 'jsonwebtoken';
9
- import type { Logger } from 'nightingale-logger';
10
- import type MongoUsersManager from '../MongoUsersManager';
11
- import type { User, UserSanitized } from '../types';
7
+ } from "jsonwebtoken";
8
+ import jsonwebtoken from "jsonwebtoken";
9
+ import type { Logger } from "nightingale-logger";
10
+ import type MongoUsersManager from "../MongoUsersManager";
11
+ import type { User, UserSanitized } from "../types";
12
12
 
13
13
  type Verify = (
14
14
  token: string,
@@ -28,7 +28,7 @@ const createDecodeJWT =
28
28
  (secretKey: string) =>
29
29
  async (token: string, jwtAudience: string): Promise<string | undefined> => {
30
30
  const result = await verifyPromisified(token, secretKey, {
31
- algorithms: ['HS512'],
31
+ algorithms: ["HS512"],
32
32
  audience: jwtAudience,
33
33
  });
34
34
  return (result as any)?.loggedInUserId as string | undefined;
@@ -37,7 +37,7 @@ const createDecodeJWT =
37
37
  export type FindLoggedInUser<U extends User> = (
38
38
  jwtAudience?: string,
39
39
  token?: string,
40
- ) => Promise<[U['_id'] | null | undefined, U | null | undefined]>;
40
+ ) => Promise<[U["_id"] | null | undefined, U | null | undefined]>;
41
41
 
42
42
  export const createFindLoggedInUser = <
43
43
  U extends User,
@@ -56,7 +56,7 @@ export const createFindLoggedInUser = <
56
56
  try {
57
57
  loggedInUserId = await decodeJwt(token, jwtAudience);
58
58
  } catch (error: unknown) {
59
- logger.debug('failed to verify authentification', { err: error });
59
+ logger.debug("failed to verify authentification", { err: error });
60
60
  }
61
61
 
62
62
  if (loggedInUserId == null) return [null, null];
@@ -1,14 +1,14 @@
1
- import { randomBytes } from 'node:crypto';
2
- import { promisify } from 'node:util';
1
+ import { randomBytes } from "node:crypto";
2
+ import { promisify } from "node:util";
3
3
 
4
4
  const randomBytesPromisified = promisify(randomBytes);
5
5
 
6
6
  export async function randomBase64(size: number): Promise<string> {
7
7
  const buffer = await randomBytesPromisified(size);
8
- return buffer.toString('base64');
8
+ return buffer.toString("base64");
9
9
  }
10
10
 
11
11
  export async function randomHex(size: number): Promise<string> {
12
12
  const buffer = await randomBytesPromisified(size);
13
- return buffer.toString('hex');
13
+ return buffer.toString("hex");
14
14
  }
@@ -1,25 +1,25 @@
1
- import { ClientCredentials, AuthorizationCode } from 'simple-oauth2';
1
+ import { AuthorizationCode, ClientCredentials } from "simple-oauth2";
2
2
 
3
3
  export default function dropboxStrategy(config) {
4
4
  const options = {
5
5
  client: {
6
- id: config.get('dropbox').get('clientId'),
7
- secret: config.get('dropbox').get('clientSecret'),
6
+ id: config.get("dropbox").clientId,
7
+ secret: config.get("dropbox").clientSecret,
8
8
  },
9
9
  auth: {
10
- tokenHost: 'https://www.dropbox.com',
11
- tokenPath: '/1/oauth2/token',
10
+ tokenHost: "https://www.dropbox.com",
11
+ tokenPath: "/1/oauth2/token",
12
12
  },
13
13
  };
14
14
  const authOptions = {
15
15
  ...options,
16
16
  auth: {
17
17
  ...options.auth,
18
- authorizePath: '/1/oauth2/authorize',
18
+ authorizePath: "/1/oauth2/authorize",
19
19
  },
20
20
  };
21
21
  return {
22
- type: 'oauth2',
22
+ type: "oauth2",
23
23
  oauth2: {
24
24
  authorizationCode: new AuthorizationCode(authOptions),
25
25
  clientCredentials: new ClientCredentials(options),
@@ -1,25 +1,25 @@
1
- import { ClientCredentials, AuthorizationCode } from 'simple-oauth2';
1
+ import { AuthorizationCode, ClientCredentials } from "simple-oauth2";
2
2
 
3
3
  export default function facebookStrategy(config) {
4
4
  const options = {
5
5
  client: {
6
- id: config.get('facebook').get('clientId'),
7
- secret: config.get('facebook').get('clientSecret'),
6
+ id: config.get("facebook").clientId,
7
+ secret: config.get("facebook").clientSecret,
8
8
  },
9
9
  auth: {
10
- tokenHost: 'https://www.facebook.com',
11
- tokenPath: '/oauth/access_token',
10
+ tokenHost: "https://www.facebook.com",
11
+ tokenPath: "/oauth/access_token",
12
12
  },
13
13
  };
14
14
  const authOptions = {
15
15
  ...options,
16
16
  auth: {
17
17
  ...options.auth,
18
- authorizePath: '/dialog/oauth',
18
+ authorizePath: "/dialog/oauth",
19
19
  },
20
20
  };
21
21
  return {
22
- type: 'oauth2',
22
+ type: "oauth2",
23
23
  oauth2: {
24
24
  authorizationCode: new AuthorizationCode(authOptions),
25
25
  clientCredentials: new ClientCredentials(options),
@@ -1,25 +1,25 @@
1
- import { ClientCredentials, AuthorizationCode } from 'simple-oauth2';
1
+ import { AuthorizationCode, ClientCredentials } from "simple-oauth2";
2
2
 
3
3
  export default function foursquareStrategy(config) {
4
4
  const options = {
5
5
  client: {
6
- id: config.get('foursquare').get('clientId'),
7
- secret: config.get('foursquare').get('clientSecret'),
6
+ id: config.get("foursquare").clientId,
7
+ secret: config.get("foursquare").clientSecret,
8
8
  },
9
9
  auth: {
10
- tokenHost: 'https://foursquare.com',
11
- tokenPath: '/oauth2/access_token',
10
+ tokenHost: "https://foursquare.com",
11
+ tokenPath: "/oauth2/access_token",
12
12
  },
13
13
  };
14
14
  const authOptions = {
15
15
  ...options,
16
16
  auth: {
17
17
  ...options.auth,
18
- authorizePath: '/oauth2/authenticate',
18
+ authorizePath: "/oauth2/authenticate",
19
19
  },
20
20
  };
21
21
  return {
22
- type: 'oauth2',
22
+ type: "oauth2",
23
23
  oauth2: {
24
24
  authorizationCode: new AuthorizationCode(authOptions),
25
25
  clientCredentials: new ClientCredentials(options),
@@ -1,25 +1,25 @@
1
- import { ClientCredentials, AuthorizationCode } from 'simple-oauth2';
1
+ import { AuthorizationCode, ClientCredentials } from "simple-oauth2";
2
2
 
3
3
  export default function githubStrategy(config) {
4
4
  const options = {
5
5
  client: {
6
- id: config.get('github').get('clientId'),
7
- secret: config.get('github').get('clientSecret'),
6
+ id: config.get("github").clientId,
7
+ secret: config.get("github").clientSecret,
8
8
  },
9
9
  auth: {
10
- tokenHost: 'https://github.com',
11
- tokenPath: '/login/oauth/access_token',
10
+ tokenHost: "https://github.com",
11
+ tokenPath: "/login/oauth/access_token",
12
12
  },
13
13
  };
14
14
  const authOptions = {
15
15
  ...options,
16
16
  auth: {
17
17
  ...options.auth,
18
- authorizePath: '/login/oauth/authorize',
18
+ authorizePath: "/login/oauth/authorize",
19
19
  },
20
20
  };
21
21
  return {
22
- type: 'oauth2',
22
+ type: "oauth2",
23
23
  oauth2: {
24
24
  authorizationCode: new AuthorizationCode(authOptions),
25
25
  clientCredentials: new ClientCredentials(options),
@@ -1,26 +1,26 @@
1
- import { ClientCredentials, AuthorizationCode } from 'simple-oauth2';
1
+ import { AuthorizationCode, ClientCredentials } from "simple-oauth2";
2
2
 
3
3
  export default function googleStrategy(config) {
4
4
  const options = {
5
5
  client: {
6
- id: config.get('google').get('clientId'),
7
- secret: config.get('google').get('clientSecret'),
6
+ id: config.get("google").clientId,
7
+ secret: config.get("google").clientSecret,
8
8
  },
9
9
  auth: {
10
- tokenHost: 'https://accounts.google.com',
11
- tokenPath: '/o/oauth2/token',
10
+ tokenHost: "https://accounts.google.com",
11
+ tokenPath: "/o/oauth2/token",
12
12
  },
13
13
  };
14
14
  const authOptions = {
15
15
  ...options,
16
16
  auth: {
17
17
  ...options.auth,
18
- authorizePath: '/o/oauth2/auth',
18
+ authorizePath: "/o/oauth2/auth",
19
19
  },
20
20
  };
21
21
 
22
22
  return {
23
- type: 'oauth2',
23
+ type: "oauth2",
24
24
  oauth2: {
25
25
  authorizationCode: new AuthorizationCode(authOptions),
26
26
  clientCredentials: new ClientCredentials(options),
@@ -1,25 +1,25 @@
1
- import { ClientCredentials, AuthorizationCode } from 'simple-oauth2';
1
+ import { AuthorizationCode, ClientCredentials } from "simple-oauth2";
2
2
 
3
3
  export default function slackStrategy(config) {
4
4
  const options = {
5
5
  client: {
6
- id: config.get('slack').get('clientId'),
7
- secret: config.get('slack').get('clientSecret'),
6
+ id: config.get("slack").clientId,
7
+ secret: config.get("slack").clientSecret,
8
8
  },
9
9
  auth: {
10
- tokenHost: 'https://slack.com',
11
- tokenPath: '/api/oauth.access',
10
+ tokenHost: "https://slack.com",
11
+ tokenPath: "/api/oauth.access",
12
12
  },
13
13
  };
14
14
  const authOptions = {
15
15
  ...options,
16
16
  auth: {
17
17
  ...options.auth,
18
- authorizePath: '/oauth/authorize',
18
+ authorizePath: "/oauth/authorize",
19
19
  },
20
20
  };
21
21
  return {
22
- type: 'oauth2',
22
+ type: "oauth2",
23
23
  oauth2: {
24
24
  authorizationCode: new AuthorizationCode(authOptions),
25
25
  clientCredentials: new ClientCredentials(options),
@@ -1,8 +1,13 @@
1
- import { Config, SlackParams } from 'alp-types';
2
- import { ClientCredentials, AuthorizationCode } from 'simple-oauth2';
1
+ import { ClientCredentials, AuthorizationCode } from "simple-oauth2";
2
+ export type GoogleParams =
3
+ | "access_type"
4
+ | "include_granted_scopes"
5
+ | "login_hint"
6
+ | "prompt";
7
+ export type SlackParams = "client_id" | "team";
3
8
 
4
9
  export interface Strategy<Params = SlackParams> {
5
- type: 'oauth2';
10
+ type: "oauth2";
6
11
  oauth2: {
7
12
  authorizationCode: AuthorizationCode<Params>;
8
13
  clientCredentials: ClientCredentials<Params>;