@soapjs/soap-auth 0.1.1 → 0.3.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 (41) hide show
  1. package/README.md +120 -169
  2. package/build/factories/http-auth-strategy.factory.js +1 -1
  3. package/build/factories/index.d.ts +3 -0
  4. package/build/factories/index.js +19 -0
  5. package/build/index.d.ts +4 -25
  6. package/build/index.js +4 -25
  7. package/build/session/index.d.ts +3 -0
  8. package/build/session/index.js +19 -0
  9. package/build/soap-auth.d.ts +9 -9
  10. package/build/soap-auth.js +64 -34
  11. package/build/strategies/api-key/api-key.strategy.d.ts +4 -3
  12. package/build/strategies/api-key/api-key.strategy.js +9 -6
  13. package/build/strategies/api-key/api-key.types.d.ts +2 -4
  14. package/build/strategies/base-auth.strategy.d.ts +4 -3
  15. package/build/strategies/base-auth.strategy.js +18 -2
  16. package/build/strategies/basic/basic.strategy.d.ts +5 -11
  17. package/build/strategies/basic/basic.strategy.js +14 -19
  18. package/build/strategies/basic/basic.types.d.ts +2 -2
  19. package/build/strategies/{credential-based-auth.strategy.d.ts → credential-auth.strategy.d.ts} +15 -12
  20. package/build/strategies/{credential-based-auth.strategy.js → credential-auth.strategy.js} +95 -46
  21. package/build/strategies/index.d.ts +16 -0
  22. package/build/strategies/index.js +32 -0
  23. package/build/strategies/jwt/jwt.strategy.d.ts +17 -2
  24. package/build/strategies/jwt/jwt.strategy.js +118 -57
  25. package/build/strategies/jwt/jwt.tools.d.ts +7 -3
  26. package/build/strategies/jwt/jwt.tools.js +80 -41
  27. package/build/strategies/jwt/jwt.types.d.ts +3 -27
  28. package/build/strategies/local/local.strategy.d.ts +3 -9
  29. package/build/strategies/local/local.strategy.js +7 -58
  30. package/build/strategies/local/local.types.d.ts +2 -2
  31. package/build/strategies/oauth2/oauth2.strategy.d.ts +21 -7
  32. package/build/strategies/oauth2/oauth2.strategy.js +158 -49
  33. package/build/strategies/oauth2/oauth2.types.d.ts +8 -16
  34. package/build/strategies/token-auth.strategy.d.ts +25 -0
  35. package/build/strategies/token-auth.strategy.js +78 -0
  36. package/build/tools/index.d.ts +3 -0
  37. package/build/tools/index.js +19 -0
  38. package/build/types.d.ts +87 -57
  39. package/package.json +2 -1
  40. package/build/strategies/token-based-auth.strategy.d.ts +0 -25
  41. package/build/strategies/token-based-auth.strategy.js +0 -130
package/README.md CHANGED
@@ -1,223 +1,174 @@
1
- # SoapAuth
1
+ # SoapAuth - Modular Authentication Solution
2
2
 
3
- **SoapAuth** is a flexible authentication and authorization module designed to provide support for various authentication strategies. It is intended to be used alongside a specific framework adapter, serving as the core authentication engine.
4
-
5
- ---
3
+ SoapAuth is a flexible library for handling authentication and identity management. It allows you to easily implement various authentication strategies such as JWT, OAuth2, Basic Auth, Local Auth, API Key, and more. As part of the **@soapjs** ecosystem, it can be easily extended with additional components like **soap**, **soap-express**, and **soap-cli**.
6
4
 
7
5
  ## Installation
8
-
9
6
  ```sh
10
7
  npm install @soapjs/soap-auth
11
8
  ```
12
9
 
13
- ---
14
-
15
- ## Features
16
-
17
- - Multiple authentication strategies (local, OAuth2, JWT, API key, basic auth)
18
- - Custom authentication strategy support
19
- - Built-in session management with pluggable session stores
20
- - Token handling for JWT authentication
21
- - Extensible architecture with abstract base classes
22
- - Compatible with framework adapters for seamless integration
10
+ ## Key Features
11
+ - **Supports multiple authentication strategies** (JWT, OAuth2, API Key, Basic, Local, Hybrid OAuth2).
12
+ - **Works with both HTTP and WebSocket protocols.**
13
+ - **Manages sessions, MFA, roles, account locks, and rate limiting.**
14
+ - **Easy configuration and extendability.**
15
+ - **Integration with frameworks like Express, NestJS, etc.**
23
16
 
