@soapjs/soap-auth 0.3.3 → 0.4.4

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 (98) hide show
  1. package/.claude/settings.local.json +20 -0
  2. package/build/errors.d.ts +1 -1
  3. package/build/errors.js +2 -2
  4. package/build/index.d.ts +1 -0
  5. package/build/index.js +1 -0
  6. package/build/services/auth-throttle.service.d.ts +2 -2
  7. package/build/services/auth-throttle.service.js +2 -2
  8. package/build/services/index.d.ts +1 -0
  9. package/build/services/index.js +1 -0
  10. package/build/services/password.service.d.ts +7 -5
  11. package/build/services/password.service.js +76 -18
  12. package/build/services/totp.service.d.ts +16 -0
  13. package/build/services/totp.service.js +96 -0
  14. package/build/session/session-handler.d.ts +1 -0
  15. package/build/session/session-handler.js +39 -6
  16. package/build/soap-auth.d.ts +13 -6
  17. package/build/soap-auth.js +132 -5
  18. package/build/strategies/api-key/api-key.strategy.d.ts +4 -4
  19. package/build/strategies/api-key/api-key.strategy.js +3 -2
  20. package/build/strategies/base-auth.strategy.d.ts +5 -4
  21. package/build/strategies/basic/basic.strategy.d.ts +2 -1
  22. package/build/strategies/basic/basic.strategy.js +1 -0
  23. package/build/strategies/credential-auth.strategy.d.ts +7 -7
  24. package/build/strategies/credential-auth.strategy.js +9 -14
  25. package/build/strategies/index.d.ts +1 -0
  26. package/build/strategies/index.js +1 -0
  27. package/build/strategies/jwt/jwt.strategy.d.ts +3 -1
  28. package/build/strategies/jwt/jwt.strategy.js +41 -9
  29. package/build/strategies/jwt/jwt.tools.js +16 -14
  30. package/build/strategies/local/local.strategy.d.ts +6 -3
  31. package/build/strategies/local/local.strategy.js +83 -2
  32. package/build/strategies/oauth2/hybrid.oauth2.strategy.d.ts +3 -3
  33. package/build/strategies/oauth2/hybrid.oauth2.strategy.js +1 -6
  34. package/build/strategies/oauth2/oauth2.errors.d.ts +1 -0
  35. package/build/strategies/oauth2/oauth2.errors.js +4 -0
  36. package/build/strategies/oauth2/oauth2.strategy.d.ts +6 -4
  37. package/build/strategies/oauth2/oauth2.strategy.js +114 -46
  38. package/build/strategies/oauth2/oauth2.tools.js +2 -2
  39. package/build/strategies/oauth2/oauth2.types.d.ts +2 -2
  40. package/build/strategies/oauth2/providers/facebook.strategy.d.ts +11 -0
  41. package/build/strategies/oauth2/providers/facebook.strategy.js +58 -0
  42. package/build/strategies/oauth2/providers/github.strategy.d.ts +11 -0
  43. package/build/strategies/oauth2/providers/github.strategy.js +56 -0
  44. package/build/strategies/oauth2/providers/google.strategy.d.ts +11 -0
  45. package/build/strategies/oauth2/providers/google.strategy.js +52 -0
  46. package/build/strategies/oauth2/providers/http-oauth2.strategy.d.ts +16 -0
  47. package/build/strategies/oauth2/providers/http-oauth2.strategy.js +49 -0
  48. package/build/strategies/oauth2/providers/index.d.ts +5 -0
  49. package/build/strategies/oauth2/providers/index.js +21 -0
  50. package/build/strategies/oauth2/providers/provider.types.d.ts +7 -0
  51. package/build/strategies/oauth2/providers/provider.types.js +2 -0
  52. package/build/strategies/token-auth.strategy.d.ts +4 -4
  53. package/build/strategies/token-auth.strategy.js +2 -3
  54. package/build/tools/tools.js +1 -2
  55. package/build/types.d.ts +31 -32
  56. package/build/utils/validation.d.ts +23 -0
  57. package/build/utils/validation.js +139 -0
  58. package/package.json +8 -7
  59. package/build/__tests__/soap-auth.test.d.ts +0 -1
  60. package/build/__tests__/soap-auth.test.js +0 -42
  61. package/build/services/__tests__/account-lock.service.test.d.ts +0 -1
  62. package/build/services/__tests__/account-lock.service.test.js +0 -55
  63. package/build/services/__tests__/auth-throttle.service.test.d.ts +0 -1
  64. package/build/services/__tests__/auth-throttle.service.test.js +0 -48
  65. package/build/services/__tests__/jwks.service.test.d.ts +0 -1
  66. package/build/services/__tests__/jwks.service.test.js +0 -39
  67. package/build/services/__tests__/mfa.service.test.d.ts +0 -1
  68. package/build/services/__tests__/mfa.service.test.js +0 -66
  69. package/build/services/__tests__/password.service.test.d.ts +0 -1
  70. package/build/services/__tests__/password.service.test.js +0 -66
  71. package/build/services/__tests__/pkce.service.test.d.ts +0 -1
  72. package/build/services/__tests__/pkce.service.test.js +0 -77
  73. package/build/services/__tests__/rate-limit.service.test.d.ts +0 -1
  74. package/build/services/__tests__/rate-limit.service.test.js +0 -37
  75. package/build/services/__tests__/role.service.test.d.ts +0 -1
  76. package/build/services/__tests__/role.service.test.js +0 -31
  77. package/build/session/__tests__/file.session-store.test.d.ts +0 -1
  78. package/build/session/__tests__/file.session-store.test.js +0 -117
  79. package/build/session/__tests__/memory.session-store.test.d.ts +0 -1
  80. package/build/session/__tests__/memory.session-store.test.js +0 -77
  81. package/build/session/__tests__/session-handler.test.d.ts +0 -1
  82. package/build/session/__tests__/session-handler.test.js +0 -337
  83. package/build/strategies/__tests__/base-auth.strategy.test.d.ts +0 -14
  84. package/build/strategies/__tests__/base-auth.strategy.test.js +0 -137
  85. package/build/strategies/__tests__/credential-auth.strategy.test.d.ts +0 -14
  86. package/build/strategies/__tests__/credential-auth.strategy.test.js +0 -265
  87. package/build/strategies/__tests__/token-auth.strategy.test.d.ts +0 -28
  88. package/build/strategies/__tests__/token-auth.strategy.test.js +0 -298
  89. package/build/strategies/api-key/__tests__/api-key.strategy.test.d.ts +0 -1
  90. package/build/strategies/api-key/__tests__/api-key.strategy.test.js +0 -103
  91. package/build/strategies/basic/__tests__/basic.strategy.test.d.ts +0 -1
  92. package/build/strategies/basic/__tests__/basic.strategy.test.js +0 -104
  93. package/build/strategies/jwt/__tests__/jwt.strategy.test.d.ts +0 -1
  94. package/build/strategies/jwt/__tests__/jwt.strategy.test.js +0 -156
  95. package/build/strategies/jwt/__tests__/jwt.tools.test.d.ts +0 -1
  96. package/build/strategies/jwt/__tests__/jwt.tools.test.js +0 -98
  97. package/build/strategies/local/__tests__/local.strategy.test.d.ts +0 -1
  98. package/build/strategies/local/__tests__/local.strategy.test.js +0 -115
