@soapjs/soap-auth 0.3.1 → 0.3.3

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 (121) hide show
  1. package/build/__tests__/soap-auth.test.d.ts +1 -0
  2. package/build/__tests__/soap-auth.test.js +42 -0
  3. package/build/errors.d.ts +14 -3
  4. package/build/errors.js +29 -8
  5. package/build/index.d.ts +1 -1
  6. package/build/index.js +1 -1
  7. package/build/services/__tests__/account-lock.service.test.d.ts +1 -0
  8. package/build/services/__tests__/account-lock.service.test.js +55 -0
  9. package/build/services/__tests__/auth-throttle.service.test.d.ts +1 -0
  10. package/build/services/__tests__/auth-throttle.service.test.js +48 -0
  11. package/build/services/__tests__/jwks.service.test.d.ts +1 -0
  12. package/build/services/__tests__/jwks.service.test.js +39 -0
  13. package/build/services/__tests__/mfa.service.test.d.ts +1 -0
  14. package/build/services/__tests__/mfa.service.test.js +66 -0
  15. package/build/services/__tests__/password.service.test.d.ts +1 -0
  16. package/build/services/__tests__/password.service.test.js +66 -0
  17. package/build/services/__tests__/pkce.service.test.d.ts +1 -0
  18. package/build/services/__tests__/pkce.service.test.js +77 -0
  19. package/build/services/__tests__/rate-limit.service.test.d.ts +1 -0
  20. package/build/services/__tests__/rate-limit.service.test.js +37 -0
  21. package/build/services/__tests__/role.service.test.d.ts +1 -0
  22. package/build/services/__tests__/role.service.test.js +31 -0
  23. package/build/services/account-lock.service.d.ts +12 -0
  24. package/build/services/account-lock.service.js +39 -0
  25. package/build/services/auth-throttle.service.d.ts +10 -0
  26. package/build/services/auth-throttle.service.js +43 -0
  27. package/build/services/index.d.ts +8 -0
  28. package/build/{factories → services}/index.js +8 -3
  29. package/build/services/jwks.service.d.ts +7 -0
  30. package/build/services/jwks.service.js +41 -0
  31. package/build/services/mfa.service.d.ts +12 -0
  32. package/build/services/mfa.service.js +74 -0
  33. package/build/services/password.service.d.ts +14 -0
  34. package/build/services/password.service.js +78 -0
  35. package/build/services/pkce.service.d.ts +14 -0
  36. package/build/services/pkce.service.js +81 -0
  37. package/build/services/rate-limit.service.d.ts +9 -0
  38. package/build/services/rate-limit.service.js +26 -0
  39. package/build/services/role.service.d.ts +9 -0
  40. package/build/services/role.service.js +26 -0
  41. package/build/session/__tests__/file.session-store.test.d.ts +1 -0
  42. package/build/session/__tests__/file.session-store.test.js +117 -0
  43. package/build/session/__tests__/memory.session-store.test.d.ts +1 -0
  44. package/build/session/__tests__/memory.session-store.test.js +77 -0
  45. package/build/session/__tests__/session-handler.test.d.ts +1 -0
  46. package/build/session/__tests__/session-handler.test.js +337 -0
  47. package/build/session/file.session-store.d.ts +1 -0
  48. package/build/session/file.session-store.js +7 -0
  49. package/build/session/memory.session-store.d.ts +4 -1
  50. package/build/session/memory.session-store.js +11 -5
  51. package/build/session/session-handler.d.ts +12 -7
  52. package/build/session/session-handler.js +46 -13
  53. package/build/session/session.errors.d.ts +6 -0
  54. package/build/session/session.errors.js +15 -0
  55. package/build/soap-auth.d.ts +9 -8
  56. package/build/soap-auth.js +42 -29
  57. package/build/strategies/__tests__/base-auth.strategy.test.d.ts +14 -0
  58. package/build/strategies/__tests__/base-auth.strategy.test.js +137 -0
  59. package/build/strategies/__tests__/credential-auth.strategy.test.d.ts +14 -0
  60. package/build/strategies/__tests__/credential-auth.strategy.test.js +265 -0
  61. package/build/strategies/__tests__/token-auth.strategy.test.d.ts +28 -0
  62. package/build/strategies/__tests__/token-auth.strategy.test.js +298 -0
  63. package/build/strategies/api-key/__tests__/api-key.strategy.test.d.ts +1 -0
  64. package/build/strategies/api-key/__tests__/api-key.strategy.test.js +103 -0
  65. package/build/strategies/api-key/api-key.strategy.d.ts +5 -2
  66. package/build/strategies/api-key/api-key.strategy.js +43 -35
  67. package/build/strategies/api-key/api-key.tools.d.ts +2 -0
  68. package/build/strategies/api-key/api-key.tools.js +39 -0
  69. package/build/strategies/api-key/api-key.types.d.ts +10 -2
  70. package/build/strategies/base-auth.strategy.d.ts +11 -5
  71. package/build/strategies/base-auth.strategy.js +45 -52
  72. package/build/strategies/basic/__tests__/basic.strategy.test.d.ts +1 -0
  73. package/build/strategies/basic/__tests__/basic.strategy.test.js +104 -0
  74. package/build/strategies/basic/basic.strategy.d.ts +5 -7
  75. package/build/strategies/basic/basic.strategy.js +6 -6
  76. package/build/strategies/basic/basic.tools.d.ts +2 -0
  77. package/build/strategies/basic/basic.tools.js +44 -0
  78. package/build/strategies/credential-auth.strategy.d.ts +7 -17
  79. package/build/strategies/credential-auth.strategy.js +116 -181
  80. package/build/strategies/jwt/__tests__/jwt.strategy.test.d.ts +1 -0
  81. package/build/strategies/jwt/__tests__/jwt.strategy.test.js +156 -0
  82. package/build/strategies/jwt/__tests__/jwt.tools.test.d.ts +1 -0
  83. package/build/strategies/jwt/__tests__/jwt.tools.test.js +98 -0
  84. package/build/strategies/jwt/jwt.strategy.d.ts +13 -14
  85. package/build/strategies/jwt/jwt.strategy.js +57 -44
  86. package/build/strategies/jwt/jwt.tools.d.ts +20 -7
  87. package/build/strategies/jwt/jwt.tools.js +180 -81
  88. package/build/strategies/local/__tests__/local.strategy.test.d.ts +1 -0
  89. package/build/strategies/local/__tests__/local.strategy.test.js +115 -0
  90. package/build/strategies/local/local.strategy.d.ts +4 -3
  91. package/build/strategies/local/local.strategy.js +7 -6
  92. package/build/strategies/local/local.tools.d.ts +2 -0
  93. package/build/strategies/local/local.tools.js +44 -0
  94. package/build/strategies/oauth2/hybrid.oauth2.strategy.d.ts +5 -0
  95. package/build/strategies/oauth2/hybrid.oauth2.strategy.js +92 -0
  96. package/build/strategies/oauth2/oauth2.errors.d.ts +12 -0
  97. package/build/strategies/oauth2/oauth2.errors.js +24 -0
  98. package/build/strategies/oauth2/oauth2.strategy.d.ts +25 -15
  99. package/build/strategies/oauth2/oauth2.strategy.js +131 -141
  100. package/build/strategies/oauth2/oauth2.tools.d.ts +7 -2
  101. package/build/strategies/oauth2/oauth2.tools.js +119 -14
  102. package/build/strategies/oauth2/oauth2.types.d.ts +32 -1
  103. package/build/strategies/token-auth.strategy.d.ts +14 -8
  104. package/build/strategies/token-auth.strategy.js +162 -38
  105. package/build/tools/index.d.ts +0 -2
  106. package/build/tools/index.js +0 -2
  107. package/build/tools/tools.d.ts +2 -1
  108. package/build/tools/tools.js +9 -12
  109. package/build/types.d.ts +88 -57
  110. package/package.json +1 -1
  111. package/build/factories/auth-strategy.factory.d.ts +0 -9
  112. package/build/factories/auth-strategy.factory.js +0 -16
  113. package/build/factories/http-auth-strategy.factory.d.ts +0 -5
  114. package/build/factories/http-auth-strategy.factory.js +0 -41
  115. package/build/factories/index.d.ts +0 -3
  116. package/build/factories/socket-auth-strategy.factory.d.ts +0 -5
  117. package/build/factories/socket-auth-strategy.factory.js +0 -27
  118. package/build/tools/session.tools.d.ts +0 -6
  119. package/build/tools/session.tools.js +0 -15
  120. package/build/tools/token.tools.d.ts +0 -7
  121. package/build/tools/token.tools.js +0 -32
