@soapjs/soap-auth 0.1.0 → 0.2.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.
- package/README.md +475 -8
- package/build/factories/http-auth-strategy.factory.js +1 -2
- package/build/factories/index.d.ts +3 -0
- package/build/factories/index.js +19 -0
- package/build/index.d.ts +4 -25
- package/build/index.js +4 -25
- package/build/session/index.d.ts +3 -0
- package/build/session/index.js +19 -0
- package/build/soap-auth.d.ts +9 -9
- package/build/soap-auth.js +64 -34
- package/build/strategies/api-key/api-key.strategy.d.ts +4 -3
- package/build/strategies/api-key/api-key.strategy.js +9 -6
- package/build/strategies/api-key/api-key.types.d.ts +2 -4
- package/build/strategies/base-auth.strategy.d.ts +4 -3
- package/build/strategies/base-auth.strategy.js +22 -6
- package/build/strategies/basic/basic.strategy.d.ts +5 -11
- package/build/strategies/basic/basic.strategy.js +14 -19
- package/build/strategies/basic/basic.types.d.ts +2 -2
- package/build/strategies/{credential-based-auth.strategy.d.ts → credential-auth.strategy.d.ts} +15 -12
- package/build/strategies/{credential-based-auth.strategy.js → credential-auth.strategy.js} +95 -46
- package/build/strategies/index.d.ts +16 -0
- package/build/strategies/index.js +32 -0
- package/build/strategies/jwt/jwt.strategy.d.ts +17 -2
- package/build/strategies/jwt/jwt.strategy.js +118 -45
- package/build/strategies/jwt/jwt.tools.d.ts +7 -3
- package/build/strategies/jwt/jwt.tools.js +80 -41
- package/build/strategies/jwt/jwt.types.d.ts +4 -14
- package/build/strategies/local/local.strategy.d.ts +3 -9
- package/build/strategies/local/local.strategy.js +7 -58
- package/build/strategies/local/local.types.d.ts +2 -2
- package/build/strategies/oauth2/oauth2.strategy.d.ts +21 -7
- package/build/strategies/oauth2/oauth2.strategy.js +161 -52
- package/build/strategies/oauth2/oauth2.types.d.ts +9 -17
- package/build/strategies/token-auth.strategy.d.ts +25 -0
- package/build/strategies/token-auth.strategy.js +78 -0
- package/build/tools/index.d.ts +3 -0
- package/build/tools/index.js +19 -0
- package/build/types.d.ts +94 -68
- package/package.json +3 -3
- package/build/strategies/token-based-auth.strategy.d.ts +0 -25
- package/build/strategies/token-based-auth.strategy.js +0 -124
package/README.md
CHANGED
|
@@ -1,6 +1,456 @@
|
|
|
1
|
-
# SoapAuth
|
|
1
|
+
# SoapAuth - Authentication Strategy Manager
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
1. [Introduction](#introduction)
|
|
6
|
+
- [What is `SoapAuth`?](#what-is-soapauth)
|
|
7
|
+
- [Key Features](#key-features)
|
|
8
|
+
- [Supported Authentication Strategies](#supported-authentication-strategies)
|
|
9
|
+
- [When to Use `SoapAuth`](#when-to-use-soapauth)
|
|
10
|
+
|
|
11
|
+
2. [Installation & Setup](#installation--setup)
|
|
12
|
+
- [Prerequisites](#prerequisites)
|
|
13
|
+
- [Installing `soap-auth`](#installing-soap-auth)
|
|
14
|
+
- [Basic Configuration](#basic-configuration)
|
|
15
|
+
|
|
16
|
+
3. [Core Concepts](#core-concepts)
|
|
17
|
+
- [Authentication Strategies (`AuthStrategy`)](#authentication-strategies-authstrategy)
|
|
18
|
+
- [`SoapAuth` Core Class Overview](#soapauth-core-class-overview)
|
|
19
|
+
- [How Strategies Work with `SoapAuth`](#how-strategies-work-with-soapauth)
|
|
20
|
+
- [HTTP vs. WebSocket Authentication](#http-vs-websocket-authentication)
|
|
21
|
+
|
|
22
|
+
4. [Implementing Strategies](#implementing-strategies)
|
|
23
|
+
|
|
24
|
+
<!-- WIP
|
|
25
|
+
5. [Using `SoapAuth` in Different Environments](#using-soapauth-in-different-environments)
|
|
26
|
+
- [Express.js Integration](#expressjs-integration)
|
|
27
|
+
- [Middleware Setup](#middleware-setup)
|
|
28
|
+
- [Protecting Routes](#protecting-routes)
|
|
29
|
+
- [Example: Authenticating Requests in Express](#example-authenticating-requests-in-express)
|
|
30
|
+
- [WebSocket Authentication](#websocket-authentication)
|
|
31
|
+
- [How WebSocket Authentication Works](#how-websocket-authentication-works)
|
|
32
|
+
- [Example: Securing WebSocket Connections](#example-securing-websocket-connections)
|
|
33
|
+
- [GraphQL Authentication](#graphql-authentication)
|
|
34
|
+
- [Using `SoapAuth` with Apollo Server](#using-soapauth-with-apollo-server)
|
|
35
|
+
- [Example: Adding Authentication to GraphQL Resolvers](#example-adding-authentication-to-graphql-resolvers)
|
|
36
|
+
- [Microservices & External APIs](#microservices--external-apis)
|
|
37
|
+
- [Using `SoapAuth` for Microservices](#using-soapauth-for-microservices)
|
|
38
|
+
- [Example: Validating API Requests from External Services](#example-validating-api-requests-from-external-services)
|
|
39
|
+
|
|
40
|
+
6. [Advanced Usage](#advanced-usage)
|
|
41
|
+
- [Handling Multiple Strategies Simultaneously](#handling-multiple-strategies-simultaneously)
|
|
42
|
+
- [Refreshing Tokens and Session Management](#refreshing-tokens-and-session-management)
|
|
43
|
+
- [Logging and Error Handling](#logging-and-error-handling) -->
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
## 1️. Introduction
|
|
47
|
+
|
|
48
|
+
### What is `SoapAuth`?
|
|
49
|
+
|
|
50
|
+
`SoapAuth` is a **flexible authentication strategy manager** and one of the core modules of `@soapjs` – a toolkit for building clean architecture-based applications efficiently.
|
|
51
|
+
|
|
52
|
+
It provides a **structured and extensible approach** to authentication, allowing developers to manage multiple authentication strategies across different environments, including **HTTP APIs (Express.js), WebSockets, GraphQL, and microservices**.
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
With `SoapAuth`, you can:
|
|
56
|
+
|
|
57
|
+
- Easily **add, remove, and switch authentication strategies** dynamically.
|
|
58
|
+
- Support **OAuth2, JWT, API Keys, and custom authentication strategies**.
|
|
59
|
+
- Use it in **Express.js, WebSockets, GraphQL, and microservices**.
|
|
60
|
+
- Handle **token refresh, session management, and error handling** efficiently.
|
|
61
|
+
|
|
62
|
+
### Key Features
|
|
63
|
+
|
|
64
|
+
✔ **Multi-strategy support** – Use different authentication methods within the same application.
|
|
65
|
+
✔ **Modular and extensible** – Easily add new authentication strategies.
|
|
66
|
+
✔ **Works with HTTP & WebSockets** – Supports both request-based and persistent connection authentication.
|
|
67
|
+
✔ **Easy integration** – Plug it into Express, WebSockets, GraphQL, or any custom API.
|
|
68
|
+
✔ **Dynamic management** – Add, remove, or update authentication strategies at runtime.
|
|
69
|
+
✔ **Built-in logging and debugging** – Helps troubleshoot authentication issues.
|
|
70
|
+
|
|
71
|
+
### Supported Authentication Strategies
|
|
72
|
+
|
|
73
|
+
| Strategy Type | Description |
|
|
74
|
+
|--------------------|------------|
|
|
75
|
+
| **OAuth2** | Authenticate users via external providers like Google, Facebook, or GitHub. |
|
|
76
|
+
| **JWT (JSON Web Token)** | Secure API endpoints with token-based authentication. |
|
|
77
|
+
| **API Key** | Use API keys for authentication in RESTful services. |
|
|
78
|
+
| **Custom Strategies** | Define your own authentication mechanisms based on your needs. |
|
|
79
|
+
|
|
80
|
+
### When to Use `SoapAuth`?
|
|
81
|
+
|
|
82
|
+
Use `SoapAuth` if you need:
|
|
83
|
+
|
|
84
|
+
- **Multiple authentication methods** in your application (e.g., JWT for API + OAuth2 for users).
|
|
85
|
+
- **A structured way** to manage authentication across different request types (HTTP, WebSockets).
|
|
86
|
+
- **Flexibility to swap authentication methods** without modifying business logic.
|
|
87
|
+
- **Easy expansion** with custom authentication strategies.
|
|
88
|
+
|
|
89
|
+
## 2️. Installation & Setup
|
|
90
|
+
|
|
91
|
+
### Prerequisites
|
|
92
|
+
|
|
93
|
+
Before installing `soap-auth`, ensure you have the following:
|
|
94
|
+
|
|
95
|
+
- **Node.js** (v16+ recommended)
|
|
96
|
+
- **TypeScript** (optional but recommended for type safety)
|
|
97
|
+
- **A package manager** (`npm`, `yarn`, or `pnpm`)
|
|
98
|
+
|
|
99
|
+
### Installing `soap-auth`
|
|
100
|
+
|
|
101
|
+
You can install `soap-auth` using your preferred package manager:
|
|
102
|
+
|
|
103
|
+
```sh
|
|
104
|
+
# Using npm
|
|
105
|
+
npm install @soapjs/soap-auth
|
|
106
|
+
|
|
107
|
+
# Using yarn
|
|
108
|
+
yarn add @soapjs/soap-auth
|
|
109
|
+
|
|
110
|
+
# Using pnpm
|
|
111
|
+
pnpm add @soapjs/soap-auth
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Basic Configuration
|
|
115
|
+
|
|
116
|
+
`soap-auth` serves as the **core authentication manager** within the `@soapjs` ecosystem. It provides a **framework-agnostic foundation** for authentication strategies and is designed to be extended for use in specific frameworks like Express, WebSockets, and others.
|
|
117
|
+
|
|
118
|
+
To start using `soap-auth`, you need to configure it with authentication strategies.
|
|
119
|
+
|
|
120
|
+
#### **1️. Import `SoapAuth` and Define Strategies**
|
|
121
|
+
Create an `auth.ts` file where you initialize `SoapAuth` with the authentication strategies you plan to use.
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
import { SoapAuth } from "@soapjs/soap-auth";
|
|
125
|
+
import { OAuth2Strategy, JwtStrategy } from "@soapjs/soap-auth";
|
|
126
|
+
|
|
127
|
+
const soapAuth = new SoapAuth({
|
|
128
|
+
strategies: {
|
|
129
|
+
http: {
|
|
130
|
+
oauth2: new OAuth2Strategy({
|
|
131
|
+
clientId: "your-client-id",
|
|
132
|
+
clientSecret: "your-client-secret",
|
|
133
|
+
endpoints: {
|
|
134
|
+
authorizationUrl: "https://provider.com/oauth/authorize",
|
|
135
|
+
tokenUrl: "https://provider.com/oauth/token",
|
|
136
|
+
userInfoUrl: "https://provider.com/userinfo",
|
|
137
|
+
},
|
|
138
|
+
}),
|
|
139
|
+
jwt: new JwtStrategy({
|
|
140
|
+
accessToken: {
|
|
141
|
+
issuer: {
|
|
142
|
+
secretKey: "your-jwt-secret",
|
|
143
|
+
options: {
|
|
144
|
+
issuer: "your-app",
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
routes: {
|
|
149
|
+
login: { path: "your-login-path" method: "POST" },
|
|
150
|
+
logout: { path: "your-logout-path" method: "POST" },
|
|
151
|
+
...
|
|
152
|
+
},
|
|
153
|
+
}),
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
logger: console, // Optional logging
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
export default soapAuth;
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
#### **2️. Initialize Strategies**
|
|
163
|
+
Before using authentication, ensure all strategies are properly initialized.
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
await soapAuth.init();
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### **3️. Authenticating Requests**
|
|
170
|
+
To authenticate a request using a specific strategy:
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
const authResult = await soapAuth.authenticate("http", "jwt", request);
|
|
174
|
+
console.log(authResult.user);
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Framework-Specific Implementations
|
|
178
|
+
|
|
179
|
+
`soap-auth` serves as the **foundation** for authentication in multiple environments. Specific implementations for frameworks like **Express.js, WebSockets, and GraphQL** are built on top of it.
|
|
180
|
+
|
|
181
|
+
If you're using a specific framework, consider installing its dedicated package:
|
|
182
|
+
|
|
183
|
+
```sh
|
|
184
|
+
# Express.js soap package (WIP)
|
|
185
|
+
npm install @soapjs/soap-express
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
These packages extend `soap-auth`, providing **plug-and-play middleware** for authentication in framework-specific contexts.
|
|
190
|
+
|
|
191
|
+
## 3️. Core Concepts
|
|
192
|
+
|
|
193
|
+
### Authentication Strategies (`AuthStrategy`)
|
|
194
|
+
|
|
195
|
+
At the core of `soap-auth` is the concept of **authentication strategies**, which define how authentication should be performed. Each strategy is responsible for:
|
|
196
|
+
|
|
197
|
+
- Extracting credentials or tokens from the request.
|
|
198
|
+
- Validating the provided credentials.
|
|
199
|
+
- Returning an authenticated user or rejecting the request.
|
|
200
|
+
|
|
201
|
+
Examples of authentication strategies include **OAuth2, JWT, API Keys, and custom strategies**.
|
|
202
|
+
|
|
203
|
+
### `SoapAuth` Core Class Overview
|
|
204
|
+
|
|
205
|
+
The `SoapAuth` class serves as the **authentication manager**, handling multiple authentication strategies within an application. It allows developers to:
|
|
206
|
+
|
|
207
|
+
- **Register authentication strategies** dynamically.
|
|
208
|
+
- **Manage authentication across different layers** (HTTP, WebSockets, GraphQL, etc.).
|
|
209
|
+
- **Authenticate requests** using specific strategies.
|
|
210
|
+
- **Handle token storage, session management, and error handling**.
|
|
211
|
+
|
|
212
|
+
### How Strategies Work with `SoapAuth`
|
|
213
|
+
|
|
214
|
+
1. **A user sends a request** (e.g., HTTP request, WebSocket connection).
|
|
215
|
+
2. **`SoapAuth` selects the appropriate strategy** based on the request context.
|
|
216
|
+
3. **The selected strategy authenticates the request** by validating tokens, credentials, or API keys.
|
|
217
|
+
4. **If authentication succeeds, the user is granted access**; otherwise, an error is returned.
|
|
218
|
+
|
|
219
|
+
### HTTP vs. WebSocket Authentication
|
|
220
|
+
|
|
221
|
+
| Feature | HTTP Authentication | WebSocket Authentication |
|
|
222
|
+
|---------|----------------------|--------------------------|
|
|
223
|
+
| Request Type | One-time requests | Persistent connection |
|
|
224
|
+
| Example Strategies | OAuth2, JWT, API Key | Token-based, session-based |
|
|
225
|
+
| Validation | Per request | On connection + periodic checks |
|
|
226
|
+
|
|
227
|
+
- **For HTTP**, authentication is performed **on each request**.
|
|
228
|
+
- **For WebSockets**, authentication happens **once on connection** and may include **token refresh checks** during the session.
|
|
229
|
+
|
|
230
|
+
Understanding these differences helps in choosing the right strategy for your use case.
|
|
231
|
+
|
|
232
|
+
## 4️. Implementing Strategies
|
|
233
|
+
|
|
234
|
+
### Built-in Authentication Strategies
|
|
235
|
+
|
|
236
|
+
`soap-auth` provides built-in support for multiple authentication strategies:
|
|
237
|
+
|
|
238
|
+
1. **Basic Authentication** - Username & password via HTTP headers.
|
|
239
|
+
2. **Local Authentication** - Custom credential-based authentication.
|
|
240
|
+
3. **API Key Authentication** - Secure access using an API key.
|
|
241
|
+
4. **JWT Authentication** - Token-based authentication using JSON Web Tokens.
|
|
242
|
+
5. **OAuth2 Authentication** - Third-party authentication with OAuth2 providers.
|
|
243
|
+
|
|
244
|
+
Each strategy is **configurable** and can be **easily extended** or **customized**.
|
|
245
|
+
|
|
246
|
+
### **Basic Authentication (Username & Password)**
|
|
247
|
+
Basic authentication works by extracting credentials from an `Authorization` header.
|
|
248
|
+
|
|
249
|
+
```ts
|
|
250
|
+
import { BasicStrategy } from "@soapjs/soap-auth/strategies/basic.strategy";
|
|
251
|
+
|
|
252
|
+
const basicAuth = new BasicStrategy({
|
|
253
|
+
credentials: {
|
|
254
|
+
extractCredentials: (context) => {
|
|
255
|
+
const authHeader = context.headers?.authorization;
|
|
256
|
+
if (!authHeader || !authHeader.startsWith("Basic ")) return null;
|
|
257
|
+
const decoded = Buffer.from(authHeader.substring(6), "base64").toString();
|
|
258
|
+
const [username, password] = decoded.split(":");
|
|
259
|
+
return { identifier: username, password };
|
|
260
|
+
},
|
|
261
|
+
verifyCredentials: async (username, password) => {
|
|
262
|
+
const user = await database.getUser(username);
|
|
263
|
+
return user && user.password === password;
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
user: {
|
|
267
|
+
getUserData: async (identifier) => database.getUser(identifier),
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
#### **Authenticating a Request**
|
|
273
|
+
```ts
|
|
274
|
+
const authResult = await basicAuth.authenticate(request);
|
|
275
|
+
console.log(authResult.user);
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### **Local Authentication (Custom Credential System)**
|
|
279
|
+
Local authentication allows custom username/password authentication.
|
|
280
|
+
|
|
281
|
+
```ts
|
|
282
|
+
import { LocalStrategy } from "@soapjs/soap-auth/strategies/local.strategy";
|
|
283
|
+
|
|
284
|
+
const localAuth = new LocalStrategy({
|
|
285
|
+
credentials: {
|
|
286
|
+
extractCredentials: (context) => ({
|
|
287
|
+
identifier: context.body.username,
|
|
288
|
+
password: context.body.password,
|
|
289
|
+
}),
|
|
290
|
+
verifyCredentials: async (username, password) => {
|
|
291
|
+
const user = await database.getUser(username);
|
|
292
|
+
return user && user.password === password;
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
user: {
|
|
296
|
+
getUserData: async (identifier) => database.getUser(identifier),
|
|
297
|
+
},
|
|
298
|
+
});
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
#### **Authenticating a Request**
|
|
302
|
+
```ts
|
|
303
|
+
const authResult = await localAuth.authenticate(request);
|
|
304
|
+
console.log(authResult.user);
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### **API Key Authentication**
|
|
308
|
+
API Key authentication extracts and verifies API keys sent in headers.
|
|
309
|
+
|
|
310
|
+
```ts
|
|
311
|
+
import { ApiKeyStrategy } from "@soapjs/soap-auth/strategies/api-key.strategy";
|
|
312
|
+
|
|
313
|
+
const apiKeyAuth = new ApiKeyStrategy({
|
|
314
|
+
extractApiKey: (context) => context.headers["x-api-key"],
|
|
315
|
+
retrieveUserByApiKey: async (apiKey) => database.getUserByApiKey(apiKey),
|
|
316
|
+
authorize: async (user, action) => user.permissions.includes(action),
|
|
317
|
+
isApiKeyExpired: async (apiKey) => false,
|
|
318
|
+
});
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
#### **Authenticating a Request**
|
|
322
|
+
```ts
|
|
323
|
+
const authResult = await apiKeyAuth.authenticate(request);
|
|
324
|
+
console.log(authResult.user);
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### **JWT Authentication**
|
|
328
|
+
JWT authentication verifies JSON Web Tokens (JWTs) passed in headers.
|
|
329
|
+
|
|
330
|
+
```ts
|
|
331
|
+
import { JwtStrategy } from "@soapjs/soap-auth/strategies/jwt.strategy";
|
|
332
|
+
|
|
333
|
+
const jwtAuth = new JwtStrategy({
|
|
334
|
+
accessToken: {
|
|
335
|
+
issuer: {
|
|
336
|
+
secretKey: "your-secret-key",
|
|
337
|
+
options: { expiresIn: "1h" },
|
|
338
|
+
},
|
|
339
|
+
retrieve: (context) => context.headers.authorization?.split(" ")[1],
|
|
340
|
+
},
|
|
341
|
+
user: {
|
|
342
|
+
getUserData: async (decodedToken) => database.getUser(decodedToken.sub),
|
|
343
|
+
},
|
|
344
|
+
});
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
#### **Authenticating a Request**
|
|
348
|
+
```ts
|
|
349
|
+
const authResult = await jwtAuth.authenticate(request);
|
|
350
|
+
console.log(authResult.user);
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### **OAuth2 Authentication**
|
|
354
|
+
OAuth2 authentication enables integration with third-party providers.
|
|
355
|
+
|
|
356
|
+
```ts
|
|
357
|
+
import { OAuth2Strategy } from "@soapjs/soap-auth/strategies/oauth2.strategy";
|
|
358
|
+
|
|
359
|
+
const oauth2Auth = new OAuth2Strategy({
|
|
360
|
+
clientId: "your-client-id",
|
|
361
|
+
clientSecret: "your-client-secret",
|
|
362
|
+
redirectUri: "https://your-app.com/callback",
|
|
363
|
+
grantType: "authorization_code",
|
|
364
|
+
endpoints: {
|
|
365
|
+
authorizationUrl: "https://provider.com/oauth/authorize",
|
|
366
|
+
tokenUrl: "https://provider.com/oauth/token",
|
|
367
|
+
userInfoUrl: "https://provider.com/userinfo",
|
|
368
|
+
},
|
|
369
|
+
user: {
|
|
370
|
+
validateUser: async (userData) => database.getUser(userData.email),
|
|
371
|
+
},
|
|
372
|
+
});
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
#### **Authenticating a Request**
|
|
376
|
+
```ts
|
|
377
|
+
const authResult = await oauth2Auth.authenticate(request);
|
|
378
|
+
console.log(authResult.user);
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### **Custom Authentication Strategy**
|
|
382
|
+
If you need a custom authentication method, you can extend `AuthStrategy`.
|
|
383
|
+
|
|
384
|
+
```ts
|
|
385
|
+
import { AuthStrategy } from "@soapjs/soap-auth";
|
|
386
|
+
|
|
387
|
+
class CustomAuthStrategy extends AuthStrategy {
|
|
388
|
+
async authenticate(context) {
|
|
389
|
+
const user = await database.findUser(context.credentials);
|
|
390
|
+
return user ? { user } : null;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### **Using other auth libraries with `soap-auth`**
|
|
396
|
+
Instead of implementing authentication manually, you can integrate `passport.js`.
|
|
397
|
+
|
|
398
|
+
```ts
|
|
399
|
+
import passport from "passport";
|
|
400
|
+
import { Strategy as FacebookStrategy } from "passport-facebook";
|
|
401
|
+
import { AuthStrategy } from "@soapjs/soap-auth";
|
|
402
|
+
|
|
403
|
+
class PassportAuthStrategy extends AuthStrategy {
|
|
404
|
+
|
|
405
|
+
init() {
|
|
406
|
+
passport.use(
|
|
407
|
+
new FacebookStrategy(
|
|
408
|
+
{
|
|
409
|
+
clientID: "your-facebook-client-id",
|
|
410
|
+
clientSecret: "your-facebook-client-secret",
|
|
411
|
+
callbackURL: "/auth/facebook/callback",
|
|
412
|
+
profileFields: ["id", "emails", "displayName"],
|
|
413
|
+
},
|
|
414
|
+
async (accessToken, refreshToken, profile, done) => {
|
|
415
|
+
const user = await database.findOrCreateUser(profile);
|
|
416
|
+
return done(null, user);
|
|
417
|
+
}
|
|
418
|
+
)
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
async authenticate(context) {
|
|
422
|
+
return new Promise((resolve, reject) => {
|
|
423
|
+
passport.authenticate("facebook", (error, user) => {
|
|
424
|
+
if (error || !user) return reject(new Error("Authentication failed"));
|
|
425
|
+
resolve({ user });
|
|
426
|
+
})(context.request, context.response);
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
|
|
2
453
|
|
|
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
454
|
|
|
5
455
|
---
|
|
6
456
|
|
|
@@ -34,13 +484,16 @@ The base interface that all strategies must implement. Provides methods such as
|
|
|
34
484
|
### 3. `SessionHandler`
|
|
35
485
|
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
486
|
|
|
37
|
-
### 4. `
|
|
487
|
+
### 4. `TokenAuthStrategy`
|
|
488
|
+
Abstract class for token-based authentication strategies, providing methods for handling access and refresh tokens.
|
|
489
|
+
|
|
490
|
+
### 5. `OAuth2Strategy`
|
|
38
491
|
Abstract class for token-based authentication strategies, providing methods for handling access and refresh tokens.
|
|
39
492
|
|
|
40
|
-
###
|
|
493
|
+
### 6. `CredentialAuthStrategy`
|
|
41
494
|
Abstract class for username-password-based authentication strategies.
|
|
42
495
|
|
|
43
|
-
###
|
|
496
|
+
### 7. `HttpAuthStrategyFactory` & `SocketAuthStrategyFactory`
|
|
44
497
|
Factories responsible for creating instances of HTTP and socket-based authentication strategies respectively.
|
|
45
498
|
|
|
46
499
|
---
|
|
@@ -169,13 +622,13 @@ console.log("Authenticated user:", user);
|
|
|
169
622
|
|
|
170
623
|
To create a custom strategy, extend the appropriate base class depending on the authentication type:
|
|
171
624
|
|
|
172
|
-
1. **For token-based strategies:** Extend `
|
|
173
|
-
2. **For credential-based strategies:** Extend `
|
|
625
|
+
1. **For token-based strategies:** Extend `TokenAuthStrategy`.
|
|
626
|
+
2. **For credential-based strategies:** Extend `CredentialAuthStrategy`.
|
|
174
627
|
3. **For generic implementations:** Extend `BaseAuthStrategy` directly.
|
|
175
628
|
|
|
176
629
|
**Example:**
|
|
177
630
|
```typescript
|
|
178
|
-
class CustomAuthStrategy extends
|
|
631
|
+
class CustomAuthStrategy extends TokenAuthStrategy {
|
|
179
632
|
async authenticate(context) {
|
|
180
633
|
const token = context.headers.authorization;
|
|
181
634
|
if (token === "valid-token") {
|
|
@@ -221,3 +674,17 @@ app.use(async (req, res, next) => {
|
|
|
221
674
|
}
|
|
222
675
|
});
|
|
223
676
|
```
|
|
677
|
+
## Issues
|
|
678
|
+
If you encounter any issues, please feel free to report them [here](https://github.com/soapjs/soap/issues/new/choose).
|
|
679
|
+
|
|
680
|
+
## Contact
|
|
681
|
+
For any questions, collaboration interests, or support needs, you can contact us through the following:
|
|
682
|
+
|
|
683
|
+
- Official:
|
|
684
|
+
- Website: http://docs.soapjs.com
|
|
685
|
+
- Radoslaw Kamysz:
|
|
686
|
+
- Email: [radoslaw.kamysz@gmail.com](mailto:radoslaw.kamysz@gmail.com)
|
|
687
|
+
- Warpcast: [@k4mr4ad](https://warpcast.com/k4mr4ad)
|
|
688
|
+
- Twitter: [@radoslawkamysz](https://x.com/radoslawkamysz)
|
|
689
|
+
## License
|
|
690
|
+
SoapJS is licensed under the MIT License.
|
|
@@ -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],
|
|
18
|
+
strategies.set(provider, new oauth2_strategy_1.OAuth2Strategy(config.http.oauth2[provider], this.getSessionHandler(config.http.oauth2[provider].session, config.session), config.logger));
|
|
20
19
|
}
|
|
21
20
|
}
|
|
22
21
|
if (config.http.apiKey) {
|
|
@@ -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
|
|
2
|
-
export * from "./
|
|
3
|
-
export * from "./
|
|
4
|
-
export * from "./
|
|
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
|
|
18
|
-
__exportStar(require("./
|
|
19
|
-
__exportStar(require("./
|
|
20
|
-
__exportStar(require("./
|
|
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,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);
|
package/build/soap-auth.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { AuthResult, AuthStrategy, SoapAuthConfig } from "./types";
|
|
2
2
|
export declare class SoapAuth {
|
|
3
3
|
private requiredStrategyMethods;
|
|
4
|
-
private
|
|
5
|
-
private
|
|
4
|
+
private strategies;
|
|
5
|
+
private logger?;
|
|
6
6
|
constructor(config: SoapAuthConfig);
|
|
7
7
|
private isAuthStrategy;
|
|
8
|
-
addStrategy(
|
|
9
|
-
removeStrategy(type:
|
|
10
|
-
hasStrategy(type:
|
|
11
|
-
getStrategy(
|
|
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(
|
|
15
|
-
logout(
|
|
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
|
}
|