@soapjs/soap-auth 0.1.0 → 0.1.1

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.
@@ -6,7 +6,6 @@ const api_key_strategy_1 = require("../strategies/api-key/api-key.strategy");
6
6
  const jwt_strategy_1 = require("../strategies/jwt/jwt.strategy");
7
7
  const basic_strategy_1 = require("../strategies/basic/basic.strategy");
8
8
  const auth_strategy_factory_1 = require("./auth-strategy.factory");
9
- const tools_1 = require("../tools/tools");
10
9
  const local_strategy_1 = require("../strategies/local/local.strategy");
11
10
  class HttpAuthStrategyFactory extends auth_strategy_factory_1.AuthStrategyFactory {
12
11
  createStrategies(config) {
@@ -16,7 +15,7 @@ class HttpAuthStrategyFactory extends auth_strategy_factory_1.AuthStrategyFactor
16
15
  }
17
16
  if (config.http.oauth2) {
18
17
  for (const provider in config.http.oauth2) {
19
- strategies.set(provider, new oauth2_strategy_1.OAuth2Strategy(config.http.oauth2[provider], (0, tools_1.resolveConfig)(config.http.oauth2[provider].tokens.access, config.tokens.access), (0, tools_1.resolveConfig)(config.http.oauth2[provider].tokens.refresh, config.tokens.refresh), this.getSessionHandler(config.http.oauth2[provider].session, config.session), config.logger));
18
+ strategies.set(provider, new oauth2_strategy_1.OAuth2Strategy(config.http.oauth2[provider], config.http.oauth2[provider].accessToken, config.http.oauth2[provider].refreshToken, this.getSessionHandler(config.http.oauth2[provider].session, config.session), config.logger));
20
19
  }
21
20
  }
22
21
  if (config.http.apiKey) {
@@ -15,14 +15,14 @@ class BaseAuthStrategy {
15
15
  return Promise.resolve();
16
16
  }
17
17
  async isAccountLocked(account, ...args) {
18
- if (await this.config.isAccountLocked?.(account, ...args)) {
18
+ if (await this.config.lock.isAccountLocked?.(account, ...args)) {
19
19
  throw new errors_1.AccountLockedError();
20
20
  }
21
21
  return false;
22
22
  }
23
23
  async isAuthorized(user) {
24
- if (this.config.authorizeByRoles && this.config.roles) {
25
- const hasAccess = await this.config.authorizeByRoles(user, this.config.roles);
24
+ if (this.config.role.authorizeByRoles && this.config.role.roles) {
25
+ const hasAccess = await this.config.role.authorizeByRoles(user, this.config.role.roles);
26
26
  if (!hasAccess) {
27
27
  throw new errors_1.UnauthorizedRoleError();
28
28
  }
@@ -30,8 +30,8 @@ class BaseAuthStrategy {
30
30
  return true;
31
31
  }
32
32
  async checkRateLimit(data) {
33
- if (this.config.checkRateLimit &&
34
- (await this.config.checkRateLimit(data))) {
33
+ if (this.config.rateLimit.checkRateLimit &&
34
+ (await this.config.rateLimit.checkRateLimit(data))) {
35
35
  throw new errors_1.RateLimitExceededError();
36
36
  }
37
37
  }
@@ -152,7 +152,7 @@ class CredentialBasedAuthStrategy extends base_auth_strategy_1.BaseAuthStrategy
152
152
  }
153
153
  }
154
154
  async isAccountLocked(account, ...args) {
155
- if (await this.config.isAccountLocked?.(account, ...args)) {
155
+ if (await this.config.lock.isAccountLocked?.(account, ...args)) {
156
156
  throw new errors_1.AccountLockedError();
157
157
  }
158
158
  if (typeof account === "string" && this.config.security?.lockoutDuration) {
@@ -5,20 +5,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.JwtStrategy = void 0;
7
7
  const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
8
- const util_1 = require("util");
9
8
  const token_based_auth_strategy_1 = require("../token-based-auth.strategy");
10
9
  const errors_1 = require("../../errors");
11
10
  const jwt_tools_1 = require("./jwt.tools");
12
- const verifyAsync = (0, util_1.promisify)(jsonwebtoken_1.default.verify);
13
11
  class JwtStrategy extends token_based_auth_strategy_1.TokenBasedAuthStrategy {
14
12
  config;
15
13
  session;
16
14
  logger;
17
15
  constructor(config, session, logger) {
18
- if (!config.access.secretKey) {
16
+ if (!config.accessToken.secretKey) {
19
17
  throw new errors_1.UndefinedTokenSecretError("Access");
20
18
  }
21
- if (config.refresh && !config.refresh.secretKey) {
19
+ if (config.refreshToken && !config.refreshToken.secretKey) {
22
20
  throw new errors_1.UndefinedTokenSecretError("Refresh");
23
21
  }
24
22
  const accessTokenConfig = (0, jwt_tools_1.prepareAccessTokenConfig)(config);
@@ -34,7 +32,14 @@ class JwtStrategy extends token_based_auth_strategy_1.TokenBasedAuthStrategy {
34
32
  throw new errors_1.UndefinedTokenError("Access");
35
33
  if (!accessTokenConfig.secretKey)
36
34
  throw new errors_1.UndefinedTokenSecretError("Access");
37
- return verifyAsync(token, accessTokenConfig.secretKey, accessTokenConfig.verifyOptions);
35
+ return new Promise((resolve, reject) => {
36
+ jsonwebtoken_1.default.verify(token, accessTokenConfig.secretKey, accessTokenConfig.verifyOptions, (err, payload) => {
37
+ if (err)
38
+ reject(err);
39
+ else
40
+ resolve(payload);
41
+ });
42
+ });
38
43
  }
39
44
  catch (error) {
40
45
  this.logger?.error("JWT verification failed:", error);
@@ -52,7 +57,14 @@ class JwtStrategy extends token_based_auth_strategy_1.TokenBasedAuthStrategy {
52
57
  throw new errors_1.UndefinedTokenError("Refresh");
53
58
  if (!refreshTokenConfig.secretKey)
54
59
  throw new errors_1.UndefinedTokenSecretError("Refresh");
55
- return verifyAsync(token, refreshTokenConfig.secretKey, refreshTokenConfig.verifyOptions);
60
+ return new Promise((resolve, reject) => {
61
+ jsonwebtoken_1.default.verify(token, refreshTokenConfig.secretKey, refreshTokenConfig.verifyOptions, (err, payload) => {
62
+ if (err)
63
+ reject(err);
64
+ else
65
+ resolve(payload);
66
+ });
67
+ });
56
68
  }
57
69
  catch (error) {
58
70
  this.logger?.error("JWT verification failed:", error);
@@ -1,3 +1,3 @@
1
- import { JwtAccessTokenHandlerConfig, JwtConfig, JwtRefreshTokenHandlerConfig } from "./jwt.types";
2
- export declare const prepareAccessTokenConfig: (config: JwtConfig) => JwtAccessTokenHandlerConfig;
3
- export declare const prepareRefreshTokenConfig: (config: JwtConfig) => JwtRefreshTokenHandlerConfig;
1
+ import { JwtAccessTokenConfig, JwtConfig, JwtRefreshTokenConfig } from "./jwt.types";
2
+ export declare const prepareAccessTokenConfig: (config: JwtConfig) => JwtAccessTokenConfig;
3
+ export declare const prepareRefreshTokenConfig: (config: JwtConfig) => JwtRefreshTokenConfig;
@@ -27,25 +27,25 @@ exports.prepareRefreshTokenConfig = exports.prepareAccessTokenConfig = void 0;
27
27
  const Soap = __importStar(require("@soapjs/soap"));
28
28
  const prepareAccessTokenConfig = (config) => {
29
29
  return Soap.removeUndefinedProperties({
30
- ...config.access,
30
+ ...config.accessToken,
31
31
  tokenType: "Access",
32
- expiresIn: config.access.expiresIn || "1h",
32
+ expiresIn: config.accessToken.expiresIn || "1h",
33
33
  signOptions: {
34
- ...config.access.signOptions,
35
- algorithm: config.access.signOptions.algorithm || "HS256",
36
- expiresIn: config.access.expiresIn || "1h",
37
- audience: config.access.audience,
38
- issuer: config.access.issuer,
39
- subject: config.access.subject,
34
+ ...config.accessToken.signOptions,
35
+ algorithm: config.accessToken.signOptions.algorithm || "HS256",
36
+ expiresIn: config.accessToken.expiresIn || "1h",
37
+ audience: config.accessToken.audience,
38
+ issuer: config.accessToken.issuer,
39
+ subject: config.accessToken.subject,
40
40
  },
41
- verifyOptions: config.access.verifyOptions
41
+ verifyOptions: config.accessToken.verifyOptions
42
42
  ? {
43
- ...config.access.verifyOptions,
44
- algorithms: config.access.verifyOptions.algorithms || ["HS256"],
45
- expiresIn: config.access.expiresIn || "1h",
46
- audience: config.access.audience,
47
- issuer: config.access.issuer,
48
- subject: config.access.subject,
43
+ ...config.accessToken.verifyOptions,
44
+ algorithms: config.accessToken.verifyOptions.algorithms || ["HS256"],
45
+ expiresIn: config.accessToken.expiresIn || "1h",
46
+ audience: config.accessToken.audience,
47
+ issuer: config.accessToken.issuer,
48
+ subject: config.accessToken.subject,
49
49
  }
50
50
  : {},
51
51
  });
@@ -53,25 +53,25 @@ const prepareAccessTokenConfig = (config) => {
53
53
  exports.prepareAccessTokenConfig = prepareAccessTokenConfig;
54
54
  const prepareRefreshTokenConfig = (config) => {
55
55
  return Soap.removeUndefinedProperties({
56
- ...config.refresh,
57
- secretKey: config.refresh.secretKey,
56
+ ...config.refreshToken,
57
+ secretKey: config.refreshToken.secretKey,
58
58
  tokenType: "Refresh",
59
59
  signOptions: {
60
- ...config.refresh.signOptions,
61
- algorithm: config.refresh.signOptions.algorithm || "HS256",
62
- expiresIn: config.refresh.expiresIn || "7d",
63
- audience: config.refresh.audience,
64
- issuer: config.refresh.issuer,
65
- subject: config.refresh.subject,
60
+ ...config.refreshToken.signOptions,
61
+ algorithm: config.refreshToken.signOptions.algorithm || "HS256",
62
+ expiresIn: config.refreshToken.expiresIn || "7d",
63
+ audience: config.refreshToken.audience,
64
+ issuer: config.refreshToken.issuer,
65
+ subject: config.refreshToken.subject,
66
66
  },
67
- verifyOptions: config.refresh.verifyOptions
67
+ verifyOptions: config.refreshToken.verifyOptions
68
68
  ? {
69
- ...config.refresh.verifyOptions,
70
- algorithm: config.refresh.verifyOptions.algorithms || ["HS256"],
71
- expiresIn: config.refresh.expiresIn || "7d",
72
- audience: config.refresh.audience,
73
- issuer: config.refresh.issuer,
74
- subject: config.refresh.subject,
69
+ ...config.refreshToken.verifyOptions,
70
+ algorithm: config.refreshToken.verifyOptions.algorithms || ["HS256"],
71
+ expiresIn: config.refreshToken.expiresIn || "7d",
72
+ audience: config.refreshToken.audience,
73
+ issuer: config.refreshToken.issuer,
74
+ subject: config.refreshToken.subject,
75
75
  }
76
76
  : {},
77
77
  });
@@ -1,4 +1,4 @@
1
- import { TokenBasedAuthStrategyConfig, TokenHandlerConfig } from "../../types";
1
+ import { TokenBasedAuthStrategyConfig, TokenConfig } from "../../types";
2
2
  export interface JwtVerifyOptions {
3
3
  algorithms?: string[];
4
4
  notBefore?: string | number;
@@ -19,15 +19,29 @@ export interface JwtSignOptions {
19
19
  keyid?: string;
20
20
  allowUnsafe?: boolean;
21
21
  }
22
- export type JwtAccessTokenHandlerConfig = {
22
+ export type JwtAccessTokenConfig = {
23
23
  verifyOptions?: JwtVerifyOptions;
24
24
  signOptions: JwtSignOptions;
25
- } & TokenHandlerConfig;
26
- export type JwtRefreshTokenHandlerConfig = {
25
+ } & TokenConfig;
26
+ export type JwtRefreshTokenConfig = {
27
27
  verifyOptions?: JwtVerifyOptions;
28
28
  signOptions: JwtSignOptions;
29
- } & TokenHandlerConfig;
30
- export type JwtConfig<TContext = unknown, TUser = unknown> = {
31
- access: JwtAccessTokenHandlerConfig;
32
- refresh?: JwtRefreshTokenHandlerConfig;
33
- } & TokenBasedAuthStrategyConfig<TContext, TUser>;
29
+ } & TokenConfig;
30
+ export interface JwtConfig<TContext = unknown, TUser = unknown> extends TokenBasedAuthStrategyConfig<TContext, TUser> {
31
+ accessToken: JwtAccessTokenConfig;
32
+ refreshToken?: JwtRefreshTokenConfig;
33
+ routes?: {
34
+ login?: {
35
+ path: string;
36
+ method?: "POST" | "GET";
37
+ };
38
+ logout?: {
39
+ path: string;
40
+ method?: "POST" | "GET";
41
+ };
42
+ refresh?: {
43
+ path: string;
44
+ method?: "POST" | "GET";
45
+ };
46
+ };
47
+ }
@@ -1,15 +1,15 @@
1
1
  import * as Soap from "@soapjs/soap";
2
- import { TokenHandlerConfig, AuthResult } from "../../types";
2
+ import { TokenConfig, AuthResult } from "../../types";
3
3
  import { TokenBasedAuthStrategy } from "../token-based-auth.strategy";
4
4
  import { OAuth2StrategyConfig } from "./oauth2.types";
5
5
  import { SessionHandler } from "../../session/session-handler";
6
6
  export declare class OAuth2Strategy<TContext = unknown, TUser = unknown> extends TokenBasedAuthStrategy<TContext, TUser> {
7
7
  protected config: OAuth2StrategyConfig<TContext, TUser>;
8
- protected accessTokenHandler: TokenHandlerConfig;
9
- protected refreshTokenHandler?: TokenHandlerConfig;
8
+ protected accessTokenConfig: TokenConfig;
9
+ protected refreshTokenConfig?: TokenConfig;
10
10
  protected session?: SessionHandler;
11
11
  protected logger?: Soap.Logger;
12
- constructor(config: OAuth2StrategyConfig<TContext, TUser>, accessTokenHandler: TokenHandlerConfig, refreshTokenHandler?: TokenHandlerConfig, session?: SessionHandler, logger?: Soap.Logger);
12
+ constructor(config: OAuth2StrategyConfig<TContext, TUser>, accessTokenConfig: TokenConfig, refreshTokenConfig?: TokenConfig, session?: SessionHandler, logger?: Soap.Logger);
13
13
  authenticate(context: TContext): Promise<AuthResult<TUser>>;
14
14
  protected verifyAuthorizationCode(context: TContext, code: string): void;
15
15
  protected extractAuthorizationCode(context: TContext): string | null;
@@ -10,35 +10,35 @@ const token_based_auth_strategy_1 = require("../token-based-auth.strategy");
10
10
  const oauth2_tools_1 = require("./oauth2.tools");
11
11
  class OAuth2Strategy extends token_based_auth_strategy_1.TokenBasedAuthStrategy {
12
12
  config;
13
- accessTokenHandler;
14
- refreshTokenHandler;
13
+ accessTokenConfig;
14
+ refreshTokenConfig;
15
15
  session;
16
16
  logger;
17
- constructor(config, accessTokenHandler, refreshTokenHandler, session, logger) {
18
- super(config, accessTokenHandler, refreshTokenHandler, session, logger);
17
+ constructor(config, accessTokenConfig, refreshTokenConfig, session, logger) {
18
+ super(config, accessTokenConfig, refreshTokenConfig, session, logger);
19
19
  this.config = config;
20
- this.accessTokenHandler = accessTokenHandler;
21
- this.refreshTokenHandler = refreshTokenHandler;
20
+ this.accessTokenConfig = accessTokenConfig;
21
+ this.refreshTokenConfig = refreshTokenConfig;
22
22
  this.session = session;
23
23
  this.logger = logger;
24
- this.config.scope = this.config.scope ?? "openid profile email";
24
+ this.config.scope = this.config.scope ?? "email";
25
25
  }
26
26
  async authenticate(context) {
27
27
  try {
28
28
  let user;
29
29
  let refreshToken;
30
- let accessToken = await this.accessTokenHandler.retrieve?.(context);
30
+ let accessToken = await this.accessTokenConfig.retrieve?.(context);
31
31
  if (!accessToken) {
32
32
  this.logger?.info("No access token found, checking for refresh token.");
33
- refreshToken = await this.refreshTokenHandler?.retrieve?.(context);
33
+ refreshToken = await this.refreshTokenConfig?.retrieve?.(context);
34
34
  if (refreshToken) {
35
35
  this.logger?.info("Found refresh token, attempting to refresh access token.");
36
36
  const newTokens = await this.refreshAccessToken(context);
37
37
  accessToken = newTokens.accessToken;
38
- this.accessTokenHandler.embed?.(context, accessToken);
38
+ this.accessTokenConfig.embed?.(context, accessToken);
39
39
  if (newTokens.refreshToken) {
40
40
  refreshToken = newTokens.refreshToken;
41
- this.refreshTokenHandler?.embed?.(context, newTokens.refreshToken);
41
+ this.refreshTokenConfig?.embed?.(context, newTokens.refreshToken);
42
42
  }
43
43
  }
44
44
  else {
@@ -67,24 +67,24 @@ class OAuth2Strategy extends token_based_auth_strategy_1.TokenBasedAuthStrategy
67
67
  default:
68
68
  throw new Error(`Unsupported grant type: ${this.config.grantType}`);
69
69
  }
70
- this.accessTokenHandler.embed?.(context, accessToken);
70
+ this.accessTokenConfig.embed?.(context, accessToken);
71
71
  if (refreshToken) {
72
- this.refreshTokenHandler?.embed?.(context, refreshToken);
72
+ this.refreshTokenConfig?.embed?.(context, refreshToken);
73
73
  }
74
74
  }
75
75
  }
76
76
  else if (accessToken && (await this.isTokenExpired(accessToken))) {
77
77
  this.logger?.info("Access token expired, attempting refresh.");
78
- refreshToken = await this.refreshTokenHandler?.retrieve?.(context);
78
+ refreshToken = await this.refreshTokenConfig?.retrieve?.(context);
79
79
  if (!refreshToken) {
80
80
  throw new errors_1.MissingTokenError("Refresh");
81
81
  }
82
82
  const newTokens = await this.refreshAccessToken(context);
83
83
  accessToken = newTokens.accessToken;
84
- this.accessTokenHandler.embed?.(context, accessToken);
84
+ this.accessTokenConfig.embed?.(context, accessToken);
85
85
  if (newTokens.refreshToken && newTokens.refreshToken !== refreshToken) {
86
86
  refreshToken = newTokens.refreshToken;
87
- this.refreshTokenHandler?.embed?.(context, newTokens.refreshToken);
87
+ this.refreshTokenConfig?.embed?.(context, newTokens.refreshToken);
88
88
  }
89
89
  }
90
90
  if (!accessToken) {
@@ -126,7 +126,7 @@ class OAuth2Strategy extends token_based_auth_strategy_1.TokenBasedAuthStrategy
126
126
  }
127
127
  buildAuthorizationUrl(context) {
128
128
  let authorizationUrl = `${this.config.endpoints.authorizationUrl}?client_id=${this.config.clientId}&redirect_uri=${encodeURIComponent(this.config.redirectUri)}&response_type=code&scope=${this.config.scope ?? ""}`;
129
- if (this.config.pkce?.enabled) {
129
+ if (this.config.pkce) {
130
130
  const codeVerifier = this.config.pkce.generateCodeVerifier
131
131
  ? this.config.pkce.generateCodeVerifier()
132
132
  : oauth2_tools_1.OAuth2Tools.generateCodeVerifier();
@@ -143,7 +143,7 @@ class OAuth2Strategy extends token_based_auth_strategy_1.TokenBasedAuthStrategy
143
143
  code,
144
144
  redirect_uri: this.config.redirectUri,
145
145
  };
146
- if (this.config.pkce?.enabled) {
146
+ if (this.config.pkce) {
147
147
  const codeVerifier = this.config.pkce.retrieveCodeVerifier?.(context);
148
148
  if (!codeVerifier) {
149
149
  throw new Error("Missing PKCE code verifier in context.");
@@ -215,7 +215,7 @@ class OAuth2Strategy extends token_based_auth_strategy_1.TokenBasedAuthStrategy
215
215
  }
216
216
  async refreshAccessToken(context) {
217
217
  try {
218
- const refreshToken = await this.refreshTokenHandler?.retrieve?.(context);
218
+ const refreshToken = await this.refreshTokenConfig?.retrieve?.(context);
219
219
  if (!refreshToken) {
220
220
  throw new errors_1.MissingTokenError("Refresh");
221
221
  }
@@ -229,9 +229,9 @@ class OAuth2Strategy extends token_based_auth_strategy_1.TokenBasedAuthStrategy
229
229
  accessToken: response.data.access_token,
230
230
  refreshToken: response.data.refresh_token,
231
231
  };
232
- await this.accessTokenHandler.embed?.(context, refreshedTokens.accessToken);
232
+ await this.accessTokenConfig.embed?.(context, refreshedTokens.accessToken);
233
233
  if (refreshedTokens.refreshToken) {
234
- await this.refreshTokenHandler?.embed?.(context, refreshedTokens.refreshToken);
234
+ await this.refreshTokenConfig?.embed?.(context, refreshedTokens.refreshToken);
235
235
  }
236
236
  return refreshedTokens;
237
237
  }
@@ -1,4 +1,4 @@
1
- import { TokenBasedAuthStrategyConfig } from "../../types";
1
+ import { TokenBasedAuthStrategyConfig, TokenConfig } from "../../types";
2
2
  export interface OAuth2Endpoints {
3
3
  authorizationUrl: string;
4
4
  tokenUrl: string;
@@ -6,7 +6,7 @@ export interface OAuth2Endpoints {
6
6
  introspectionUrl?: string;
7
7
  revocationUrl?: string;
8
8
  }
9
- export interface OAuth2StrategyConfig<TContext = unknown, TUser = unknown> extends TokenBasedAuthStrategyConfig<TContext, TUser>, PKCEConfig<TContext> {
9
+ export interface OAuth2StrategyConfig<TContext = unknown, TUser = unknown> extends TokenBasedAuthStrategyConfig<TContext, TUser> {
10
10
  clientId: string;
11
11
  clientSecret: string;
12
12
  redirectUri: string;
@@ -18,12 +18,12 @@ export interface OAuth2StrategyConfig<TContext = unknown, TUser = unknown> exten
18
18
  username: string;
19
19
  password: string;
20
20
  };
21
+ pkce?: PKCEConfig<TContext>;
22
+ accessToken?: TokenConfig;
23
+ refreshToken?: TokenConfig;
21
24
  }
22
25
  export interface PKCEConfig<TContext> {
23
- pkce?: {
24
- enabled?: boolean;
25
- generateCodeVerifier?: () => string;
26
- storeCodeVerifier?: (context: TContext, codeVerifier: string) => void;
27
- retrieveCodeVerifier?: (context: TContext) => string | null;
28
- };
26
+ generateCodeVerifier?: () => string;
27
+ storeCodeVerifier?: (context: TContext, codeVerifier: string) => void;
28
+ retrieveCodeVerifier?: (context: TContext) => string | null;
29
29
  }
@@ -1,15 +1,15 @@
1
1
  import * as Soap from "@soapjs/soap";
2
2
  import { AuthResult, TokenBasedAuthStrategyConfig } from "../types";
3
3
  import { BaseAuthStrategy } from "./base-auth.strategy";
4
- import { TokenHandlerConfig } from "../types";
4
+ import { TokenConfig } from "../types";
5
5
  import { SessionHandler } from "../session/session-handler";
6
6
  export declare abstract class TokenBasedAuthStrategy<TContext = unknown, TUser = unknown> extends BaseAuthStrategy<TContext, TUser> {
7
7
  protected config: TokenBasedAuthStrategyConfig<TContext, TUser>;
8
- protected accessTokenHandler: TokenHandlerConfig;
9
- protected refreshTokenHandler?: TokenHandlerConfig;
8
+ protected accessTokenConfig?: TokenConfig;
9
+ protected refreshTokenConfig?: TokenConfig;
10
10
  protected session?: SessionHandler;
11
11
  protected logger?: Soap.Logger;
12
- constructor(config: TokenBasedAuthStrategyConfig<TContext, TUser>, accessTokenHandler: TokenHandlerConfig, refreshTokenHandler?: TokenHandlerConfig, session?: SessionHandler, logger?: Soap.Logger);
12
+ constructor(config: TokenBasedAuthStrategyConfig<TContext, TUser>, accessTokenConfig?: TokenConfig, refreshTokenConfig?: TokenConfig, session?: SessionHandler, logger?: Soap.Logger);
13
13
  protected retrieveUser(decodedToken: any): Promise<TUser | null>;
14
14
  authenticate(context: TContext): Promise<AuthResult<TUser>>;
15
15
  logout(context: TContext): Promise<void>;
@@ -5,15 +5,15 @@ const base_auth_strategy_1 = require("./base-auth.strategy");
5
5
  const errors_1 = require("../errors");
6
6
  class TokenBasedAuthStrategy extends base_auth_strategy_1.BaseAuthStrategy {
7
7
  config;
8
- accessTokenHandler;
9
- refreshTokenHandler;
8
+ accessTokenConfig;
9
+ refreshTokenConfig;
10
10
  session;
11
11
  logger;
12
- constructor(config, accessTokenHandler, refreshTokenHandler, session, logger) {
12
+ constructor(config, accessTokenConfig, refreshTokenConfig, session, logger) {
13
13
  super(config, session, logger);
14
14
  this.config = config;
15
- this.accessTokenHandler = accessTokenHandler;
16
- this.refreshTokenHandler = refreshTokenHandler;
15
+ this.accessTokenConfig = accessTokenConfig;
16
+ this.refreshTokenConfig = refreshTokenConfig;
17
17
  this.session = session;
18
18
  this.logger = logger;
19
19
  }
@@ -22,11 +22,12 @@ class TokenBasedAuthStrategy extends base_auth_strategy_1.BaseAuthStrategy {
22
22
  }
23
23
  async authenticate(context) {
24
24
  try {
25
- let accessToken = await this.accessTokenHandler.retrieve?.(context);
25
+ let accessToken = await this.accessTokenConfig.retrieve?.(context);
26
+ let refreshToken;
26
27
  await this.checkRateLimit(context);
27
28
  if (accessToken) {
28
29
  try {
29
- const decoded = await this.accessTokenHandler.verify?.(accessToken);
30
+ const decoded = await this.accessTokenConfig.verify?.(accessToken);
30
31
  const user = await this.retrieveUser(decoded);
31
32
  if (!user) {
32
33
  throw new errors_1.UserNotFoundError();
@@ -38,13 +39,18 @@ class TokenBasedAuthStrategy extends base_auth_strategy_1.BaseAuthStrategy {
38
39
  this.logger?.warn("Access token is invalid or expired, trying refresh token...");
39
40
  }
40
41
  }
41
- const refreshToken = await this.refreshTokenHandler?.retrieve?.(context);
42
- if (!refreshToken) {
43
- throw new errors_1.MissingTokenError();
42
+ if (this.refreshTokenConfig) {
43
+ refreshToken = await this.refreshTokenConfig?.retrieve?.(context);
44
+ if (!refreshToken) {
45
+ throw new errors_1.MissingTokenError("Refresh");
46
+ }
47
+ accessToken = await this.refreshTokenConfig?.rotate?.(refreshToken);
48
+ if (!accessToken) {
49
+ throw new errors_1.MissingTokenError("Access");
50
+ }
44
51
  }
45
- accessToken = await this.refreshTokenHandler?.rotate?.(refreshToken);
46
- this.accessTokenHandler.embed?.(context, accessToken);
47
- const decoded = await this.accessTokenHandler.verify?.(accessToken);
52
+ this.accessTokenConfig.embed?.(context, accessToken);
53
+ const decoded = await this.accessTokenConfig.verify?.(accessToken);
48
54
  const user = await this.retrieveUser(decoded);
49
55
  if (!user) {
50
56
  throw new errors_1.UserNotFoundError();
@@ -59,9 +65,9 @@ class TokenBasedAuthStrategy extends base_auth_strategy_1.BaseAuthStrategy {
59
65
  }
60
66
  async logout(context) {
61
67
  try {
62
- await this.accessTokenHandler.remove?.(context);
63
- if (this.refreshTokenHandler) {
64
- await this.refreshTokenHandler.remove?.(context);
68
+ await this.accessTokenConfig.remove?.(context);
69
+ if (this.refreshTokenConfig) {
70
+ await this.refreshTokenConfig.remove?.(context);
65
71
  }
66
72
  await this.config.logout.onSuccess?.(context);
67
73
  this.logger?.info("User logged out successfully.");
@@ -74,32 +80,32 @@ class TokenBasedAuthStrategy extends base_auth_strategy_1.BaseAuthStrategy {
74
80
  }
75
81
  async generateTokens(user, context) {
76
82
  const payload = { userId: user.id, roles: user.roles };
77
- const accessToken = this.accessTokenHandler.generate?.(payload);
83
+ const accessToken = this.accessTokenConfig.generate?.(payload);
78
84
  if (!accessToken)
79
85
  throw new Error("Failed to generate access token.");
80
- await this.accessTokenHandler.store?.(accessToken, user, +this.accessTokenHandler.expiresIn);
81
- this.accessTokenHandler.embed?.(context, accessToken);
86
+ await this.accessTokenConfig.store?.(accessToken, user, +this.accessTokenConfig.expiresIn);
87
+ this.accessTokenConfig.embed?.(context, accessToken);
82
88
  let refreshToken;
83
- if (this.refreshTokenHandler) {
84
- refreshToken = this.refreshTokenHandler.generate?.(payload);
89
+ if (this.refreshTokenConfig) {
90
+ refreshToken = this.refreshTokenConfig.generate?.(payload);
85
91
  if (refreshToken) {
86
- await this.refreshTokenHandler.store?.(refreshToken, user, +this.refreshTokenHandler.expiresIn);
87
- this.refreshTokenHandler.embed?.(context, refreshToken);
92
+ await this.refreshTokenConfig.store?.(refreshToken, user, +this.refreshTokenConfig.expiresIn);
93
+ this.refreshTokenConfig.embed?.(context, refreshToken);
88
94
  }
89
95
  }
90
96
  return { accessToken, refreshToken };
91
97
  }
92
98
  async rotateToken(context) {
93
99
  try {
94
- if (!this.refreshTokenHandler) {
100
+ if (!this.refreshTokenConfig) {
95
101
  throw new Error("Refresh token handler is not configured.");
96
102
  }
97
- const refreshToken = await this.refreshTokenHandler.retrieve?.(context);
103
+ const refreshToken = await this.refreshTokenConfig.retrieve?.(context);
98
104
  if (!refreshToken) {
99
105
  throw new errors_1.MissingTokenError("Refresh");
100
106
  }
101
- const newAccessToken = await this.refreshTokenHandler.rotate?.(refreshToken);
102
- this.accessTokenHandler.embed?.(context, newAccessToken);
107
+ const newAccessToken = await this.refreshTokenConfig.rotate?.(refreshToken);
108
+ this.accessTokenConfig.embed?.(context, newAccessToken);
103
109
  return { accessToken: newAccessToken, refreshToken };
104
110
  }
105
111
  catch (error) {
package/build/types.d.ts CHANGED
@@ -40,15 +40,17 @@ export interface AuthResultConfig<TContext = unknown, TUser = unknown> {
40
40
  onFailure?: (context: AuthFailureContext<TContext>) => Promise<void> | void;
41
41
  }
42
42
  export interface SecurityConfig {
43
- security?: {
44
- maxFailedLoginAttempts?: number;
45
- lockoutDuration?: number;
46
- notifyOnLockout?: (account: any) => Promise<void>;
47
- };
43
+ maxFailedLoginAttempts?: number;
44
+ lockoutDuration?: number;
45
+ notifyOnLockout?: (account: any) => Promise<void>;
48
46
  }
49
- export interface BaseAuthStrategyConfig<TContext = unknown, TUser = unknown> extends AccountLockConfig<TContext>, RateLimitConfig, RoleAuthorizationConfig<TUser>, SecurityConfig {
47
+ export interface BaseAuthStrategyConfig<TContext = unknown, TUser = unknown> {
50
48
  mfa?: MfaConfig<TUser, TContext>;
51
49
  session?: SessionConfig;
50
+ role?: RoleAuthorizationConfig<TUser>;
51
+ rateLimit?: RateLimitConfig;
52
+ security?: SecurityConfig;
53
+ lock?: AccountLockConfig<TContext>;
52
54
  }
53
55
  export interface AuditLoggingConfig<TContext = unknown> {
54
56
  logAttempt?: (userId: string, success: boolean, context?: TContext) => Promise<void>;
@@ -98,15 +100,14 @@ export interface CredentialBasedAuthStrategyConfig<TContext = unknown, TUser = u
98
100
  updatePassword?: (identifier: string, newPassword: string) => Promise<void>;
99
101
  } & AuthResultConfig<TContext, TUser>;
100
102
  }
101
- export interface TokenBasedAuthStrategyConfig<TContext = unknown, TUser = unknown> extends BaseAuthStrategyConfig<TContext, TUser>, TokenRotationConfig<TUser> {
102
- tokens?: TokenHandlersConfig;
103
+ export interface TokenBasedAuthStrategyConfig<TContext = unknown, TUser = unknown> extends BaseAuthStrategyConfig<TContext, TUser> {
104
+ rotation?: TokenRotationConfig<TUser>;
103
105
  login: {
104
106
  retrieveUserData: (identifier: string) => Promise<TUser | null>;
105
107
  } & AuthResultConfig<TContext, TUser>;
106
108
  logout: {} & AuthResultConfig<TContext, TUser>;
107
109
  }
108
110
  export interface TokenRotationConfig<TUser = unknown> {
109
- enableRotation?: boolean;
110
111
  maxRotations?: number;
111
112
  storeUsedTokens?: boolean;
112
113
  getRefreshToken?: (user: TUser) => Promise<string>;
@@ -184,7 +185,6 @@ export interface SoapSocketAuthConfig<TContext = unknown, TUser = unknown> {
184
185
  }
185
186
  export interface SoapAuthConfig<TContext = unknown, TUser = unknown> {
186
187
  session?: SessionConfig;
187
- tokens?: TokenHandlersConfig;
188
188
  http?: SoapHttpAuthConfig<TContext, TUser>;
189
189
  socket?: SoapSocketAuthConfig<TContext, TUser>;
190
190
  logger?: Soap.Logger;
@@ -230,7 +230,7 @@ export interface StorageContext {
230
230
  encrypt?: (data: string) => Promise<string> | string;
231
231
  decrypt?: (data: string) => Promise<string> | string;
232
232
  }
233
- export interface TokenHandlerConfig {
233
+ export interface TokenConfig {
234
234
  secretKey: string;
235
235
  expiresIn: string | number;
236
236
  audience?: string | string[];
@@ -245,7 +245,3 @@ export interface TokenHandlerConfig {
245
245
  embed?: (context: any, token: string) => void;
246
246
  rotate?: (oldToken: string) => Promise<string>;
247
247
  }
248
- export interface TokenHandlersConfig {
249
- access: TokenHandlerConfig;
250
- refresh?: TokenHandlerConfig;
251
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soapjs/soap-auth",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "",
5
5
  "homepage": "https://docs.soapjs.com",
6
6
  "repository": "https://github.com/soapjs/soap-auth",
@@ -15,14 +15,14 @@
15
15
  "prepublish": "npm run clean && tsc --project tsconfig.build.json"
16
16
  },
17
17
  "devDependencies": {
18
- "@soapjs/soap": "^0.5.2",
18
+ "@soapjs/soap": "^0.5.8",
19
19
  "@types/jest": "^27.0.3",
20
20
  "jest": "^27.4.5",
21
21
  "ts-jest": "^27.1.3",
22
22
  "typescript": "^4.8.2"
23
23
  },
24
24
  "peerDependencies": {
25
- "@soapjs/soap": ">=0.5.2"
25
+ "@soapjs/soap": ">=0.5.8"
26
26
  },
27
27
  "dependencies": {
28
28
  "axios": "^1.7.9",