24
17
  ---
25
18
 
26
- ## Core Classes Overview
27
-
28
- ### 1. `SoapAuth`
29
- This is the main entry point for managing authentication. It initializes different strategies based on the provided configuration and provides methods for authentication, authorization, and session management.
30
-
31
- ### 2. `AuthStrategy`
32
- The base interface that all strategies must implement. Provides methods such as `authenticate`, `authorize`, `init`, and `logout`.
33
-
34
- ### 3. `SessionHandler`
35
- Handles session operations like retrieving, storing, and generating session IDs. It supports multiple session storage mechanisms such as in-memory and file-based stores.
36
-
37
- ### 4. `TokenBasedAuthStrategy`
38
- Abstract class for token-based authentication strategies, providing methods for handling access and refresh tokens.
19
+ ## Basic Usage
20
+ ```typescript
21
+ import { SoapAuth, JwtStrategy } from "@soapjs/soap-auth";
39
22
 
40
- ### 5. `CredentialBasedAuthStrategy`
41
- Abstract class for username-password-based authentication strategies.
23
+ const auth = new SoapAuth();
24
+ auth.addStrategy(new JwtStrategy({ secret: "super-secret-key" }), "jwt", "http");
42
25
 
43
- ### 6. `HttpAuthStrategyFactory` & `SocketAuthStrategyFactory`
44
- Factories responsible for creating instances of HTTP and socket-based authentication strategies respectively.
26
+ const result = await auth.authenticate("http", "jwt", request);
27
+ console.log(result.user);
28
+ ```
45
29
 
46
30
  ---
47
31
 
48
- ## Available Authentication Strategies
49
-
50
- ### 1. Local Strategy
32
+ ## Supported Authentication Strategies
51
33
 
52
- **When to use:**
53
- - Ideal for applications that require username and password authentication stored locally.
34
+ SoapAuth supports multiple authentication strategies. Below is a description and example configuration for each.
54
35
 
55
- **Configuration example:**
36
+ ### **JWT Strategy** *(Token-based authentication)*
56
37
  ```typescript
57
- const authConfig = {
58
- http: {
59
- local: {
60
- usernameField: "email",
61
- passwordField: "password",
62
- validateUser: async (username, password) => {
63
- return username === "user@example.com" && password === "securepass" ? { id: 1, name: "John Doe" } : null;
64
- },
65
- },
38
+ import { JwtStrategy } from "@soapjs/soap-auth";
39
+
40
+ auth.addStrategy(new JwtStrategy({
41
+ secret: "your-secret-key",
42
+ accessToken: {
43
+ expiresIn: "1h",
44
+ },
45
+ refreshToken: {
46
+ expiresIn: "7d",
66
47
  },
67
- };
48
+ }), "jwt", "http");
68
49
  ```
69
50
 
70
- ### 2. OAuth2 Strategy
71
-
72
- **When to use:**
73
- - Suitable for social logins (Google, Facebook, Twitter, etc.).
74
-
75
- **Configuration example:**
51
+ ### **OAuth2 Strategy** *(OAuth 2.0 authentication)*
76
52
  ```typescript
77
- const authConfig = {
78
- http: {
79
- oauth2: {
80
- google: {
81
- clientId: "your-client-id",
82
- clientSecret: "your-client-secret",
83
- redirectUri: "https://yourapp.com/auth/callback",
84
- scope: "openid profile email",
85
- endpoints: {
86
- authorizationUrl: "https://accounts.google.com/o/oauth2/auth",
87
- tokenUrl: "https://oauth2.googleapis.com/token",
88
- },
89
- },
90
- },
53
+ import { OAuth2Strategy } from "@soapjs/soap-auth";
54
+
55
+ auth.addStrategy(new OAuth2Strategy({
56
+ clientId: "your-client-id",
57
+ clientSecret: "your-client-secret",
58
+ redirectUri: "https://your-app.com/callback",
59
+ endpoints: {
60
+ authorizationUrl: "https://auth.server.com/auth",
61
+ tokenUrl: "https://auth.server.com/token",
91
62
  },
92
- };
63
+ }), "oauth2", "http");
93
64
  ```