@@ -2,14 +2,15 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LocalStrategy = void 0;
4
4
  const credential_auth_strategy_1 = require("../credential-auth.strategy");
5
+ const local_tools_1 = require("./local.tools");
5
6
  class LocalStrategy extends credential_auth_strategy_1.CredentialAuthStrategy {
6
- config;
7
7
  session;
8
+ jwt;
8
9
  logger;
9
- constructor(config, session, logger) {
10
- super(config, session, logger);
11
- this.config = config;
10
+ constructor(config, session, jwt, logger) {
11
+ super((0, local_tools_1.prepareLocalConfig)(config), session, jwt, logger);
12
12
  this.session = session;
13
+ this.jwt = jwt;
13
14
  this.logger = logger;
14
15
  }
15
16
  extractCredentials(context) {
@@ -18,8 +19,8 @@ class LocalStrategy extends credential_auth_strategy_1.CredentialAuthStrategy {
18
19
  async verifyCredentials(identifier, password) {
19
20
  return this.config.credentials.verifyCredentials(identifier, password);
20
21
  }
21
- async retrieveUser(credentials) {
22
- return this.config.user.getUserData(credentials.identifier);
22
+ async fetchUser(credentials) {
23
+ return this.config.user.fetchUser(credentials.identifier);
23
24
  }
24
25
  }
25
26
  exports.LocalStrategy = LocalStrategy;
@@ -0,0 +1,2 @@
1
+ import { LocalStrategyConfig } from "./local.types";
2
+ export declare const prepareLocalConfig: <TContext = any, TUser = any>(config: LocalStrategyConfig<TContext, TUser>) => LocalStrategyConfig<TContext, TUser>;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.prepareLocalConfig = void 0;
27
+ const Soap = __importStar(require("@soapjs/soap"));
28
+ const prepareLocalConfig = (config) => {
29
+ return Soap.removeUndefinedProperties({
30
+ ...config,
31
+ routes: {
32
+ ...config.routes,
33
+ login: {
34
+ path: config.routes.login.path || '/auth/local/login',
35
+ method: config.routes.login.method || 'POST'
36
+ },
37
+ logout: {
38
+ path: config.routes.logout.path || '/auth/local/logout',
39
+ method: config.routes.logout.method || 'POST'
40
+ }
41
+ }
42
+ });
43
+ };
44
+ exports.prepareLocalConfig = prepareLocalConfig;
@@ -0,0 +1,5 @@
1
+ import { AuthResult } from "../../types";
2
+ import { OAuth2Strategy } from "./oauth2.strategy";
3
+ export declare abstract class HybridOAuth2Strategy<TContext = unknown, TUser = unknown> extends OAuth2Strategy<TContext, TUser> {
4
+ authenticate(context: TContext): Promise<AuthResult<TUser>>;
5
+ }
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HybridOAuth2Strategy = void 0;
4
+ const errors_1 = require("../../errors");
5
+ const oauth2_strategy_1 = require("./oauth2.strategy");
6
+ const oauth2_errors_1 = require("./oauth2.errors");
7
+ const oauth2_tools_1 = require("./oauth2.tools");
8
+ class HybridOAuth2Strategy extends oauth2_strategy_1.OAuth2Strategy {
9
+ async authenticate(context) {
10
+ try {
11
+ let tokens;
12
+ let session;
13
+ let accessToken, idToken, refreshToken;
14
+ if (this.jwt) {
15
+ try {
16
+ const jwtResult = await this.jwt.authenticate(context);
17
+ if (jwtResult.user) {
18
+ this.logger?.info("Authenticated using JWT.");
19
+ return jwtResult;
20
+ }
21
+ }
22
+ catch (e) {
23
+ this.logger?.warn("JWT authentication failed, proceeding with OAuth2 flow.");
24
+ }
25
+ }
26
+ if (this.session) {
27
+ try {
28
+ const sessionResult = await this.authenticateWithSession(context);
29
+ if (sessionResult.user) {
30
+ this.logger?.info("Authenticated using session.");
31
+ return sessionResult;
32
+ }
33
+ }
34
+ catch (e) {
35
+ this.logger?.warn("Session authentication failed, proceeding with OAuth2 flow.");
36
+ }
37
+ }
38
+ refreshToken = await this.extractRefreshToken(context);
39
+ if (refreshToken) {
40
+ this.logger?.info("Refreshing expired access token...");
41
+ try {
42
+ const refreshedTokens = await this.refreshAccessToken(context);
43
+ accessToken = refreshedTokens.accessToken;
44
+ idToken = refreshedTokens.idToken;
45
+ }
46
+ catch (error) {
47
+ this.logger?.warn("Failed to refresh access token, clearing refresh token.");
48
+ await this.storeRefreshToken("", context);
49
+ }
50
+ }
51
+ if (!accessToken) {
52
+ const code = this.extractAuthorizationCode(context);
53
+ if (!code) {
54
+ this.login(context);
55
+ throw new errors_1.MissingAuthorizationCodeError();
56
+ }
57
+ const returnedState = oauth2_tools_1.OAuth2Tools.extractState(context);
58
+ if (!(await this.config.state?.validateState(context, returnedState))) {
59
+ throw new oauth2_errors_1.InvalidStateError();
60
+ }
61
+ const exchangedTokens = await this.exchangeCodeForToken(context, code);
62
+ accessToken = exchangedTokens.accessToken;
63
+ refreshToken = exchangedTokens.refreshToken;
64
+ idToken = exchangedTokens.idToken;
65
+ }
66
+ const user = idToken
67
+ ? await this.verifyIdToken(idToken)
68
+ : await this.fetchUser(accessToken);
69
+ if (!user)
70
+ throw new errors_1.UserNotFoundError();
71
+ if (this.jwt) {
72
+ tokens = await this.jwt.issueTokens(user, context);
73
+ }
74
+ if (this.session) {
75
+ session = await this.session.issueSession(user, context);
76
+ }
77
+ return {
78
+ user,
79
+ tokens: tokens ?? { accessToken, idToken, refreshToken },
80
+ session,
81
+ };
82
+ }
83
+ catch (error) {
84
+ await this.onFailure("authenticate", {
85
+ context,
86
+ error,
87
+ });
88
+ throw error;
89
+ }
90
+ }
91
+ }
92
+ exports.HybridOAuth2Strategy = HybridOAuth2Strategy;
@@ -0,0 +1,12 @@
1
+ export declare class InvalidNonceError extends Error {
2
+ }
3
+ export declare class InvalidStateError extends Error {
4
+ }
5
+ export declare class InvalidIdTokenError extends Error {
6
+ }
7
+ export declare class UnsupportedGrantTypeError extends Error {
8
+ constructor(type: string);
9
+ }
10
+ export declare class MissingCodeVerifierError extends Error {
11
+ constructor();
12
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MissingCodeVerifierError = exports.UnsupportedGrantTypeError = exports.InvalidIdTokenError = exports.InvalidStateError = exports.InvalidNonceError = void 0;
4
+ class InvalidNonceError extends Error {
5
+ }
6
+ exports.InvalidNonceError = InvalidNonceError;
7
+ class InvalidStateError extends Error {
8
+ }
9
+ exports.InvalidStateError = InvalidStateError;
10
+ class InvalidIdTokenError extends Error {
11
+ }
12
+ exports.InvalidIdTokenError = InvalidIdTokenError;
13
+ class UnsupportedGrantTypeError extends Error {
14
+ constructor(type) {
15
+ super(`Unsupported grant type: ${type}`);
16
+ }
17
+ }
18
+ exports.UnsupportedGrantTypeError = UnsupportedGrantTypeError;
19
+ class MissingCodeVerifierError extends Error {
20
+ constructor() {
21
+ super("Missing PKCE code verifier in context.");
22
+ }
23
+ }
24
+ exports.MissingCodeVerifierError = MissingCodeVerifierError;
@@ -3,38 +3,44 @@ import { AuthResult } from "../../types";
3
3
  import { OAuth2StrategyConfig } from "./oauth2.types";
4
4
  import { SessionHandler } from "../../session/session-handler";
5
5
  import { BaseAuthStrategy } from "../base-auth.strategy";
6
- export declare class OAuth2Strategy<TContext = unknown, TUser = unknown> extends BaseAuthStrategy<TContext, TUser> {
6
+ import { JwtStrategy } from "../jwt/jwt.strategy";
7
+ import { JwtService } from "../../services/jwks.service";
8
+ import { PKCEService } from "../../services/pkce.service";
9
+ export declare abstract class OAuth2Strategy<TContext = unknown, TUser = unknown> extends BaseAuthStrategy<TContext, TUser> {
7
10
  protected config: OAuth2StrategyConfig<TContext, TUser>;
8
11
  protected session?: SessionHandler;
12
+ protected jwt?: JwtStrategy<TContext, TUser>;
9
13
  protected logger?: Soap.Logger;
10
- constructor(config: OAuth2StrategyConfig<TContext, TUser>, session?: SessionHandler, logger?: Soap.Logger);
14
+ protected jwks: JwtService;
15
+ protected pkce: PKCEService<TContext>;
16
+ protected abstract extractAccessToken(context: TContext): Promise<string | undefined>;
17
+ protected abstract extractRefreshToken(context: TContext): Promise<string | undefined>;
18
+ protected abstract storeAccessToken(token: string, context: TContext): Promise<void>;
19
+ protected abstract storeRefreshToken(token: string, context: TContext): Promise<void>;
20
+ protected abstract embedAccessToken(token: string, context: TContext): any;
21
+ protected abstract embedRefreshToken(token: string, context: TContext): any;
22
+ protected abstract extractAuthorizationCode(context: TContext): string | null;
23
+ protected abstract redirectUser(context: TContext, authUrl: string): void;
24
+ constructor(config: OAuth2StrategyConfig<TContext, TUser>, session?: SessionHandler, jwt?: JwtStrategy<TContext, TUser>, logger?: Soap.Logger);
11
25
  logout(context: TContext): Promise<void>;
12
26
  protected getCredentialsForPasswordGrant(context: TContext): Promise<{
13
27
  identifier: string;
14
28
  password: string;
15
29
  }>;
16
- protected retrieveAccessToken(context: TContext): Promise<string | undefined>;
17
- protected retrieveRefreshToken(context: TContext): Promise<string | undefined>;
18
- protected storeAccessToken(token: string, context: TContext): Promise<void>;
19
- protected storeRefreshToken(token: string, context: TContext): Promise<void>;
20
- protected embedAccessToken(token: string, context: TContext): void;
21
- protected embedRefreshToken(token: string, context: TContext): void;
22
- isTokenExpired(token: string): Promise<boolean>;
23
30
  authenticate(context: TContext): Promise<AuthResult<TUser>>;
24
31
  protected processOAuthFlow(context: TContext): Promise<{
25
32
  accessToken: string;
26
33
  refreshToken?: string;
27
34
  }>;
28
- protected verifyAuthorizationCode(context: TContext, code: string): void;
29
- protected extractAuthorizationCode(context: TContext): string | null;
30
- protected redirectUser(context: TContext, authUrl: string): void;
31
- protected buildAuthorizationUrl(context: TContext): string;
35
+ protected verifyAuthorizationCode(context: TContext, code: string): Promise<void>;
36
+ protected buildAuthorizationUrl(context: TContext): Promise<string>;
32
37
  protected exchangeCodeForToken(context: TContext, code: string): Promise<{
33
38
  accessToken: string;
39
+ idToken?: string;
34
40
  refreshToken?: string;
35
41
  }>;
36
- handleAuthorizationRedirect(context: TContext): void;
37
- protected retrieveUser(accessToken: string): Promise<TUser | null>;
42
+ login(context: TContext): Promise<void>;
43
+ protected fetchUser(accessToken: string): Promise<TUser | null>;
38
44
  protected exchangeClientCredentials(): Promise<{
39
45
  accessToken: string;
40
46
  }>;
@@ -44,6 +50,10 @@ export declare class OAuth2Strategy<TContext = unknown, TUser = unknown> extends
44
50
  refreshAccessToken(context: TContext): Promise<{
45
51
  accessToken: string;
46
52
  refreshToken?: string;
53
+ idToken?: string;
47
54
  }>;
55
+ protected handleTokenRefreshFailure(context: TContext): Promise<void>;
56
+ protected verifyIdToken(idToken: string): Promise<TUser | null>;
48
57
  revokeToken(token: string): Promise<void>;
58
+ protected isTokenExpired(token: string): boolean;
49
59
  }