@venizia/ignis-docs 0.0.6-2 → 0.0.7-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 +125 -388
- package/dist/mcp-server/common/config.d.ts +0 -21
- package/dist/mcp-server/common/config.d.ts.map +1 -1
- package/dist/mcp-server/common/config.js +1 -36
- package/dist/mcp-server/common/config.js.map +1 -1
- package/dist/mcp-server/helpers/docs.helper.d.ts +0 -24
- package/dist/mcp-server/helpers/docs.helper.d.ts.map +1 -1
- package/dist/mcp-server/helpers/docs.helper.js +0 -25
- package/dist/mcp-server/helpers/docs.helper.js.map +1 -1
- package/dist/mcp-server/helpers/github.helper.d.ts +0 -13
- package/dist/mcp-server/helpers/github.helper.d.ts.map +1 -1
- package/dist/mcp-server/helpers/github.helper.js +3 -20
- package/dist/mcp-server/helpers/github.helper.js.map +1 -1
- package/dist/mcp-server/index.js +1 -20
- package/dist/mcp-server/index.js.map +1 -1
- package/dist/mcp-server/tools/base.tool.d.ts +4 -85
- package/dist/mcp-server/tools/base.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/base.tool.js +1 -38
- package/dist/mcp-server/tools/base.tool.js.map +1 -1
- package/dist/mcp-server/tools/docs/get-document-content.tool.d.ts +8 -2
- package/dist/mcp-server/tools/docs/get-document-content.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/docs/get-document-content.tool.js +1 -10
- package/dist/mcp-server/tools/docs/get-document-content.tool.js.map +1 -1
- package/dist/mcp-server/tools/docs/get-document-metadata.tool.d.ts +13 -2
- package/dist/mcp-server/tools/docs/get-document-metadata.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/docs/get-document-metadata.tool.js +1 -10
- package/dist/mcp-server/tools/docs/get-document-metadata.tool.js.map +1 -1
- package/dist/mcp-server/tools/docs/get-package-overview.tool.d.ts +16 -8
- package/dist/mcp-server/tools/docs/get-package-overview.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/docs/get-package-overview.tool.js +2 -25
- package/dist/mcp-server/tools/docs/get-package-overview.tool.js.map +1 -1
- package/dist/mcp-server/tools/docs/list-categories.tool.d.ts +5 -2
- package/dist/mcp-server/tools/docs/list-categories.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/docs/list-categories.tool.js +1 -10
- package/dist/mcp-server/tools/docs/list-categories.tool.js.map +1 -1
- package/dist/mcp-server/tools/docs/list-documents.tool.d.ts +11 -2
- package/dist/mcp-server/tools/docs/list-documents.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/docs/list-documents.tool.js +1 -10
- package/dist/mcp-server/tools/docs/list-documents.tool.js.map +1 -1
- package/dist/mcp-server/tools/docs/search-documents.tool.d.ts +13 -2
- package/dist/mcp-server/tools/docs/search-documents.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/docs/search-documents.tool.js +1 -10
- package/dist/mcp-server/tools/docs/search-documents.tool.js.map +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +9 -2
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.js +1 -10
- package/dist/mcp-server/tools/github/list-project-files.tool.js.map +1 -1
- package/dist/mcp-server/tools/github/search-code.tool.d.ts +16 -2
- package/dist/mcp-server/tools/github/search-code.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/search-code.tool.js +2 -14
- package/dist/mcp-server/tools/github/search-code.tool.js.map +1 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.d.ts +19 -6
- package/dist/mcp-server/tools/github/verify-dependencies.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js +2 -19
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js.map +1 -1
- package/dist/mcp-server/tools/github/view-source-file.tool.d.ts +8 -2
- package/dist/mcp-server/tools/github/view-source-file.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/view-source-file.tool.js +1 -10
- package/dist/mcp-server/tools/github/view-source-file.tool.js.map +1 -1
- package/dist/mcp-server/tools/index.d.ts.map +1 -1
- package/dist/mcp-server/tools/index.js +0 -2
- package/dist/mcp-server/tools/index.js.map +1 -1
- package/package.json +68 -54
- package/wiki/best-practices/api-usage-examples.md +7 -5
- package/wiki/best-practices/code-style-standards/advanced-patterns.md +1 -1
- package/wiki/best-practices/code-style-standards/constants-configuration.md +1 -1
- package/wiki/best-practices/code-style-standards/control-flow.md +1 -1
- package/wiki/best-practices/code-style-standards/function-patterns.md +1 -1
- package/wiki/best-practices/common-pitfalls.md +1 -1
- package/wiki/best-practices/data-modeling.md +33 -1
- package/wiki/best-practices/error-handling.md +7 -4
- package/wiki/best-practices/performance-optimization.md +1 -1
- package/wiki/best-practices/security-guidelines.md +5 -4
- package/wiki/guides/core-concepts/components-guide.md +1 -1
- package/wiki/guides/core-concepts/controllers.md +14 -8
- package/wiki/guides/core-concepts/persistent/models.md +32 -0
- package/wiki/guides/core-concepts/services.md +2 -1
- package/wiki/guides/get-started/5-minute-quickstart.md +1 -1
- package/wiki/guides/reference/mcp-docs-server.md +0 -134
- package/wiki/guides/tutorials/building-a-crud-api.md +2 -1
- package/wiki/guides/tutorials/complete-installation.md +2 -2
- package/wiki/guides/tutorials/ecommerce-api.md +3 -3
- package/wiki/guides/tutorials/realtime-chat.md +7 -6
- package/wiki/index.md +2 -1
- package/wiki/references/base/components.md +2 -1
- package/wiki/references/base/controllers.md +19 -12
- package/wiki/references/base/middlewares.md +2 -1
- package/wiki/references/base/models.md +11 -2
- package/wiki/references/base/services.md +2 -1
- package/wiki/references/components/authentication/api.md +525 -205
- package/wiki/references/components/authentication/errors.md +502 -105
- package/wiki/references/components/authentication/index.md +388 -75
- package/wiki/references/components/authentication/usage.md +428 -266
- package/wiki/references/components/authorization/api.md +1213 -0
- package/wiki/references/components/authorization/errors.md +387 -0
- package/wiki/references/components/authorization/index.md +712 -0
- package/wiki/references/components/authorization/usage.md +758 -0
- package/wiki/references/components/health-check.md +2 -1
- package/wiki/references/components/index.md +2 -0
- package/wiki/references/components/socket-io/index.md +9 -4
- package/wiki/references/components/socket-io/usage.md +1 -1
- package/wiki/references/components/static-asset/index.md +3 -5
- package/wiki/references/components/swagger.md +2 -1
- package/wiki/references/configuration/environment-variables.md +2 -1
- package/wiki/references/configuration/index.md +2 -1
- package/wiki/references/helpers/error/index.md +1 -1
- package/wiki/references/helpers/index.md +1 -0
- package/wiki/references/helpers/inversion/index.md +1 -1
- package/wiki/references/helpers/kafka/index.md +305 -0
- package/wiki/references/helpers/redis/index.md +2 -9
- package/wiki/references/quick-reference.md +3 -5
- package/wiki/references/utilities/crypto.md +2 -2
- package/wiki/references/utilities/date.md +5 -5
- package/wiki/references/utilities/index.md +3 -11
- package/wiki/references/utilities/jsx.md +4 -2
- package/wiki/references/utilities/module.md +1 -1
- package/wiki/references/utilities/parse.md +4 -4
- package/wiki/references/utilities/performance.md +2 -2
- package/wiki/references/utilities/promise.md +4 -4
- package/wiki/references/utilities/request.md +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Authentication -- Setup & Configuration
|
|
2
2
|
|
|
3
|
-
> JWT and
|
|
3
|
+
> JWT authentication with JWS (symmetric) and JWKS (asymmetric) standards, optional AES-encrypted payloads, Basic HTTP authentication, multi-strategy support, and built-in auth controller
|
|
4
4
|
|
|
5
5
|
## Quick Reference
|
|
6
6
|
|
|
@@ -16,21 +16,44 @@
|
|
|
16
16
|
|-----------|---------|
|
|
17
17
|
| **AuthenticateComponent** | Main component registering auth services and controllers |
|
|
18
18
|
| **AuthenticationStrategyRegistry** | Singleton managing available auth strategies |
|
|
19
|
-
| **
|
|
19
|
+
| **JWSAuthenticationStrategy** | JWT verification using symmetric `JWSTokenService` (HS256) |
|
|
20
|
+
| **JWKSIssuerAuthenticationStrategy** | JWT verification using asymmetric `JWKSIssuerTokenService` (ES256/RS256/EdDSA) |
|
|
21
|
+
| **JWKSVerifierAuthenticationStrategy** | JWT verification via remote JWKS URL |
|
|
20
22
|
| **BasicAuthenticationStrategy** | Basic HTTP authentication using `BasicTokenService` |
|
|
21
|
-
| **
|
|
23
|
+
| **AbstractBearerTokenService** | Base class for all Bearer token services (JWS, JWKS Issuer, JWKS Verifier) |
|
|
24
|
+
| **JWSTokenService** | Symmetric JWT — sign, verify, optional AES encrypt/decrypt |
|
|
25
|
+
| **JWKSIssuerTokenService** | Asymmetric JWT — sign with private key, verify with public key, serve JWKS endpoint |
|
|
26
|
+
| **JWKSVerifierTokenService** | Asymmetric JWT — verify-only via remote JWKS URL |
|
|
22
27
|
| **BasicTokenService** | Extract and verify Basic auth credentials |
|
|
28
|
+
| **JWKSController** | Serves `/.well-known/jwks.json`-style endpoint at `/certs` |
|
|
23
29
|
| **IAuthService** | Interface for custom auth implementation (sign-in, sign-up) |
|
|
24
30
|
| **defineAuthController** | Factory function for creating custom auth controllers |
|
|
25
|
-
| **
|
|
31
|
+
| **AbstractJWKSTokenService** | Base class for JWKS services with lazy initialization and retry-on-failure |
|
|
32
|
+
| **authenticate** | Standalone middleware function using `AuthenticationProvider` to create auth middleware |
|
|
33
|
+
|
|
34
|
+
### JOSE Standards
|
|
35
|
+
|
|
36
|
+
The authentication module supports two JOSE (JSON Object Signing and Encryption) standards:
|
|
37
|
+
|
|
38
|
+
| Standard | Class | Use Case | Signing | Key Type |
|
|
39
|
+
|----------|-------|----------|---------|----------|
|
|
40
|
+
| **JWS** | `JWSTokenService` | Single-service apps where the same service signs and verifies | HS256 (symmetric) | Shared secret (`jwtSecret`) |
|
|
41
|
+
| **JWKS (Issuer)** | `JWKSIssuerTokenService` | Multi-service / microservice architectures where one service issues tokens | ES256 / RS256 / EdDSA (asymmetric) | Private key (sign) + Public key (verify) |
|
|
42
|
+
| **JWKS (Verifier)** | `JWKSVerifierTokenService` | Services that only verify tokens issued by another service | N/A (verify-only) | Remote JWKS URL |
|
|
26
43
|
|
|
27
44
|
### Environment Variables
|
|
28
45
|
|
|
29
46
|
| Variable | Purpose | Required |
|
|
30
47
|
|----------|---------|----------|
|
|
31
|
-
| `
|
|
32
|
-
| `
|
|
33
|
-
| `APP_ENV_JWT_EXPIRES_IN` | Token expiration (seconds) |
|
|
48
|
+
| `APP_ENV_JWT_SECRET` | Sign and verify JWT signature (JWS only) | Required for JWS |
|
|
49
|
+
| `APP_ENV_APPLICATION_SECRET` | AES-encrypt JWT payload fields | Optional |
|
|
50
|
+
| `APP_ENV_JWT_EXPIRES_IN` | Token expiration (seconds) | Required |
|
|
51
|
+
| `APP_ENV_JWKS_ALGORITHM` | JWKS signing algorithm (e.g., `ES256`) | Required for JWKS |
|
|
52
|
+
| `APP_ENV_JWKS_KEY_DRIVER` | Key source: `text` or `file` | Required for JWKS |
|
|
53
|
+
| `APP_ENV_JWKS_KEY_FORMAT` | Key format: `pem` or `jwk` | Required for JWKS |
|
|
54
|
+
| `APP_ENV_JWKS_PRIVATE_KEY` | Private key content or file path | Required for JWKS Issuer |
|
|
55
|
+
| `APP_ENV_JWKS_PUBLIC_KEY` | Public key content or file path | Required for JWKS Issuer |
|
|
56
|
+
| `APP_ENV_JWKS_KID` | Key ID for JWKS endpoint | Required for JWKS Issuer |
|
|
34
57
|
|
|
35
58
|
### Auth Modes
|
|
36
59
|
|
|
@@ -51,10 +74,6 @@
|
|
|
51
74
|
|
|
52
75
|
| Constant | Value | Description |
|
|
53
76
|
|----------|-------|-------------|
|
|
54
|
-
| `Authentication.ACCESS_TOKEN_SECRET` | `'token.secret'` | Default access token secret key |
|
|
55
|
-
| `Authentication.ACCESS_TOKEN_EXPIRES_IN` | `86400` | Default access token expiration (seconds, 24h) |
|
|
56
|
-
| `Authentication.REFRESH_TOKEN_SECRET` | `'refresh.secret'` | Default refresh token secret key |
|
|
57
|
-
| `Authentication.REFRESH_TOKEN_EXPIRES_IN` | `86400` | Default refresh token expiration (seconds, 24h) |
|
|
58
77
|
| `Authentication.AUTHENTICATION_STRATEGY` | `'authentication.strategy'` | Namespace prefix for strategy binding keys |
|
|
59
78
|
| `Authentication.STRATEGY_JWT` | `'jwt'` | JWT strategy name |
|
|
60
79
|
| `Authentication.STRATEGY_BASIC` | `'basic'` | Basic strategy name |
|
|
@@ -64,36 +83,91 @@
|
|
|
64
83
|
| `Authentication.CURRENT_USER` | `'auth.current.user'` | Context key for the authenticated user payload |
|
|
65
84
|
| `Authentication.AUDIT_USER_ID` | `'audit.user.id'` | Context key for the authenticated user ID |
|
|
66
85
|
|
|
86
|
+
### JWKS Constants
|
|
87
|
+
|
|
88
|
+
| Class | Constant | Value | Description |
|
|
89
|
+
|-------|----------|-------|-------------|
|
|
90
|
+
| `JOSEStandards` | `JWS` | `'JWS'` | Symmetric JWT standard |
|
|
91
|
+
| `JOSEStandards` | `JWKS` | `'JWKS'` | Asymmetric JWT standard |
|
|
92
|
+
| `JWKSModes` | `ISSUER` | `'issuer'` | Issuer mode (sign + verify + serve JWKS) |
|
|
93
|
+
| `JWKSModes` | `VERIFIER` | `'verifier'` | Verifier mode (verify-only via remote JWKS) |
|
|
94
|
+
| `JWKSKeyDrivers` | `TEXT` | `'text'` | Key provided as inline text |
|
|
95
|
+
| `JWKSKeyDrivers` | `FILE` | `'file'` | Key loaded from file path |
|
|
96
|
+
| `JWKSKeyFormats` | `PEM` | `'pem'` | PEM-encoded key format |
|
|
97
|
+
| `JWKSKeyFormats` | `JWK` | `'jwk'` | JSON Web Key format |
|
|
98
|
+
|
|
99
|
+
Each constants class also provides:
|
|
100
|
+
- `SCHEME_SET: Set<string>` — set of all valid values
|
|
101
|
+
- `isValid(input: string): boolean` — check if a value is recognized
|
|
102
|
+
|
|
67
103
|
#### Import Paths
|
|
104
|
+
|
|
68
105
|
```typescript
|
|
69
106
|
import {
|
|
107
|
+
// Component + Registry
|
|
70
108
|
AuthenticateComponent,
|
|
71
109
|
AuthenticateBindingKeys,
|
|
72
110
|
Authentication,
|
|
111
|
+
AuthenticationFieldCodecs,
|
|
73
112
|
AuthenticationModes,
|
|
74
113
|
AuthenticationTokenTypes,
|
|
75
114
|
AuthenticationStrategyRegistry,
|
|
76
|
-
|
|
115
|
+
|
|
116
|
+
// JOSE Standards + Constants
|
|
117
|
+
JOSEStandards,
|
|
118
|
+
JWKSModes,
|
|
119
|
+
JWKSKeyDrivers,
|
|
120
|
+
JWKSKeyFormats,
|
|
121
|
+
|
|
122
|
+
// Strategies
|
|
123
|
+
JWSAuthenticationStrategy,
|
|
124
|
+
JWKSIssuerAuthenticationStrategy,
|
|
125
|
+
JWKSVerifierAuthenticationStrategy,
|
|
77
126
|
BasicAuthenticationStrategy,
|
|
78
|
-
|
|
127
|
+
|
|
128
|
+
// Services
|
|
129
|
+
AbstractBearerTokenService,
|
|
130
|
+
JWSTokenService,
|
|
131
|
+
JWKSIssuerTokenService,
|
|
132
|
+
JWKSVerifierTokenService,
|
|
79
133
|
BasicTokenService,
|
|
134
|
+
|
|
135
|
+
// Controllers
|
|
80
136
|
defineAuthController,
|
|
137
|
+
JWKSController,
|
|
81
138
|
authenticate,
|
|
82
139
|
} from '@venizia/ignis';
|
|
83
140
|
|
|
84
141
|
import type {
|
|
142
|
+
// Option types
|
|
85
143
|
TAuthenticationRestOptions,
|
|
86
|
-
|
|
87
|
-
|
|
144
|
+
TJWTTokenServiceOptions,
|
|
145
|
+
IJWSTokenServiceOptions,
|
|
146
|
+
IJWKSIssuerOptions,
|
|
147
|
+
IJWKSVerifierOptions,
|
|
148
|
+
TJWKSTokenServiceOptions,
|
|
149
|
+
TBasicTokenServiceOptions,
|
|
88
150
|
IAuthenticateOptions,
|
|
151
|
+
|
|
152
|
+
// User + payload types
|
|
89
153
|
IAuthUser,
|
|
90
154
|
IJWTTokenPayload,
|
|
155
|
+
IPayloadFieldCodec,
|
|
91
156
|
IAuthService,
|
|
92
157
|
IAuthenticationStrategy,
|
|
158
|
+
|
|
159
|
+
// Controller types
|
|
93
160
|
TDefineAuthControllerOpts,
|
|
161
|
+
|
|
162
|
+
// Utility types
|
|
94
163
|
TAuthStrategy,
|
|
95
164
|
TAuthMode,
|
|
96
165
|
TGetTokenExpiresFn,
|
|
166
|
+
TJWKSAlgorithm,
|
|
167
|
+
TJWKSKeyDriver,
|
|
168
|
+
TJWKSKeyFormat,
|
|
169
|
+
TJOSEStandard,
|
|
170
|
+
TJWKSMode,
|
|
97
171
|
} from '@venizia/ignis';
|
|
98
172
|
```
|
|
99
173
|
|
|
@@ -128,46 +202,146 @@ import {
|
|
|
128
202
|
} from '@venizia/ignis';
|
|
129
203
|
```
|
|
130
204
|
|
|
205
|
+
## Component Binding Lifecycle
|
|
206
|
+
|
|
207
|
+
```mermaid
|
|
208
|
+
flowchart TD
|
|
209
|
+
A["preConfigure()"] --> B["Bind JWT_OPTIONS / BASIC_OPTIONS / REST_OPTIONS"]
|
|
210
|
+
B --> C["this.component(AuthenticateComponent)"]
|
|
211
|
+
C --> D["AuthenticateComponent.binding()"]
|
|
212
|
+
D --> E{"jwtOptions.standard?"}
|
|
213
|
+
E -->|"JWS"| F["defineJWSAuth()"]
|
|
214
|
+
E -->|"JWKS"| G["defineJWKSAuth()"]
|
|
215
|
+
E -->|"none"| H["Skip JWT"]
|
|
216
|
+
F --> I["Register JWSTokenService"]
|
|
217
|
+
G --> J{"mode?"}
|
|
218
|
+
J -->|"issuer"| K["Register JWKSIssuerTokenService + JWKSController"]
|
|
219
|
+
J -->|"verifier"| L["Register JWKSVerifierTokenService"]
|
|
220
|
+
D --> M["defineBasicAuth()"]
|
|
221
|
+
M --> N["Register BasicTokenService"]
|
|
222
|
+
D --> O["defineControllers()"]
|
|
223
|
+
O --> P["Register AuthController (factory-built)"]
|
|
224
|
+
C --> Q["Manual strategy registration"]
|
|
225
|
+
Q --> R["AuthenticationStrategyRegistry.register()"]
|
|
226
|
+
|
|
227
|
+
style E fill:#fff3cd,stroke:#ffc107
|
|
228
|
+
style J fill:#fff3cd,stroke:#ffc107
|
|
229
|
+
```
|
|
230
|
+
|
|
131
231
|
## Setup
|
|
132
232
|
|
|
133
233
|
### Step 1: Bind Configuration
|
|
134
234
|
|
|
135
|
-
Bind
|
|
235
|
+
Bind JWT options using the discriminated union `TJWTTokenServiceOptions`, which requires a `standard` field to select the JOSE standard.
|
|
136
236
|
|
|
137
|
-
###
|
|
237
|
+
### JWS (Symmetric JWT) Setup
|
|
138
238
|
|
|
139
239
|
```typescript
|
|
140
240
|
import {
|
|
141
241
|
AuthenticateBindingKeys,
|
|
142
|
-
|
|
242
|
+
JOSEStandards,
|
|
243
|
+
TJWTTokenServiceOptions,
|
|
143
244
|
} from '@venizia/ignis';
|
|
144
245
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
246
|
+
this.bind<TJWTTokenServiceOptions>({ key: AuthenticateBindingKeys.JWT_OPTIONS }).toValue({
|
|
247
|
+
standard: JOSEStandards.JWS,
|
|
248
|
+
options: {
|
|
249
|
+
jwtSecret: process.env.APP_ENV_JWT_SECRET,
|
|
250
|
+
applicationSecret: process.env.APP_ENV_APPLICATION_SECRET, // Optional — enables AES payload encryption
|
|
251
|
+
getTokenExpiresFn: () => Number(process.env.APP_ENV_JWT_EXPIRES_IN || 86400),
|
|
252
|
+
},
|
|
150
253
|
});
|
|
151
254
|
```
|
|
152
255
|
|
|
153
|
-
**Example `.env` file:**
|
|
256
|
+
**Example `.env` file (JWS):**
|
|
154
257
|
|
|
155
258
|
```
|
|
156
|
-
APP_ENV_APPLICATION_SECRET=your-strong-application-secret
|
|
157
259
|
APP_ENV_JWT_SECRET=your-strong-jwt-secret
|
|
260
|
+
APP_ENV_APPLICATION_SECRET=your-strong-application-secret
|
|
158
261
|
APP_ENV_JWT_EXPIRES_IN=86400
|
|
159
262
|
```
|
|
160
263
|
|
|
264
|
+
> [!NOTE]
|
|
265
|
+
> `applicationSecret` is optional. When provided, all custom JWT claim keys and values are AES-encrypted. When omitted, payloads are stored in plaintext (standard JWT behavior).
|
|
266
|
+
|
|
267
|
+
### JWKS Issuer (Asymmetric JWT) Setup
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
import {
|
|
271
|
+
AuthenticateBindingKeys,
|
|
272
|
+
JOSEStandards,
|
|
273
|
+
JWKSModes,
|
|
274
|
+
JWKSKeyDrivers,
|
|
275
|
+
JWKSKeyFormats,
|
|
276
|
+
TJWTTokenServiceOptions,
|
|
277
|
+
} from '@venizia/ignis';
|
|
278
|
+
|
|
279
|
+
this.bind<TJWTTokenServiceOptions>({ key: AuthenticateBindingKeys.JWT_OPTIONS }).toValue({
|
|
280
|
+
standard: JOSEStandards.JWKS,
|
|
281
|
+
options: {
|
|
282
|
+
mode: JWKSModes.ISSUER,
|
|
283
|
+
algorithm: 'ES256',
|
|
284
|
+
keys: {
|
|
285
|
+
driver: JWKSKeyDrivers.FILE, // or JWKSKeyDrivers.TEXT
|
|
286
|
+
format: JWKSKeyFormats.PEM, // or JWKSKeyFormats.JWK
|
|
287
|
+
private: './keys/private.pem',
|
|
288
|
+
public: './keys/public.pem',
|
|
289
|
+
},
|
|
290
|
+
kid: 'my-key-id-1',
|
|
291
|
+
getTokenExpiresFn: () => Number(process.env.APP_ENV_JWT_EXPIRES_IN || 86400),
|
|
292
|
+
// Optional AES payload encryption
|
|
293
|
+
aesAlgorithm: 'aes-256-cbc',
|
|
294
|
+
applicationSecret: process.env.APP_ENV_APPLICATION_SECRET,
|
|
295
|
+
},
|
|
296
|
+
});
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
**Example `.env` file (JWKS Issuer):**
|
|
300
|
+
|
|
301
|
+
```
|
|
302
|
+
APP_ENV_JWKS_ALGORITHM=ES256
|
|
303
|
+
APP_ENV_JWKS_KEY_DRIVER=file
|
|
304
|
+
APP_ENV_JWKS_KEY_FORMAT=pem
|
|
305
|
+
APP_ENV_JWKS_PRIVATE_KEY=./keys/private.pem
|
|
306
|
+
APP_ENV_JWKS_PUBLIC_KEY=./keys/public.pem
|
|
307
|
+
APP_ENV_JWKS_KID=my-key-id-1
|
|
308
|
+
APP_ENV_JWT_EXPIRES_IN=86400
|
|
309
|
+
APP_ENV_APPLICATION_SECRET=your-strong-application-secret
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### JWKS Verifier (Remote Verification) Setup
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
import {
|
|
316
|
+
AuthenticateBindingKeys,
|
|
317
|
+
JOSEStandards,
|
|
318
|
+
JWKSModes,
|
|
319
|
+
TJWTTokenServiceOptions,
|
|
320
|
+
} from '@venizia/ignis';
|
|
321
|
+
|
|
322
|
+
this.bind<TJWTTokenServiceOptions>({ key: AuthenticateBindingKeys.JWT_OPTIONS }).toValue({
|
|
323
|
+
standard: JOSEStandards.JWKS,
|
|
324
|
+
options: {
|
|
325
|
+
mode: JWKSModes.VERIFIER,
|
|
326
|
+
jwksUrl: 'https://auth-service.example.com/certs',
|
|
327
|
+
cacheTtlMs: 43_200_000, // Cache JWKS for 12 hours (default)
|
|
328
|
+
cooldownMs: 30_000, // Wait 30s between JWKS refreshes (default)
|
|
329
|
+
// Optional AES payload decryption (must match issuer's applicationSecret)
|
|
330
|
+
aesAlgorithm: 'aes-256-cbc',
|
|
331
|
+
applicationSecret: process.env.APP_ENV_APPLICATION_SECRET,
|
|
332
|
+
},
|
|
333
|
+
});
|
|
334
|
+
```
|
|
335
|
+
|
|
161
336
|
### Basic Auth Only (Alternative Setup)
|
|
162
337
|
|
|
163
338
|
```typescript
|
|
164
339
|
import {
|
|
165
340
|
AuthenticateBindingKeys,
|
|
166
|
-
|
|
341
|
+
TBasicTokenServiceOptions,
|
|
167
342
|
} from '@venizia/ignis';
|
|
168
343
|
|
|
169
|
-
|
|
170
|
-
this.bind<IBasicTokenServiceOptions>({ key: AuthenticateBindingKeys.BASIC_OPTIONS }).toValue({
|
|
344
|
+
this.bind<TBasicTokenServiceOptions>({ key: AuthenticateBindingKeys.BASIC_OPTIONS }).toValue({
|
|
171
345
|
verifyCredentials: async (opts) => {
|
|
172
346
|
const { credentials, context } = opts;
|
|
173
347
|
const user = await userRepo.findByUsername(credentials.username);
|
|
@@ -179,14 +353,20 @@ this.bind<IBasicTokenServiceOptions>({ key: AuthenticateBindingKeys.BASIC_OPTION
|
|
|
179
353
|
});
|
|
180
354
|
```
|
|
181
355
|
|
|
182
|
-
### Combined
|
|
356
|
+
### Combined JWKS + Basic with Auth Controller (Full Setup)
|
|
183
357
|
|
|
184
358
|
```typescript
|
|
185
359
|
import {
|
|
186
360
|
AuthenticateBindingKeys,
|
|
187
|
-
|
|
188
|
-
|
|
361
|
+
JOSEStandards,
|
|
362
|
+
JWKSModes,
|
|
363
|
+
JWKSKeyDrivers,
|
|
364
|
+
JWKSKeyFormats,
|
|
365
|
+
TJWTTokenServiceOptions,
|
|
366
|
+
TBasicTokenServiceOptions,
|
|
189
367
|
TAuthenticationRestOptions,
|
|
368
|
+
BindingKeys,
|
|
369
|
+
BindingNamespaces,
|
|
190
370
|
} from '@venizia/ignis';
|
|
191
371
|
|
|
192
372
|
// Bind REST options (enables auth controller)
|
|
@@ -194,6 +374,10 @@ this.bind<TAuthenticationRestOptions>({ key: AuthenticateBindingKeys.REST_OPTION
|
|
|
194
374
|
useAuthController: true,
|
|
195
375
|
controllerOpts: {
|
|
196
376
|
restPath: '/auth',
|
|
377
|
+
serviceKey: BindingKeys.build({
|
|
378
|
+
namespace: BindingNamespaces.SERVICE,
|
|
379
|
+
key: AuthenticationService.name,
|
|
380
|
+
}),
|
|
197
381
|
payload: {
|
|
198
382
|
signIn: {
|
|
199
383
|
request: { schema: SignInRequestSchema },
|
|
@@ -203,19 +387,33 @@ this.bind<TAuthenticationRestOptions>({ key: AuthenticateBindingKeys.REST_OPTION
|
|
|
203
387
|
request: { schema: SignUpRequestSchema },
|
|
204
388
|
response: { schema: SignUpResponseSchema },
|
|
205
389
|
},
|
|
390
|
+
changePassword: {
|
|
391
|
+
request: { schema: ChangePasswordRequestSchema },
|
|
392
|
+
response: { schema: ChangePasswordResponseSchema },
|
|
393
|
+
},
|
|
206
394
|
},
|
|
207
395
|
},
|
|
208
396
|
});
|
|
209
397
|
|
|
210
|
-
// Bind JWT options
|
|
211
|
-
this.bind<
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
398
|
+
// Bind JWT options (JWKS issuer mode)
|
|
399
|
+
this.bind<TJWTTokenServiceOptions>({ key: AuthenticateBindingKeys.JWT_OPTIONS }).toValue({
|
|
400
|
+
standard: JOSEStandards.JWKS,
|
|
401
|
+
options: {
|
|
402
|
+
mode: JWKSModes.ISSUER,
|
|
403
|
+
algorithm: 'ES256',
|
|
404
|
+
keys: {
|
|
405
|
+
driver: JWKSKeyDrivers.FILE,
|
|
406
|
+
format: JWKSKeyFormats.PEM,
|
|
407
|
+
private: './keys/private.pem',
|
|
408
|
+
public: './keys/public.pem',
|
|
409
|
+
},
|
|
410
|
+
kid: 'my-key-id-1',
|
|
411
|
+
getTokenExpiresFn: () => Number(process.env.APP_ENV_JWT_EXPIRES_IN || 86400),
|
|
412
|
+
},
|
|
215
413
|
});
|
|
216
414
|
|
|
217
415
|
// Bind Basic auth options
|
|
218
|
-
this.bind<
|
|
416
|
+
this.bind<TBasicTokenServiceOptions>({ key: AuthenticateBindingKeys.BASIC_OPTIONS }).toValue({
|
|
219
417
|
verifyCredentials: async (opts) => {
|
|
220
418
|
const authenticateService = this.get<AuthenticationService>({
|
|
221
419
|
key: BindingKeys.build({
|
|
@@ -231,14 +429,14 @@ this.bind<IBasicTokenServiceOptions>({ key: AuthenticateBindingKeys.BASIC_OPTION
|
|
|
231
429
|
});
|
|
232
430
|
```
|
|
233
431
|
|
|
234
|
-
### Step 2: Register Component
|
|
432
|
+
### Step 2: Register Component and Strategies
|
|
235
433
|
|
|
236
434
|
```typescript
|
|
237
435
|
import {
|
|
238
436
|
AuthenticateComponent,
|
|
239
437
|
Authentication,
|
|
240
438
|
AuthenticationStrategyRegistry,
|
|
241
|
-
|
|
439
|
+
JWKSIssuerAuthenticationStrategy,
|
|
242
440
|
BasicAuthenticationStrategy,
|
|
243
441
|
BaseApplication,
|
|
244
442
|
ValueOrPromise,
|
|
@@ -254,11 +452,11 @@ export class Application extends BaseApplication {
|
|
|
254
452
|
// Register component
|
|
255
453
|
this.component(AuthenticateComponent);
|
|
256
454
|
|
|
257
|
-
// Register strategies
|
|
455
|
+
// Register strategies manually AFTER the component
|
|
258
456
|
AuthenticationStrategyRegistry.getInstance().register({
|
|
259
457
|
container: this,
|
|
260
458
|
strategies: [
|
|
261
|
-
{ name: Authentication.STRATEGY_JWT, strategy:
|
|
459
|
+
{ name: Authentication.STRATEGY_JWT, strategy: JWKSIssuerAuthenticationStrategy },
|
|
262
460
|
{ name: Authentication.STRATEGY_BASIC, strategy: BasicAuthenticationStrategy },
|
|
263
461
|
],
|
|
264
462
|
});
|
|
@@ -266,46 +464,141 @@ export class Application extends BaseApplication {
|
|
|
266
464
|
}
|
|
267
465
|
```
|
|
268
466
|
|
|
467
|
+
> [!IMPORTANT]
|
|
468
|
+
> Strategies are NOT auto-registered by `AuthenticateComponent`. You must manually register them after calling `this.component(AuthenticateComponent)`. This gives you full control over which strategies are available.
|
|
469
|
+
|
|
269
470
|
> [!NOTE]
|
|
270
|
-
>
|
|
471
|
+
> Choose the strategy class matching your JOSE standard:
|
|
472
|
+
> - JWS: `JWSAuthenticationStrategy`
|
|
473
|
+
> - JWKS Issuer: `JWKSIssuerAuthenticationStrategy`
|
|
474
|
+
> - JWKS Verifier: `JWKSVerifierAuthenticationStrategy`
|
|
271
475
|
|
|
272
476
|
## Configuration
|
|
273
477
|
|
|
274
|
-
###
|
|
478
|
+
### TJWTTokenServiceOptions (Discriminated Union)
|
|
275
479
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
480
|
+
```mermaid
|
|
481
|
+
flowchart LR
|
|
482
|
+
T["TJWTTokenServiceOptions"] --> S{"standard"}
|
|
483
|
+
S -->|"'JWS'"| JWS["IJWSTokenServiceOptions"]
|
|
484
|
+
S -->|"'JWKS'"| JWKS["TJWKSTokenServiceOptions"]
|
|
485
|
+
JWKS --> M{"mode"}
|
|
486
|
+
M -->|"'issuer'"| ISS["IJWKSIssuerOptions"]
|
|
487
|
+
M -->|"'verifier'"| VER["IJWKSVerifierOptions"]
|
|
283
488
|
|
|
284
|
-
|
|
285
|
-
|
|
489
|
+
style S fill:#e8f4fd,stroke:#0d6efd
|
|
490
|
+
style M fill:#e8f4fd,stroke:#0d6efd
|
|
491
|
+
```
|
|
286
492
|
|
|
287
|
-
|
|
288
|
-
|
|
493
|
+
The top-level JWT options use a discriminated union on the `standard` field:
|
|
494
|
+
|
|
495
|
+
```typescript
|
|
496
|
+
type TJWTTokenServiceOptions =
|
|
497
|
+
| { standard: typeof JOSEStandards.JWS; options: IJWSTokenServiceOptions }
|
|
498
|
+
| { standard: typeof JOSEStandards.JWKS; options: TJWKSTokenServiceOptions };
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
This enables clean TypeScript narrowing — once you set `standard: JOSEStandards.JWS`, the `options` field is typed as `IJWSTokenServiceOptions`; with `standard: JOSEStandards.JWKS`, it becomes `TJWKSTokenServiceOptions`.
|
|
502
|
+
|
|
503
|
+
### JWS Options (IJWSTokenServiceOptions)
|
|
289
504
|
|
|
290
|
-
|
|
505
|
+
| Option | Type | Default | Required | Description |
|
|
506
|
+
|--------|------|---------|----------|-------------|
|
|
507
|
+
| `jwtSecret` | `string` | -- | Yes | Secret for signing and verifying JWT signature |
|
|
508
|
+
| `getTokenExpiresFn` | `TGetTokenExpiresFn` | -- | Yes | Function returning token expiration in seconds |
|
|
509
|
+
| `applicationSecret` | `string` | -- | No | Secret for AES-encrypting JWT payload fields |
|
|
510
|
+
| `aesAlgorithm` | `AESAlgorithmType` | `'aes-256-cbc'` | No | AES algorithm for payload encryption |
|
|
511
|
+
| `headerAlgorithm` | `string` | `'HS256'` | No | JWT signing algorithm |
|
|
512
|
+
| `fieldCodecs` | `IPayloadFieldCodec[]` | `[]` | No | Custom field codecs for payload serialization |
|
|
291
513
|
|
|
514
|
+
```typescript
|
|
515
|
+
interface IJWSTokenServiceOptions {
|
|
516
|
+
headerAlgorithm?: string;
|
|
517
|
+
jwtSecret: string;
|
|
518
|
+
getTokenExpiresFn: TGetTokenExpiresFn;
|
|
519
|
+
aesAlgorithm?: AESAlgorithmType;
|
|
520
|
+
applicationSecret?: string;
|
|
521
|
+
fieldCodecs?: IPayloadFieldCodec[];
|
|
522
|
+
}
|
|
292
523
|
```
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
524
|
+
|
|
525
|
+
> [!WARNING]
|
|
526
|
+
> `jwtSecret` is mandatory. The component will throw an error if it is missing or set to `'unknown_secret'`. The error message from `defineJWSAuth` **includes the actual provided secret value** in the error output, so ensure these errors are never exposed to end users.
|
|
527
|
+
|
|
528
|
+
> [!NOTE]
|
|
529
|
+
> `applicationSecret` is optional. When provided, custom JWT payload fields are AES-encrypted (keys and values). When omitted, the JWT payload is stored in standard plaintext. Standard JWT fields (`iss`, `sub`, `aud`, `jti`, `nbf`, `exp`, `iat`) are never encrypted.
|
|
530
|
+
|
|
531
|
+
### JWKS Issuer Options (IJWKSIssuerOptions)
|
|
532
|
+
|
|
533
|
+
| Option | Type | Default | Required | Description |
|
|
534
|
+
|--------|------|---------|----------|-------------|
|
|
535
|
+
| `mode` | `typeof JWKSModes.ISSUER` | -- | Yes | Must be `'issuer'` |
|
|
536
|
+
| `algorithm` | `TJWKSAlgorithm` | -- | Yes | Signing algorithm: `'ES256'`, `'RS256'`, or `'EdDSA'` |
|
|
537
|
+
| `keys.driver` | `TJWKSKeyDriver` | -- | Yes | Key source: `'text'` (inline) or `'file'` (file path) |
|
|
538
|
+
| `keys.format` | `TJWKSKeyFormat` | -- | Yes | Key format: `'pem'` or `'jwk'` |
|
|
539
|
+
| `keys.private` | `string` | -- | Yes | Private key content (text) or file path (file) |
|
|
540
|
+
| `keys.public` | `string` | -- | Yes | Public key content (text) or file path (file) |
|
|
541
|
+
| `kid` | `string` | -- | Yes | Key ID exposed in the JWKS endpoint |
|
|
542
|
+
| `getTokenExpiresFn` | `TGetTokenExpiresFn` | -- | Yes | Function returning token expiration in seconds |
|
|
543
|
+
| `rest` | `{ path: string }` | `{ path: '/certs' }` | No | Custom path for the JWKS endpoint |
|
|
544
|
+
| `aesAlgorithm` | `AESAlgorithmType` | `'aes-256-cbc'` | No | AES algorithm for payload encryption |
|
|
545
|
+
| `applicationSecret` | `string` | -- | No | Secret for AES-encrypting JWT payload fields |
|
|
546
|
+
| `fieldCodecs` | `IPayloadFieldCodec[]` | `[]` | No | Custom field codecs for payload serialization |
|
|
547
|
+
|
|
548
|
+
```typescript
|
|
549
|
+
interface IJWKSIssuerOptions {
|
|
550
|
+
mode: typeof JWKSModes.ISSUER;
|
|
551
|
+
algorithm: TJWKSAlgorithm;
|
|
552
|
+
rest?: { path: string };
|
|
553
|
+
keys: {
|
|
554
|
+
driver: TJWKSKeyDriver;
|
|
555
|
+
format: TJWKSKeyFormat;
|
|
556
|
+
private: string;
|
|
557
|
+
public: string;
|
|
558
|
+
};
|
|
559
|
+
kid: string;
|
|
560
|
+
getTokenExpiresFn: TGetTokenExpiresFn;
|
|
561
|
+
aesAlgorithm?: AESAlgorithmType;
|
|
562
|
+
applicationSecret?: string;
|
|
563
|
+
fieldCodecs?: IPayloadFieldCodec[];
|
|
564
|
+
}
|
|
296
565
|
```
|
|
297
566
|
|
|
298
|
-
|
|
567
|
+
### JWKS Verifier Options (IJWKSVerifierOptions)
|
|
568
|
+
|
|
569
|
+
| Option | Type | Default | Required | Description |
|
|
570
|
+
|--------|------|---------|----------|-------------|
|
|
571
|
+
| `mode` | `typeof JWKSModes.VERIFIER` | -- | Yes | Must be `'verifier'` |
|
|
572
|
+
| `jwksUrl` | `string` | -- | Yes | URL of the remote JWKS endpoint |
|
|
573
|
+
| `cacheTtlMs` | `number` | `43_200_000` (12h) | No | How long to cache the JWKS response |
|
|
574
|
+
| `cooldownMs` | `number` | `30_000` (30s) | No | Minimum time between JWKS refreshes |
|
|
575
|
+
| `aesAlgorithm` | `AESAlgorithmType` | `'aes-256-cbc'` | No | AES algorithm for payload decryption |
|
|
576
|
+
| `applicationSecret` | `string` | -- | No | Secret for AES-decrypting JWT payload fields |
|
|
577
|
+
| `fieldCodecs` | `IPayloadFieldCodec[]` | `[]` | No | Custom field codecs for payload deserialization |
|
|
578
|
+
|
|
299
579
|
```typescript
|
|
300
|
-
interface
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
580
|
+
interface IJWKSVerifierOptions {
|
|
581
|
+
mode: typeof JWKSModes.VERIFIER;
|
|
582
|
+
jwksUrl: string;
|
|
583
|
+
cacheTtlMs?: number;
|
|
584
|
+
cooldownMs?: number;
|
|
304
585
|
aesAlgorithm?: AESAlgorithmType;
|
|
305
|
-
|
|
586
|
+
applicationSecret?: string;
|
|
587
|
+
fieldCodecs?: IPayloadFieldCodec[];
|
|
306
588
|
}
|
|
307
589
|
```
|
|
308
590
|
|
|
591
|
+
> [!IMPORTANT]
|
|
592
|
+
> In verifier mode, the `applicationSecret` must match the issuer's secret exactly. If the issuer encrypts payloads with AES, the verifier must use the same `applicationSecret` to decrypt them.
|
|
593
|
+
|
|
594
|
+
### JWKS Token Service Options (Union)
|
|
595
|
+
|
|
596
|
+
```typescript
|
|
597
|
+
type TJWKSTokenServiceOptions = IJWKSIssuerOptions | IJWKSVerifierOptions;
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
This union is discriminated on the `mode` field (`'issuer'` vs `'verifier'`).
|
|
601
|
+
|
|
309
602
|
### Basic Auth Options
|
|
310
603
|
|
|
311
604
|
| Option | Type | Default | Description |
|
|
@@ -321,14 +614,14 @@ type TBasicAuthVerifyFn<E extends Env = Env> = (opts: {
|
|
|
321
614
|
}) => Promise<IAuthUser | null>;
|
|
322
615
|
```
|
|
323
616
|
|
|
324
|
-
####
|
|
617
|
+
#### TBasicTokenServiceOptions -- Full Interface
|
|
325
618
|
```typescript
|
|
326
|
-
|
|
619
|
+
type TBasicTokenServiceOptions<E extends Env = Env> = {
|
|
327
620
|
verifyCredentials: (opts: {
|
|
328
621
|
credentials: { username: string; password: string };
|
|
329
622
|
context: TContext<E, string>;
|
|
330
623
|
}) => Promise<IAuthUser | null>;
|
|
331
|
-
}
|
|
624
|
+
};
|
|
332
625
|
```
|
|
333
626
|
|
|
334
627
|
### REST Options
|
|
@@ -358,7 +651,7 @@ type TAuthenticationRestOptions = {} & (
|
|
|
358
651
|
| Option | Type | Default | Description |
|
|
359
652
|
|--------|------|---------|-------------|
|
|
360
653
|
| `restPath` | `string` | `'/auth'` | Base path for auth endpoints |
|
|
361
|
-
| `serviceKey` | `string` |
|
|
654
|
+
| `serviceKey` | `string` | -- | DI key for the auth service (required) |
|
|
362
655
|
| `requireAuthenticatedSignUp` | `boolean` | `false` | Whether sign-up requires JWT authentication |
|
|
363
656
|
| `payload` | `object` | `{}` | Custom Zod schemas for request/response payloads |
|
|
364
657
|
|
|
@@ -366,7 +659,7 @@ type TAuthenticationRestOptions = {} & (
|
|
|
366
659
|
```typescript
|
|
367
660
|
type TDefineAuthControllerOpts = {
|
|
368
661
|
restPath?: string;
|
|
369
|
-
serviceKey
|
|
662
|
+
serviceKey: string;
|
|
370
663
|
requireAuthenticatedSignUp?: boolean;
|
|
371
664
|
payload?: {
|
|
372
665
|
signIn?: {
|
|
@@ -387,13 +680,29 @@ type TDefineAuthControllerOpts = {
|
|
|
387
680
|
|
|
388
681
|
### Route Configuration Options
|
|
389
682
|
|
|
390
|
-
|
|
683
|
+
Per-route authentication is configured via the `authenticate` field on route configs, using `TRouteAuthenticateConfig`:
|
|
684
|
+
|
|
685
|
+
```typescript
|
|
686
|
+
type TRouteAuthenticateConfig =
|
|
687
|
+
| { skip: true }
|
|
688
|
+
| { skip?: false; strategies?: TAuthStrategy[]; mode?: TAuthMode };
|
|
689
|
+
```
|
|
391
690
|
|
|
392
691
|
| Option | Type | Default | Description |
|
|
393
692
|
|--------|------|---------|-------------|
|
|
394
|
-
| `
|
|
395
|
-
| `
|
|
396
|
-
| `
|
|
693
|
+
| `authenticate.strategies` | `TAuthStrategy[]` | -- | Array of strategy names (e.g., `['jwt']`, `['jwt', 'basic']`) |
|
|
694
|
+
| `authenticate.mode` | `'any' \| 'all'` | `'any'` | How to handle multiple strategies |
|
|
695
|
+
| `authenticate.skip` | `true` | -- | Skip authentication for this route |
|
|
696
|
+
|
|
697
|
+
Example route config:
|
|
698
|
+
```typescript
|
|
699
|
+
const SECURE_ROUTE = {
|
|
700
|
+
path: '/data',
|
|
701
|
+
method: HTTP.Methods.GET,
|
|
702
|
+
authenticate: { strategies: [Authentication.STRATEGY_JWT] },
|
|
703
|
+
responses: jsonResponse({ description: 'Protected', schema: z.object({ data: z.any() }) }),
|
|
704
|
+
} as const;
|
|
705
|
+
```
|
|
397
706
|
|
|
398
707
|
### IAuthUser Interface
|
|
399
708
|
|
|
@@ -482,12 +791,16 @@ interface IJWTTokenPayload extends JWTPayload, IAuthUser {
|
|
|
482
791
|
| Key | Constant | Type | Required | Default |
|
|
483
792
|
|-----|----------|------|----------|---------|
|
|
484
793
|
| `@app/authenticate/rest-options` | `AuthenticateBindingKeys.REST_OPTIONS` | `TAuthenticationRestOptions` | No | <code v-pre>{ useAuthController: false }</code> |
|
|
485
|
-
| `@app/authenticate/jwt-options` | `AuthenticateBindingKeys.JWT_OPTIONS` | `
|
|
486
|
-
| `@app/authenticate/
|
|
794
|
+
| `@app/authenticate/jwt-options` | `AuthenticateBindingKeys.JWT_OPTIONS` | `TJWTTokenServiceOptions` | Conditional | -- |
|
|
795
|
+
| `@app/authenticate/jwks-options` | `AuthenticateBindingKeys.JWKS_OPTIONS` | `IJWKSIssuerOptions \| IJWKSVerifierOptions` | Internal | Bound by the component |
|
|
796
|
+
| `@app/authenticate/basic-options` | `AuthenticateBindingKeys.BASIC_OPTIONS` | `TBasicTokenServiceOptions` | Conditional | -- |
|
|
487
797
|
|
|
488
798
|
> [!IMPORTANT]
|
|
489
799
|
> At least one of `JWT_OPTIONS` or `BASIC_OPTIONS` must be bound. If neither is configured, the component will throw an error during `binding()`.
|
|
490
800
|
|
|
801
|
+
> [!NOTE]
|
|
802
|
+
> `JWKS_OPTIONS` is bound internally by the component when `standard: JOSEStandards.JWKS` is configured. You do not need to bind it manually. The component extracts the JWKS options from the discriminated union and re-binds them to `JWKS_OPTIONS` so that the JWKS services can resolve them via `@inject`.
|
|
803
|
+
|
|
491
804
|
### Context Variables
|
|
492
805
|
|
|
493
806
|
These values are set on the Hono `Context` during authentication and can be accessed via `context.get()`:
|