94
65
 
95
- ### 3. JWT Strategy
96
-
97
- **When to use:**
98
- - Suitable for stateless authentication where tokens are passed between the client and server.
99
-
100
- **Configuration example:**
66
+ ### **API Key Strategy** *(Key-based authentication)*
101
67
  ```typescript
102
- const authConfig = {
103
- http: {
104
- jwt: {
105
- access: {
106
- secretKey: "your-secret-key",
107
- expiresIn: "1h",
108
- signOptions: { algorithm: "HS256" },
109
- },
110
- },
68
+ import { ApiKeyStrategy } from "@soapjs/soap-auth";
69
+
70
+ auth.addStrategy(new ApiKeyStrategy({
71
+ extractApiKey: (ctx) => ctx.headers["x-api-key"],
72
+ retrieveUserByApiKey: async (key) => {
73
+ return mockDatabase.findUserByApiKey(key);
111
74
  },
112
- };
75
+ }), "apikey", "http");
113
76
  ```
114
77
 
115
- ### 4. API Key Strategy
116
-
117
- **When to use:**
118
- - Best for authenticating external services using static API keys.
119
-
120
- **Configuration example:**
78
+ ### **Basic Auth Strategy** *(Username & Password authentication)*
121
79
  ```typescript
122
- const authConfig = {
123
- http: {
124
- apiKey: {
125
- extractApiKey: (context) => context.headers["x-api-key"],
126
- retrieveUserByApiKey: async (apiKey) => {
127
- return apiKey === "valid-api-key" ? { id: 1, role: "admin" } : null;
128
- },
129
- },
80
+ import { BasicStrategy } from "@soapjs/soap-auth";
81
+
82
+ auth.addStrategy(new BasicStrategy({
83
+ extractCredentials: (ctx) => {
84
+ return { identifier: ctx.body.username, password: ctx.body.password };
130
85
  },
131
- };
86
+ verifyCredentials: async (id, pass) => {
87
+ return mockDatabase.verifyUser(id, pass);
88
+ },
89
+ }), "basic", "http");
132
90
  ```
133
91
 
134
- ### 5. Basic Authentication
92
+ ### **Local Strategy** *(Custom authentication logic)*
93
+ ```typescript
94
+ import { LocalStrategy } from "@soapjs/soap-auth";
135
95
 
136
- **When to use:**
137
- - Useful for simple username-password authentication with minimal overhead.
96
+ auth.addStrategy(new LocalStrategy({
97
+ extractCredentials: (ctx) => ({ identifier: ctx.query.email, password: ctx.query.pass }),
98
+ verifyCredentials: async (id, pass) => {
99
+ return mockDatabase.verifyUser(id, pass);
100
+ },
101
+ }), "local", "http");
102
+ ```
138
103
 
139
- **Configuration example:**
104
+ ### **Hybrid OAuth2 Strategy** *(Combination of multiple authentication methods)*
140
105
  ```typescript
141
- const authConfig = {
142
- http: {
143
- basic: {
144
- validateUser: async (username, password) => {
145
- return username === "admin" && password === "password" ? { id: 1, role: "admin" } : null;
146
- },
106
+ import { HybridOAuth2Strategy } from "@soapjs/soap-auth";
107
+
108
+ auth.addStrategy(new HybridOAuth2Strategy({
109
+ clientId: "your-client-id",
110
+ clientSecret: "your-client-secret",
111
+ oauth2: {
112
+ endpoints: {
113
+ authorizationUrl: "https://oauth.provider.com/auth",
114
+ tokenUrl: "https://oauth.provider.com/token",
147
115
  },
148
116
  },
149
- };
117
+ }), "hybrid-oauth2", "http");
150
118
  ```
151
119
 
152
120
  ---
153
121
 
154
- ## Using SoapAuth
155
-
122
+ ## Configuration & Extensions
123
+ ### Role Management
156
124
  ```typescript
157
- import { SoapAuth } from "@soapjs/soap-auth";
158
-
159
- const auth = new SoapAuth(authConfig);
160
- await auth.init();
161
-
162
- const user = await auth.authenticate("local", { email: "user@example.com", password: "securepass" });
163
- console.log("Authenticated user:", user);
125
+ role: {
126
+ authorizeByRoles: async (user, roles) => roles.includes(user.role),
127
+ roles: ["admin", "user"]
128
+ }
164
129
  ```