@@ -1,11 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SoapAuth = void 0;
4
+ const validation_1 = require("./utils/validation");
5
+ const session_handler_1 = require("./session/session-handler");
6
+ const jwt_strategy_1 = require("./strategies/jwt/jwt.strategy");
7
+ const local_strategy_1 = require("./strategies/local/local.strategy");
8
+ const basic_strategy_1 = require("./strategies/basic/basic.strategy");
9
+ const api_key_strategy_1 = require("./strategies/api-key/api-key.strategy");
4
10
  class SoapAuth {
5
- requiredStrategyMethods = ["authenticate", "init"];
11
+ requiredStrategyMethods = ["authenticate"];
6
12
  strategies = new Map();
7
13
  logger;
8
14
  constructor(config) {
15
+ this.validateConfig(config);
9
16
  this.strategies.set("http", new Map());
10
17
  this.strategies.set("socket", new Map());
11
18
  this.strategies.set("event", new Map());
@@ -15,12 +22,83 @@ class SoapAuth {
15
22
  this.strategies.set("edge", new Map());
16
23
  this.logger = config.logger;
17
24
  }
25
+ validateConfig(config) {
26
+ try {
27
+ validation_1.ValidationUtils.required(config, "config");
28
+ if (config.logger) {
29
+ validation_1.ValidationUtils.object(config.logger, "config.logger");
30
+ }
31
+ if (config.session) {
32
+ this.validateSessionConfig(config.session);
33
+ }
34
+ if (config.jwt) {
35
+ this.validateJwtConfig(config.jwt);
36
+ }
37
+ if (config.http) {
38
+ this.validateHttpStrategies(config.http);
39
+ }
40
+ if (config.socket) {
41
+ this.validateSocketStrategies(config.socket);
42
+ }
43
+ }
44
+ catch (error) {
45
+ if (error instanceof validation_1.ValidationError) {
46
+ throw error;
47
+ }
48
+ throw new validation_1.ValidationError(`Invalid configuration: ${error.message}`);
49
+ }
50
+ }
51
+ validateSessionConfig(session) {
52
+ validation_1.ValidationUtils.required(session.secret, "session.secret");
53
+ validation_1.ValidationUtils.nonEmptyString(session.secret, "session.secret");
54
+ if (session.sessionKey) {
55
+ validation_1.ValidationUtils.nonEmptyString(session.sessionKey, "session.sessionKey");
56
+ }
57
+ if (session.sessionHeader) {
58
+ validation_1.ValidationUtils.nonEmptyString(session.sessionHeader, "session.sessionHeader");
59
+ }
60
+ }
61
+ validateJwtConfig(jwt) {
62
+ if (jwt.accessToken) {
63
+ validation_1.ValidationUtils.required(jwt.accessToken.issuer, "jwt.accessToken.issuer");
64
+ validation_1.ValidationUtils.required(jwt.accessToken.issuer.secretKey, "jwt.accessToken.issuer.secretKey");
65
+ validation_1.ValidationUtils.nonEmptyString(jwt.accessToken.issuer.secretKey, "jwt.accessToken.issuer.secretKey");
66
+ }
67
+ if (jwt.refreshToken) {
68
+ validation_1.ValidationUtils.required(jwt.refreshToken.issuer, "jwt.refreshToken.issuer");
69
+ validation_1.ValidationUtils.required(jwt.refreshToken.issuer.secretKey, "jwt.refreshToken.issuer.secretKey");
70
+ validation_1.ValidationUtils.nonEmptyString(jwt.refreshToken.issuer.secretKey, "jwt.refreshToken.issuer.secretKey");
71
+ }
72
+ }
73
+ validateHttpStrategies(http) {
74
+ validation_1.ValidationUtils.object(http, "http");
75
+ if (http.custom) {
76
+ validation_1.ValidationUtils.object(http.custom, "http.custom");
77
+ for (const [name, strategy] of Object.entries(http.custom)) {
78
+ validation_1.ValidationUtils.required(strategy, `http.custom.${name}`);
79
+ validation_1.ValidationUtils.object(strategy, `http.custom.${name}`);
80
+ }
81
+ }
82
+ }
83
+ validateSocketStrategies(socket) {
84
+ validation_1.ValidationUtils.object(socket, "socket");
85
+ if (socket.custom) {
86
+ validation_1.ValidationUtils.object(socket.custom, "socket.custom");
87
+ for (const [name, strategy] of Object.entries(socket.custom)) {
88
+ validation_1.ValidationUtils.required(strategy, `socket.custom.${name}`);
89
+ validation_1.ValidationUtils.object(strategy, `socket.custom.${name}`);
90
+ }
91
+ }
92
+ }
18
93
  isAuthStrategy(strategy) {
19
94
  return (typeof strategy === "object" &&
20
95
  strategy !== null &&
21
96
  this.requiredStrategyMethods.every((method) => typeof strategy[method] === "function"));
22
97
  }
23
98
  addStrategy(strategyInstance, name, type) {
99
+ validation_1.ValidationUtils.required(strategyInstance, "strategyInstance");
100
+ validation_1.ValidationUtils.nonEmptyString(name, "name");
101
+ validation_1.ValidationUtils.oneOf(type, "type", ["http", "socket", "event", "isa", "webhook", "grpc", "edge"]);
24
102
  if (!this.strategies.has(type)) {
25
103
  throw new Error(`Invalid strategy type "${type}".`);
26
104
  }
@@ -33,21 +111,28 @@ class SoapAuth {
33
111
  }
34
112
  }
35
113
  removeStrategy(name, type) {
114
+ validation_1.ValidationUtils.required(name, "name");
115
+ validation_1.ValidationUtils.oneOf(type, "type", ["http", "socket", "event", "isa", "webhook", "grpc", "edge"]);
36
116
  if (!this.strategies.has(type)) {
37
117
  throw new Error(`Invalid strategy type "${type}".`);
38
118
  }
39
119
  const names = Array.isArray(name) ? name : [name];
40
120
  names.forEach((n) => {
121
+ validation_1.ValidationUtils.nonEmptyString(n, "strategy name");
41
122
  this.strategies.get(type).delete(n);
42
123
  });
43
124
  }
44
125
  hasStrategy(name, type) {
126
+ validation_1.ValidationUtils.nonEmptyString(name, "name");
127
+ validation_1.ValidationUtils.oneOf(type, "type", ["http", "socket", "event", "isa", "webhook", "grpc", "edge"]);
45
128
  if (!this.strategies.has(type)) {
46
129
  throw new Error(`Invalid strategy type "${type}".`);
47
130
  }
48
131
  return this.strategies.get(type).has(name);
49
132
  }
50
133
  getStrategy(name, type) {
134
+ validation_1.ValidationUtils.nonEmptyString(name, "name");
135
+ validation_1.ValidationUtils.oneOf(type, "type", ["http", "socket", "event", "isa", "webhook", "grpc", "edge"]);
51
136
  if (!this.strategies.has(type)) {
52
137
  throw new Error(`Invalid strategy type "${type}".`);
53
138
  }
@@ -101,7 +186,7 @@ class SoapAuth {
101
186
  if (sequential) {
102
187
  for (const strategy of strategies) {
103
188
  try {
104
- await strategy.init();
189
+ await strategy.init?.();
105
190
  }
106
191
  catch (error) {
107
192
  this.logger?.error(`Failed to initialize strategy: ${error.message}`);
@@ -109,10 +194,52 @@ class SoapAuth {
109
194
  }
110
195
  }
111
196
  else {
112
- await Promise.all(strategies.map((strategy) => strategy
113
- .init()
114
- .catch((error) => this.logger?.error(`Failed to initialize strategy: ${error.message}`))));
197
+ await Promise.all(strategies.map((strategy) => Promise.resolve(strategy.init?.()).catch((error) => this.logger?.error(`Failed to initialize strategy: ${error.message}`))));
198
+ }
199
+ }
200
+ static async create(config) {
201
+ const auth = new SoapAuth(config);
202
+ const logger = config.logger;
203
+ const sessionHandler = config.session
204
+ ? new session_handler_1.SessionHandler(config.session, logger)
205
+ : undefined;
206
+ if (config.http) {
207
+ const sharedJwt = config.http.jwt
208
+ ? new jwt_strategy_1.JwtStrategy(config.http.jwt, logger)
209
+ : undefined;
210
+ if (config.http.local) {
211
+ auth.addStrategy(new local_strategy_1.LocalStrategy(config.http.local, sessionHandler, sharedJwt, logger), "local", "http");
212
+ }
213
+ if (config.http.basic) {
214
+ auth.addStrategy(new basic_strategy_1.BasicStrategy(config.http.basic, sessionHandler, sharedJwt, logger), "basic", "http");
215
+ }
216
+ if (config.http.apiKey) {
217
+ auth.addStrategy(new api_key_strategy_1.ApiKeyStrategy(config.http.apiKey, logger), "api-key", "http");
218
+ }
219
+ if (sharedJwt) {
220
+ auth.addStrategy(sharedJwt, "jwt", "http");
221
+ }
222
+ if (config.http.custom) {
223
+ for (const [name, strategy] of Object.entries(config.http.custom)) {
224
+ auth.addStrategy(strategy, name, "http");
225
+ }
226
+ }
227
+ }
228
+ if (config.socket) {
229
+ if (config.socket.jwt) {
230
+ auth.addStrategy(new jwt_strategy_1.JwtStrategy(config.socket.jwt, logger), "jwt", "socket");
231
+ }
232
+ if (config.socket.apiKey) {
233
+ auth.addStrategy(new api_key_strategy_1.ApiKeyStrategy(config.socket.apiKey, logger), "api-key", "socket");
234
+ }
235
+ if (config.socket.custom) {
236
+ for (const [name, strategy] of Object.entries(config.socket.custom)) {
237
+ auth.addStrategy(strategy, name, "socket");
238
+ }
239
+ }
115
240
  }
241
+ await auth.init();
242
+ return auth;
116
243
  }
117
244
  }
118
245
  exports.SoapAuth = SoapAuth;
@@ -1,17 +1,17 @@
1
1
  import * as Soap from "@soapjs/soap";
2
- import { AuthResult, AuthStrategy } from "../../types";
3
2
  import { ApiKeyStrategyConfig } from "./api-key.types";
4
3
  import { BaseAuthStrategy } from "../base-auth.strategy";
5
- export declare class ApiKeyStrategy<TContext = unknown, TUser = unknown> extends BaseAuthStrategy<TContext, TUser> implements AuthStrategy<TContext, TUser> {
4
+ export declare class ApiKeyStrategy<TContext = Soap.HttpContext, TUser extends Soap.AuthUser = Soap.AuthUser> extends BaseAuthStrategy<TContext, TUser> {
6
5
  protected config: ApiKeyStrategyConfig<TContext, TUser>;
6
+ readonly name = "api-key";
7
7
  protected apiKeyValidity: {
8
8
  sessionDuration: number;
9
9
  longTermDuration: number;
10
10
  };
11
- constructor(config: ApiKeyStrategyConfig<TContext, TUser>, logger: Soap.Logger);
11
+ constructor(config: ApiKeyStrategyConfig<TContext, TUser>, logger?: Soap.Logger);
12
12
  protected fetchUser(apiKey: string, context: TContext): Promise<TUser | null>;
13
13
  init(): Promise<void>;
14
- authenticate(context?: TContext): Promise<AuthResult<TUser>>;
14
+ authenticate(context?: TContext): Promise<Soap.AuthResult<TUser> | null>;
15
15
  authorize(user: TUser, action: string, resource?: string): Promise<boolean>;
16
16
  revoke(apiKey: string): Promise<void>;
17
17
  private trackApiKeyUsage;
@@ -7,6 +7,7 @@ const base_auth_strategy_1 = require("../base-auth.strategy");
7
7
  const api_key_tools_1 = require("./api-key.tools");
8
8
  class ApiKeyStrategy extends base_auth_strategy_1.BaseAuthStrategy {
9
9
  config;
10
+ name = "api-key";
10
11
  apiKeyValidity;
11
12
  constructor(config, logger) {
12
13
  super((0, api_key_tools_1.prepareApiKeyConfig)(config), null, logger);
@@ -28,7 +29,7 @@ class ApiKeyStrategy extends base_auth_strategy_1.BaseAuthStrategy {
28
29
  return user;
29
30
  }
30
31
  catch (error) {
31
- this.logger.warn(`Attempt ${attempt + 1} failed: ${error}`);
32
+ this.logger?.warn(`Attempt ${attempt + 1} failed: ${error}`);
32
33
  if (attempt < maxRetries) {
33
34
  await new Promise((resolve) => setTimeout(resolve, retryDelay));
34
35
  }
@@ -99,7 +100,7 @@ class ApiKeyStrategy extends base_auth_strategy_1.BaseAuthStrategy {
99
100
  await this.config.trackApiKeyUsage?.(apiKey);
100
101
  }
101
102
  catch (error) {
102
- this.logger.warn("Failed to track API key usage:", error);
103
+ this.logger?.warn("Failed to track API key usage:", error);
103
104
  }
104
105
  }
105
106
  }
@@ -1,12 +1,12 @@
1
1
  import * as Soap from "@soapjs/soap";
2
- import { AuthFailureContext, AuthResult, AuthStrategy, AuthSuccessContext, BaseAuthStrategyConfig } from "../types";
2
+ import { AuthFailureContext, AuthSuccessContext, BaseAuthStrategyConfig } from "../types";
3
3
  import { SessionHandler } from "../session/session-handler";
4
4
  import { AccountLockService } from "../services/account-lock.service";
5
5
  import { MfaService } from "../services/mfa.service";
6
6
  import { RateLimitService } from "../services/rate-limit.service";
7
7
  import { RoleService } from "../services/role.service";
8
8
  import { AuthThrottleService } from "../services/auth-throttle.service";
9
- export declare abstract class BaseAuthStrategy<TContext = unknown, TUser = unknown> implements AuthStrategy<TContext, TUser> {
9
+ export declare abstract class BaseAuthStrategy<TContext = Soap.HttpContext, TUser extends Soap.AuthUser = Soap.AuthUser> {
10
10
  protected config: BaseAuthStrategyConfig<TContext, TUser>;
11
11
  protected session?: SessionHandler;
12
12
  protected logger?: Soap.Logger;
@@ -15,10 +15,11 @@ export declare abstract class BaseAuthStrategy<TContext = unknown, TUser = unkno
15
15
  protected rateLimit: RateLimitService;
16
16
  protected role: RoleService<TUser>;
17
17
  protected throttle: AuthThrottleService;
18
- abstract authenticate(context?: TContext): Promise<AuthResult<TUser>>;
18
+ abstract readonly name: string;
19
+ abstract authenticate(ctx: TContext): Promise<Soap.AuthResult<TUser> | null>;
19
20
  constructor(config: BaseAuthStrategyConfig<TContext, TUser>, session?: SessionHandler, logger?: Soap.Logger);
20
21
  init(): Promise<void>;
21
22
  protected onSuccess(action: string, context: AuthSuccessContext<TUser, TContext>): Promise<void>;
22
23
  protected onFailure(action: string, context: AuthFailureContext<TContext>): Promise<void>;
23
- protected authenticateWithSession(context: TContext): Promise<AuthResult<TUser>>;
24
+ protected authenticateWithSession(context: TContext): Promise<Soap.AuthResult<TUser>>;
24
25
  }
@@ -3,11 +3,12 @@ import { CredentialAuthStrategy } from "../credential-auth.strategy";
3
3
  import { BasicStrategyConfig } from "./basic.types";
4
4
  import { SessionHandler } from "../../session/session-handler";
5
5
  import { JwtStrategy } from "../jwt/jwt.strategy";
6
- export declare class BasicStrategy<TContext = unknown, TUser = unknown> extends CredentialAuthStrategy<TContext, TUser> {
6
+ export declare class BasicStrategy<TContext = Soap.HttpContext, TUser extends Soap.AuthUser = Soap.AuthUser> extends CredentialAuthStrategy<TContext, TUser> {
7
7
  protected config: BasicStrategyConfig<TContext, TUser>;
8
8
  protected session?: SessionHandler;
9
9
  protected jwt?: JwtStrategy<TContext, TUser>;
10
10
  protected logger?: Soap.Logger;
11
+ readonly name = "basic";
11
12
  constructor(config: BasicStrategyConfig<TContext, TUser>, session?: SessionHandler, jwt?: JwtStrategy<TContext, TUser>, logger?: Soap.Logger);
12
13
  protected extractCredentials(context?: TContext): {
13
14
  identifier: string;
@@ -9,6 +9,7 @@ class BasicStrategy extends credential_auth_strategy_1.CredentialAuthStrategy {
9
9
  session;
10
10
  jwt;
11
11
  logger;
12
+ name = "basic";
12
13
  constructor(config, session, jwt, logger) {
13
14
  super((0, basic_tools_1.prepareBasicConfig)(config), session, jwt, logger);
14
15
  this.config = config;
@@ -1,10 +1,10 @@
1
1
  import * as Soap from "@soapjs/soap";
2
- import { AuthResult, CredentialAuthStrategyConfig } from "../types";
2
+ import { CredentialAuthStrategyConfig, NewPasswordOptions } from "../types";
3
3
  import { BaseAuthStrategy } from "./base-auth.strategy";
4
4
  import { SessionHandler } from "../session/session-handler";
5
5
  import { JwtStrategy } from "./jwt/jwt.strategy";
6
6
  import { PasswordService } from "../services/password.service";
7
- export declare abstract class CredentialAuthStrategy<TContext = unknown, TUser = unknown> extends BaseAuthStrategy<TContext, TUser> {
7
+ export declare abstract class CredentialAuthStrategy<TContext = Soap.HttpContext, TUser extends Soap.AuthUser = Soap.AuthUser> extends BaseAuthStrategy<TContext, TUser> {
8
8
  protected config: CredentialAuthStrategyConfig<TContext, TUser>;
9
9
  protected session?: SessionHandler;
10
10
  protected jwt?: JwtStrategy<TContext, TUser>;
@@ -14,10 +14,10 @@ export declare abstract class CredentialAuthStrategy<TContext = unknown, TUser =
14
14
  protected abstract extractCredentials(context: TContext): any;
15
15
  constructor(config: CredentialAuthStrategyConfig<TContext, TUser>, session?: SessionHandler, jwt?: JwtStrategy<TContext, TUser>, logger?: Soap.Logger);
16
16
  protected fetchUser(payload: unknown): Promise<TUser | null>;
17
- authenticate(context: TContext): Promise<AuthResult<TUser>>;
18
- login(context: TContext): Promise<AuthResult<TUser>>;
17
+ authenticate(context: TContext): Promise<Soap.AuthResult<TUser> | null>;
18
+ login(context: TContext): Promise<Soap.AuthResult<TUser>>;
19
19
  logout(context: TContext): Promise<void>;
20
- requestPasswordReset(identifier: string, email?: string): Promise<void>;
21
- resetPassword(identifier: string, token: string, newPassword: string): Promise<void>;
22
- changePassword(identifier: string, oldPassword: string, newPassword: string): Promise<void>;
20
+ requestPasswordResetLink(identifier: string, email?: string): Promise<void>;
21
+ resetPasswordWithToken(identifier: string, token: string, newPassword: string, passwordOptions?: NewPasswordOptions): Promise<void>;
22
+ replacePassword(identifier: string, oldPassword: string, newPassword: string, options?: NewPasswordOptions): Promise<void>;
23
23
  }
@@ -126,7 +126,7 @@ class CredentialAuthStrategy extends base_auth_strategy_1.BaseAuthStrategy {
126
126
  throw error;
127
127
  }
128
128
  }
129
- async requestPasswordReset(identifier, email) {
129
+ async requestPasswordResetLink(identifier, email) {
130
130
  try {
131
131
  const token = await this.password.generateResetToken(identifier);
132
132
  if (email) {
@@ -136,7 +136,7 @@ class CredentialAuthStrategy extends base_auth_strategy_1.BaseAuthStrategy {
136
136
  identifier,
137
137
  tokens: { reset: token },
138
138
  });
139
- this.logger.info(`Password reset requested for identifier: ${identifier}`);
139
+ this.logger?.info(`Password reset requested for identifier: ${identifier}`);
140
140
  }
141
141
  catch (error) {
142
142
  await this.onFailure("request_password_reset", {
@@ -147,17 +147,12 @@ class CredentialAuthStrategy extends base_auth_strategy_1.BaseAuthStrategy {
147
147
  throw error;
148
148
  }
149
149
  }
150
- async resetPassword(identifier, token, newPassword) {
150
+ async resetPasswordWithToken(identifier, token, newPassword, passwordOptions) {
151
151
  try {
152
- if (!this.password?.validateResetToken) {
153
- throw new Soap.NotImplementedError("validateResetToken");
154
- }
155
- if ((await this.password.validateResetToken(token)) === false) {
156
- throw new errors_1.ExpiredResetTokenError();
157
- }
158
- await this.password.updatePassword(identifier, newPassword);
152
+ await this.password?.validateResetToken(token);
153
+ await this.password.updatePassword(identifier, newPassword, passwordOptions);
159
154
  await this.onSuccess("password_reset", { identifier });
160
- this.logger.info(`Password successfully reset for identifier: ${identifier}`);
155
+ this.logger?.info(`Password successfully reset for identifier: ${identifier}`);
161
156
  }
162
157
  catch (error) {
163
158
  await this.onFailure("password_reset", {
@@ -168,14 +163,14 @@ class CredentialAuthStrategy extends base_auth_strategy_1.BaseAuthStrategy {
168
163
  throw error;
169
164
  }
170
165
  }
171
- async changePassword(identifier, oldPassword, newPassword) {
166
+ async replacePassword(identifier, oldPassword, newPassword, options) {
172
167
  try {
173
168
  if (!(await this.verifyCredentials(identifier, oldPassword))) {
174
169
  throw new errors_1.InvalidCredentialsError();
175
170
  }
176
- await this.password.updatePassword(identifier, newPassword);
171
+ await this.password.updatePassword(identifier, newPassword, options);
177
172
  await this.onSuccess("change_password", { identifier });
178
- this.logger.info(`Password changed successfully for identifier: ${identifier}`);
173
+ this.logger?.info(`Password changed successfully for identifier: ${identifier}`);
179
174
  }
180
175
  catch (error) {
181
176
  await this.onFailure("change_password", {
@@ -13,4 +13,5 @@ export * from "./local/local.types";
13
13
  export * from "./oauth2/oauth2.strategy";
14
14
  export * from "./oauth2/oauth2.tools";
15
15
  export * from "./oauth2/oauth2.types";
16
+ export * from "./oauth2/providers";
16
17
  export * from "./token-auth.strategy";
@@ -29,4 +29,5 @@ __exportStar(require("./local/local.types"), exports);
29
29
  __exportStar(require("./oauth2/oauth2.strategy"), exports);
30
30
  __exportStar(require("./oauth2/oauth2.tools"), exports);
31
31
  __exportStar(require("./oauth2/oauth2.types"), exports);
32
+ __exportStar(require("./oauth2/providers"), exports);
32
33
  __exportStar(require("./token-auth.strategy"), exports);
@@ -1,12 +1,14 @@
1
1
  import * as Soap from "@soapjs/soap";
2
2
  import { TokenAuthStrategy } from "../token-auth.strategy";
3
3
  import { TokenAuthStrategyConfig, TokenConfig } from "../../types";
4
- export declare class JwtStrategy<TContext = unknown, TUser = unknown> extends TokenAuthStrategy<TContext, TUser> {
4
+ export declare class JwtStrategy<TContext = Soap.HttpContext, TUser extends Soap.AuthUser = Soap.AuthUser> extends TokenAuthStrategy<TContext, TUser> {
5
5
  protected config: TokenAuthStrategyConfig<TContext, TUser>;
6
6
  protected logger?: Soap.Logger;
7
+ readonly name = "jwt";
7
8
  protected accessTokenConfig: TokenConfig<TContext>;
8
9
  protected refreshTokenConfig: TokenConfig<TContext>;
9
10
  constructor(config: TokenAuthStrategyConfig<TContext, TUser>, logger?: Soap.Logger);
11
+ private static validateConfig;
10
12
  protected verifyAccessToken(token: string): Promise<any>;
11
13
  protected verifyRefreshToken(token: string): Promise<any>;
12
14
  protected generateAccessToken(user: TUser, context: TContext): Promise<string>;
@@ -8,12 +8,15 @@ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
8
8
  const token_auth_strategy_1 = require("../token-auth.strategy");
9
9
  const errors_1 = require("../../errors");
10
10
  const jwt_tools_1 = require("./jwt.tools");
11
+ const validation_1 = require("../../utils/validation");
11
12
  class JwtStrategy extends token_auth_strategy_1.TokenAuthStrategy {
12
13
  config;
13
14
  logger;
15
+ name = "jwt";
14
16
  accessTokenConfig;
15
17
  refreshTokenConfig;
16
18
  constructor(config, logger) {
19
+ JwtStrategy.validateConfig(config);
17
20
  if (!config.accessToken.issuer.secretKey) {
18
21
  throw new errors_1.UndefinedTokenSecretError("Access");
19
22
  }
@@ -24,13 +27,39 @@ class JwtStrategy extends token_auth_strategy_1.TokenAuthStrategy {
24
27
  this.config = config;
25
28
  this.logger = logger;
26
29
  this.accessTokenConfig = jwt_tools_1.JwtTools.prepareAccessTokenConfig(config.accessToken);
27
- this.refreshTokenConfig = jwt_tools_1.JwtTools.prepareRefreshTokenConfig(config.refreshToken);
30
+ if (config.refreshToken) {
31
+ this.refreshTokenConfig = jwt_tools_1.JwtTools.prepareRefreshTokenConfig(config.refreshToken);
32
+ }
28
33
  this.logger?.info("JWTStrategy initialized with provided configurations.");
29
34
  }
35
+ static validateConfig(config) {
36
+ try {
37
+ validation_1.ValidationUtils.required(config, "config");
38
+ validation_1.ValidationUtils.required(config.accessToken, "config.accessToken");
39
+ validation_1.ValidationUtils.required(config.accessToken.issuer, "config.accessToken.issuer");
40
+ validation_1.ValidationUtils.required(config.accessToken.issuer.secretKey, "config.accessToken.issuer.secretKey");
41
+ validation_1.ValidationUtils.nonEmptyString(config.accessToken.issuer.secretKey, "config.accessToken.issuer.secretKey");
42
+ if (config.refreshToken) {
43
+ validation_1.ValidationUtils.required(config.refreshToken.issuer, "config.refreshToken.issuer");
44
+ validation_1.ValidationUtils.required(config.refreshToken.issuer.secretKey, "config.refreshToken.issuer.secretKey");
45
+ validation_1.ValidationUtils.nonEmptyString(config.refreshToken.issuer.secretKey, "config.refreshToken.issuer.secretKey");
46
+ }
47
+ if (config.user) {
48
+ validation_1.ValidationUtils.required(config.user.fetchUser, "config.user.fetchUser");
49
+ validation_1.ValidationUtils.function(config.user.fetchUser, "config.user.fetchUser");
50
+ }
51
+ }
52
+ catch (error) {
53
+ if (error instanceof validation_1.ValidationError) {
54
+ throw error;
55
+ }
56
+ throw new validation_1.ValidationError(`Invalid JWT configuration: ${error.message}`);
57
+ }
58
+ }
30
59
  verifyAccessToken(token) {
31
60
  try {
32
- if (!token)
33
- throw new errors_1.UndefinedTokenError("Access");
61
+ validation_1.ValidationUtils.required(token, "token");
62
+ validation_1.ValidationUtils.jwtToken(token, "token");
34
63
  if (!this.accessTokenConfig.issuer.secretKey)
35
64
  throw new errors_1.UndefinedTokenSecretError("Access");
36
65
  return new Promise((resolve, reject) => {
@@ -49,8 +78,8 @@ class JwtStrategy extends token_auth_strategy_1.TokenAuthStrategy {
49
78
  }
50
79
  verifyRefreshToken(token) {
51
80
  try {
52
- if (!token)
53
- throw new errors_1.UndefinedTokenError("Refresh");
81
+ validation_1.ValidationUtils.required(token, "token");
82
+ validation_1.ValidationUtils.jwtToken(token, "token");
54
83
  if (!this.refreshTokenConfig.issuer.secretKey)
55
84
  throw new errors_1.UndefinedTokenSecretError("Refresh");
56
85
  return new Promise((resolve, reject) => {
@@ -64,7 +93,7 @@ class JwtStrategy extends token_auth_strategy_1.TokenAuthStrategy {
64
93
  }
65
94
  catch (error) {
66
95
  this.logger?.error("JWT verification failed:", error);
67
- error;
96
+ throw error;
68
97
  }
69
98
  }
70
99
  async generateAccessToken(user, context) {
@@ -76,12 +105,12 @@ class JwtStrategy extends token_auth_strategy_1.TokenAuthStrategy {
76
105
  return Promise.resolve(jwt_tools_1.JwtTools.generateRefreshToken(payload, this.refreshTokenConfig));
77
106
  }
78
107
  async storeAccessToken(token) {
79
- if (this.accessTokenConfig.persistence.store) {
108
+ if (this.accessTokenConfig.persistence?.store) {
80
109
  await this.accessTokenConfig.persistence.store(token, null, this.accessTokenConfig.issuer.options.expiresIn);
81
110
  }
82
111
  }
83
112
  async storeRefreshToken(token) {
84
- if (this.refreshTokenConfig.persistence.store) {
113
+ if (this.refreshTokenConfig?.persistence?.store) {
85
114
  await this.refreshTokenConfig.persistence.store(token, null, this.refreshTokenConfig.issuer.options.expiresIn);
86
115
  }
87
116
  }
@@ -112,6 +141,9 @@ class JwtStrategy extends token_auth_strategy_1.TokenAuthStrategy {
112
141
  }
113
142
  }
114
143
  extractRefreshToken(context) {
144
+ if (!this.refreshTokenConfig) {
145
+ return undefined;
146
+ }
115
147
  if (this.refreshTokenConfig.extract) {
116
148
  return this.refreshTokenConfig.extract(context);
117
149
  }
@@ -132,7 +164,7 @@ class JwtStrategy extends token_auth_strategy_1.TokenAuthStrategy {
132
164
  async invalidateRefreshToken(token, context) {
133
165
  const refreshToken = token || (await this.extractRefreshToken(context));
134
166
  if (refreshToken) {
135
- await this.refreshTokenConfig.persistence?.remove?.(refreshToken);
167
+ await this.refreshTokenConfig?.persistence?.remove?.(refreshToken);
136
168
  if (context) {
137
169
  jwt_tools_1.JwtTools.clearDefaultJwtCookie(context);
138
170
  jwt_tools_1.JwtTools.clearDefaultJwtHeader(context);
@@ -88,6 +88,7 @@ class JwtTools {
88
88
  return context.req.cookies?.refreshToken;
89
89
  }
90
90
  static prepareAccessTokenConfig = (config) => {
91
+ const verifierOptions = config.verifier?.options ?? {};
91
92
  return Soap.removeUndefinedProperties({
92
93
  ...config,
93
94
  issuer: {
@@ -101,14 +102,15 @@ class JwtTools {
101
102
  verifier: {
102
103
  ...config.verifier,
103
104
  options: {
104
- ...config.verifier.options,
105
- algorithms: config.verifier.options.algorithms || ["HS256"],
106
- expiresIn: config.verifier.options.expiresIn || "1h",
105
+ ...verifierOptions,
106
+ algorithms: verifierOptions.algorithms || ["HS256"],
107
+ expiresIn: verifierOptions.expiresIn || "1h",
107
108
  },
108
109
  },
109
110
  });
110
111
  };
111
112
  static prepareRefreshTokenConfig = (config) => {
113
+ const verifierOptions = config.verifier?.options ?? {};
112
114
  return Soap.removeUndefinedProperties({
113
115
  ...config,
114
116
  issuer: {
@@ -122,9 +124,9 @@ class JwtTools {
122
124
  verifier: {
123
125
  ...config.verifier,
124
126
  options: {
125
- ...config.verifier.options,
126
- algorithms: config.verifier.options.algorithms || ["HS256"],
127
- expiresIn: config.verifier.options.expiresIn || "7d",
127
+ ...verifierOptions,
128
+ algorithms: verifierOptions.algorithms || ["HS256"],
129
+ expiresIn: verifierOptions.expiresIn || "7d",
128
130
  },
129
131
  },
130
132
  });
@@ -189,6 +191,14 @@ exports.JwtTools = JwtTools;
189
191
  const prepareJwtConfig = (config) => {
190
192
  return Soap.removeUndefinedProperties({
191
193
  ...config,
194
+ user: {
195
+ ...config.user,
196
+ validateUser: config.user?.validateUser ?? (() => Promise.resolve(true)),
197
+ },
198
+ accessToken: JwtTools.prepareAccessTokenConfig(config.accessToken),
199
+ refreshToken: config.refreshToken
200
+ ? JwtTools.prepareRefreshTokenConfig(config.refreshToken)
201
+ : undefined,
192
202
  routes: {
193
203
  login: config.routes?.login ?? {
194
204
  path: "/auth/jwt/login",
@@ -203,14 +213,6 @@ const prepareJwtConfig = (config) => {
203
213
  method: "POST",
204
214
  },
205
215
  ...config.routes,
206
- user: {
207
- ...config.user,
208
- validateUser: config.user?.validateUser ?? (() => Promise.resolve(true)),
209
- },
210
- accessToken: JwtTools.prepareAccessTokenConfig(config.accessToken),
211
- refreshToken: config.refreshToken
212
- ? JwtTools.prepareRefreshTokenConfig(config.refreshToken)
213
- : undefined,
214
216
  },
215
217
  });
216
218
  };
@@ -3,18 +3,21 @@ import { CredentialAuthStrategy } from "../credential-auth.strategy";
3
3
  import { LocalStrategyConfig } from "./local.types";
4
4
  import { SessionHandler } from "../../session/session-handler";
5
5
  import { JwtStrategy } from "../jwt/jwt.strategy";
6
- export declare class LocalStrategy<TContext = unknown, TUser = unknown> extends CredentialAuthStrategy<TContext, TUser> {
6
+ export declare class LocalStrategy<TContext = Soap.HttpContext, TUser extends Soap.AuthUser = Soap.AuthUser> extends CredentialAuthStrategy<TContext, TUser> {
7
7
  protected session?: SessionHandler;
8
8
  protected jwt?: JwtStrategy<TContext, TUser>;
9
9
  protected logger?: Soap.Logger;
10
+ readonly name = "local";
10
11
  constructor(config: LocalStrategyConfig<TContext, TUser>, session?: SessionHandler, jwt?: JwtStrategy<TContext, TUser>, logger?: Soap.Logger);
12
+ private static validateConfig;
11
13
  protected extractCredentials(context?: TContext): Promise<{
12
14
  identifier: string;
13
15
  password: string;
14
16
  }>;
15
17
  protected verifyCredentials(identifier: string, password: string): Promise<boolean>;
16
- protected fetchUser(credentials: {
18
+ protected fetchUser(identifierOrCredentials: string | {
17
19
  identifier: string;
18
- password: string;
20
+ password?: string;
19
21
  }): Promise<TUser | null>;
22
+ changePassword(context: TContext): Promise<void>;
20
23
  }