165
-
166
- ---
167
-
168
- ## Creating a Custom Authentication Strategy
169
-
170
- To create a custom strategy, extend the appropriate base class depending on the authentication type:
171
-
172
- 1. **For token-based strategies:** Extend `TokenBasedAuthStrategy`.
173
- 2. **For credential-based strategies:** Extend `CredentialBasedAuthStrategy`.
174
- 3. **For generic implementations:** Extend `BaseAuthStrategy` directly.
175
-
176
- **Example:**
130
+ ### Multi-Factor Authentication (MFA)
177
131
  ```typescript
178
- class CustomAuthStrategy extends TokenBasedAuthStrategy {
179
- async authenticate(context) {
180
- const token = context.headers.authorization;
181
- if (token === "valid-token") {
182
- return { user: { id: 1, role: "admin" }, tokens: { accessToken: token } };
183
- }
184
- throw new Error("Invalid token");
185
- }
132
+ mfa: {
133
+ isMfaRequired: (user) => user.requiresMfa,
134
+ validateMfaCode: async (user, code) => mockDatabase.checkMfaCode(user, code),
186
135
  }
187
136
  ```
188
-
189
- ---
190
-
191
- ## Session Management
192
-
193
- SoapAuth supports session management through the `SessionHandler` class. The session can be stored using memory, files, or external databases via adapters.
194
-
195
- **Example Session Configuration:**
137
+ ### Account Locking after Failed Logins
196
138
  ```typescript
197
- const authConfig = {
198
- session: {
199
- secret: "your-session-secret",
200
- sessionKey: "my-session-id",
201
- store: new MemorySessionStore(),
202
- },
203
- };
139
+ lock: {
140
+ isAccountLocked: async (account) => mockDatabase.isLocked(account),
141
+ lockAccount: async (account) => mockDatabase.lock(account),
142
+ }
143
+ ```
144
+ ### Rate Limiting
145
+ ```typescript
146
+ rateLimit: {
147
+ checkRateLimit: async (ctx) => false, // No limits
148
+ }
204
149
  ```
205
150
 
206
151
  ---
207
152
 
208
- ## Framework Integration
153
+ ## FAQ
154
+ **How to report an issue?**
155
+ Open an issue on GitHub.
209
156
 
210
- SoapAuth is designed to work with various frameworks such as Express, Koa, Fastify, and more through dedicated adapters.
157
+ **How to extend `soap-auth` with custom strategies?**
158
+ You can create your own class extending `BaseAuthStrategy` and implementing `authenticate()`.
211
159
 
212
- ```typescript
213
- // basic example
214
- app.use(async (req, res, next) => {
215
- try {
216
- const user = await auth.authenticate("jwt", req);
217
- req.user = user;
218
- next();
219
- } catch (error) {
220
- res.status(401).send("Unauthorized");
221
- }
222
- });
223
- ```
160
+ ---
161
+ ## Issues
162
+ If you encounter any issues, please feel free to report them [here](https://github.com/soapjs/soap/issues/new/choose).
163
+
164
+ ## Contact
165
+ For any questions, collaboration interests, or support needs, you can contact us through the following:
166
+
167
+ - Official:
168
+ - Website: http://docs.soapjs.com
169
+ - Radoslaw Kamysz:
170
+ - Email: [radoslaw.kamysz@gmail.com](mailto:radoslaw.kamysz@gmail.com)
171
+ - Warpcast: [@k4mr4ad](https://warpcast.com/k4mr4ad)
172
+ - Twitter: [@radoslawkamysz](https://x.com/radoslawkamysz)
173
+ ## License
174
+ SoapAuth is licensed under the MIT License.
@@ -15,7 +15,7 @@ class HttpAuthStrategyFactory extends auth_strategy_factory_1.AuthStrategyFactor
15
15
  }
16
16
  if (config.http.oauth2) {
17
17
  for (const provider in config.http.oauth2) {
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));
18
+ strategies.set(provider, new oauth2_strategy_1.OAuth2Strategy(config.http.oauth2[provider], this.getSessionHandler(config.http.oauth2[provider].session, config.session), config.logger));
19
19
  }
20
20
  }
21
21
  if (config.http.apiKey) {
@@ -0,0 +1,3 @@
1
+ export * from "./auth-strategy.factory";
2
+ export * from "./http-auth-strategy.factory";
3
+ export * from "./socket-auth-strategy.factory";
@@ -0,0 +1,19 @@
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./auth-strategy.factory"), exports);
18
+ __exportStar(require("./http-auth-strategy.factory"), exports);
19
+ __exportStar(require("./socket-auth-strategy.factory"), exports);
package/build/index.d.ts CHANGED
@@ -1,28 +1,7 @@
1
- export * from "./factories/auth-strategy.factory";
2
- export * from "./factories/http-auth-strategy.factory";
3
- export * from "./factories/socket-auth-strategy.factory";
4
- export * from "./session/file.session-store";
5
- export * from "./session/memory.session-store";
6
- export * from "./session/session-handler";
7
- export * from "./strategies/api-key/api-key.errors";
8
- export * from "./strategies/api-key/api-key.strategy";
9
- export * from "./strategies/api-key/api-key.types";
10
- export * from "./strategies/base-auth.strategy";
11
- export * from "./strategies/basic/basic.strategy";
12
- export * from "./strategies/basic/basic.types";
13
- export * from "./strategies/credential-based-auth.strategy";
14
- export * from "./strategies/jwt/jwt.strategy";
15
- export * from "./strategies/jwt/jwt.tools";
16
- export * from "./strategies/jwt/jwt.types";
17
- export * from "./strategies/local/local.strategy";
18
- export * from "./strategies/local/local.types";
19
- export * from "./strategies/oauth2/oauth2.strategy";
20
- export * from "./strategies/oauth2/oauth2.tools";
21
- export * from "./strategies/oauth2/oauth2.types";
22
- export * from "./strategies/token-based-auth.strategy";
23
- export * from "./tools/session.tools";
24
- export * from "./tools/token.tools";
25
- export * from "./tools/tools";
1
+ export * from "./factories";
2
+ export * from "./session";
3
+ export * from "./strategies";
4
+ export * from "./tools";
26
5
  export * from "./errors";
27
6
  export * from "./types";
28
7
  export * from "./soap-auth";
package/build/index.js CHANGED
@@ -14,31 +14,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./factories/auth-strategy.factory"), exports);
18
- __exportStar(require("./factories/http-auth-strategy.factory"), exports);
19
- __exportStar(require("./factories/socket-auth-strategy.factory"), exports);
20
- __exportStar(require("./session/file.session-store"), exports);
21
- __exportStar(require("./session/memory.session-store"), exports);
22
- __exportStar(require("./session/session-handler"), exports);
23
- __exportStar(require("./strategies/api-key/api-key.errors"), exports);
24
- __exportStar(require("./strategies/api-key/api-key.strategy"), exports);
25
- __exportStar(require("./strategies/api-key/api-key.types"), exports);
26
- __exportStar(require("./strategies/base-auth.strategy"), exports);
27
- __exportStar(require("./strategies/basic/basic.strategy"), exports);
28
- __exportStar(require("./strategies/basic/basic.types"), exports);
29
- __exportStar(require("./strategies/credential-based-auth.strategy"), exports);
30
- __exportStar(require("./strategies/jwt/jwt.strategy"), exports);
31
- __exportStar(require("./strategies/jwt/jwt.tools"), exports);
32
- __exportStar(require("./strategies/jwt/jwt.types"), exports);
33
- __exportStar(require("./strategies/local/local.strategy"), exports);
34
- __exportStar(require("./strategies/local/local.types"), exports);
35
- __exportStar(require("./strategies/oauth2/oauth2.strategy"), exports);
36
- __exportStar(require("./strategies/oauth2/oauth2.tools"), exports);
37
- __exportStar(require("./strategies/oauth2/oauth2.types"), exports);
38
- __exportStar(require("./strategies/token-based-auth.strategy"), exports);
39
- __exportStar(require("./tools/session.tools"), exports);
40
- __exportStar(require("./tools/token.tools"), exports);
41
- __exportStar(require("./tools/tools"), exports);
17
+ __exportStar(require("./factories"), exports);
18
+ __exportStar(require("./session"), exports);
19
+ __exportStar(require("./strategies"), exports);
20
+ __exportStar(require("./tools"), exports);
42
21
  __exportStar(require("./errors"), exports);
43
22
  __exportStar(require("./types"), exports);
44
23
  __exportStar(require("./soap-auth"), exports);
@@ -0,0 +1,3 @@
1
+ export * from "./file.session-store";
2
+ export * from "./memory.session-store";
3
+ export * from "./session-handler";
@@ -0,0 +1,19 @@
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./file.session-store"), exports);
18
+ __exportStar(require("./memory.session-store"), exports);
19
+ __exportStar(require("./session-handler"), exports);
@@ -1,16 +1,16 @@
1
1
  import { AuthResult, AuthStrategy, SoapAuthConfig } from "./types";
2
2
  export declare class SoapAuth {
3
3
  private requiredStrategyMethods;
4
- private httpStrategies;
5
- private socketStrategies;
4
+ private strategies;
5
+ private logger?;
6
6
  constructor(config: SoapAuthConfig);
7
7
  private isAuthStrategy;
8
- addStrategy(strategiesMap: Map<string, AuthStrategy>, type: string, strategyInstance: AuthStrategy | undefined): void;
9
- removeStrategy(type: string): boolean;
10
- hasStrategy(type: string): boolean;
11
- getStrategy(strategyName: string, layer?: "http" | "socket"): AuthStrategy | undefined;
12
- listStrategies(): string[];
8
+ addStrategy(strategyInstance: AuthStrategy | undefined, name: string, type: "http" | "socket"): void;
9
+ removeStrategy(name: string | string[], type: "http" | "socket"): void;
10
+ hasStrategy(name: string, type: "http" | "socket"): boolean;
11
+ getStrategy(name: string, type: "http" | "socket"): AuthStrategy | undefined;
12
+ listStrategies(type: "http" | "socket"): string[];
13
13
  init(sequential?: boolean): Promise<void>;
14
- authenticate(strategyName: string, context: any): Promise<AuthResult<any>>;
15
- logout(strategyName: string, context: any): Promise<void>;
14
+ authenticate(type: "http" | "socket", name: string, context: any): Promise<AuthResult<any>>;
15
+ logout(type: "http" | "socket", name: string, context: any): Promise<void>;
16
16
  }
@@ -5,71 +5,101 @@ const http_auth_strategy_factory_1 = require("./factories/http-auth-strategy.fac
5
5
  const socket_auth_strategy_factory_1 = require("./factories/socket-auth-strategy.factory");
6
6
  class SoapAuth {
7
7
  requiredStrategyMethods = ["authenticate", "init"];
8
- httpStrategies = new Map();
9
- socketStrategies = new Map();
8
+ strategies = new Map();
9
+ logger;
10
10
  constructor(config) {
11
11
  const httpFactory = new http_auth_strategy_factory_1.HttpAuthStrategyFactory(config.logger);
12
- this.httpStrategies = httpFactory.createStrategies(config);
13
12
  const socketFactory = new socket_auth_strategy_factory_1.SocketAuthStrategyFactory(config.logger);
14
- this.socketStrategies = socketFactory.createStrategies(config);
13
+ const httpStrategies = httpFactory.createStrategies(config);
14
+ const socketStrategies = socketFactory.createStrategies(config);
15
+ this.strategies.set("http", httpStrategies);
16
+ this.strategies.set("socket", socketStrategies);
17
+ this.logger = config.logger;
15
18
  }
16
19
  isAuthStrategy(strategy) {
17
- const isValidStrategy = this.requiredStrategyMethods.every((method) => typeof strategy[method] === "function");
18
- return isValidStrategy;
20
+ return (typeof strategy === "object" &&
21
+ strategy !== null &&
22
+ this.requiredStrategyMethods.every((method) => typeof strategy[method] === "function"));
19
23
  }
20
- addStrategy(strategiesMap, type, strategyInstance) {
24
+ addStrategy(strategyInstance, name, type) {
25
+ if (!this.strategies.has(type)) {
26
+ throw new Error(`Invalid strategy type "${type}". Expected "http" or "socket".`);
27
+ }
21
28
  if (this.isAuthStrategy(strategyInstance)) {
22
- strategiesMap.set(type, strategyInstance);
29
+ this.strategies.get(type).set(name, strategyInstance);
23
30
  }
24
- }
25
- removeStrategy(type) {
26
- if (this.httpStrategies.has(type)) {
27
- this.httpStrategies.delete(type);
28
- return true;
31
+ else {
32
+ this.logger?.error("Invalid authentication strategy provided.");
33
+ throw new Error("Invalid authentication strategy: does not implement required methods.");
29
34
  }
30
- if (this.socketStrategies.has(type)) {
31
- this.socketStrategies.delete(type);
32
- return true;
35
+ }
36
+ removeStrategy(name, type) {
37
+ if (!this.strategies.has(type)) {
38
+ throw new Error(`Invalid strategy type "${type}". Expected "http" or "socket".`);
33
39
  }
34
- return false;
40
+ const names = Array.isArray(name) ? name : [name];
41
+ names.forEach((n) => {
42
+ this.strategies.get(type).delete(n);
43
+ });
35
44
  }
36
- hasStrategy(type) {
37
- return this.httpStrategies.has(type) || this.socketStrategies.has(type);
45
+ hasStrategy(name, type) {
46
+ if (!this.strategies.has(type)) {
47
+ throw new Error(`Invalid strategy type "${type}". Expected "http" or "socket".`);
48
+ }
49
+ return this.strategies.get(type).has(name);
38
50
  }
39
- getStrategy(strategyName, layer = "http") {
40
- return layer === "http"
41
- ? this.httpStrategies.get(strategyName)
42
- : this.socketStrategies.get(strategyName);
51
+ getStrategy(name, type) {
52
+ if (!this.strategies.has(type)) {
53
+ throw new Error(`Invalid strategy type "${type}". Expected "http" or "socket".`);
54
+ }
55
+ const strategy = this.strategies.get(type).get(name);
56
+ if (!strategy) {
57
+ throw new Error(`Authentication strategy "${name}" not found.`);
58
+ }
59
+ return strategy;
43
60
  }
44
- listStrategies() {
45
- return [...this.httpStrategies.keys(), ...this.socketStrategies.keys()];
61
+ listStrategies(type) {
62
+ if (!this.strategies.has(type)) {
63
+ throw new Error(`Invalid strategy type "${type}". Expected "http" or "socket".`);
64
+ }
65
+ return Array.from(this.strategies.get(type).keys());
46
66
  }
47
67
  async init(sequential = false) {
48
68
  const strategies = [
49
- ...this.httpStrategies.values(),
50
- ...this.socketStrategies.values(),
69
+ ...this.strategies.get("http").values(),
70
+ ...this.strategies.get("socket").values(),
51
71
  ];
52
72
  if (sequential) {
53
73
  for (const strategy of strategies) {
54
- await strategy.init();
74
+ try {
75
+ await strategy.init();
76
+ }
77
+ catch (error) {
78
+ this.logger?.error(`Failed to initialize strategy: ${error.message}`);
79
+ }
55
80
  }
56
81
  }
57
82
  else {
58
- await Promise.all(strategies.map((strategy) => strategy.init()));
83
+ await Promise.all(strategies.map((strategy) => strategy
84
+ .init()
85
+ .catch((error) => this.logger?.error(`Failed to initialize strategy: ${error.message}`))));
59
86
  }
60
87
  }
61
- async authenticate(strategyName, context) {
62
- const strategy = this.getStrategy(strategyName);
88
+ async authenticate(type, name, context) {
89
+ const strategy = this.getStrategy(name, type);
63
90
  if (!strategy) {
64
- throw new Error(`Authentication strategy "${strategyName}" not found.`);
91
+ throw new Error(`Authentication strategy "${name}" not found.`);
65
92
  }
66
93
  return strategy.authenticate(context);
67
94
  }
68
- async logout(strategyName, context) {
69
- const strategy = this.getStrategy(strategyName);
95
+ async logout(type, name, context) {
96
+ const strategy = this.getStrategy(name, type);
70
97
  if (strategy?.logout) {
71
98
  await strategy.logout(context);
72
99
  }
100
+ else {
101
+ this.logger?.error(`No "logout" implementation in strategy "${name}".`);
102
+ }
73
103
  }
74
104
  }
75
105
  exports.SoapAuth = SoapAuth;