@venizia/ignis-docs 0.0.5 → 0.0.6-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/package.json +1 -1
  2. package/wiki/best-practices/architectural-patterns.md +0 -2
  3. package/wiki/best-practices/architecture-decisions.md +0 -8
  4. package/wiki/best-practices/code-style-standards/control-flow.md +1 -1
  5. package/wiki/best-practices/code-style-standards/index.md +0 -1
  6. package/wiki/best-practices/code-style-standards/tooling.md +0 -3
  7. package/wiki/best-practices/contribution-workflow.md +12 -12
  8. package/wiki/best-practices/index.md +4 -14
  9. package/wiki/best-practices/performance-optimization.md +3 -3
  10. package/wiki/best-practices/security-guidelines.md +2 -2
  11. package/wiki/best-practices/troubleshooting-tips.md +1 -1
  12. package/wiki/guides/core-concepts/application/bootstrapping.md +6 -7
  13. package/wiki/guides/core-concepts/components-guide.md +1 -1
  14. package/wiki/guides/core-concepts/components.md +2 -2
  15. package/wiki/guides/core-concepts/dependency-injection.md +4 -5
  16. package/wiki/guides/core-concepts/persistent/datasources.md +4 -5
  17. package/wiki/guides/core-concepts/services.md +1 -1
  18. package/wiki/guides/get-started/5-minute-quickstart.md +4 -5
  19. package/wiki/guides/get-started/philosophy.md +12 -24
  20. package/wiki/guides/index.md +2 -9
  21. package/wiki/guides/reference/mcp-docs-server.md +13 -13
  22. package/wiki/guides/tutorials/building-a-crud-api.md +10 -10
  23. package/wiki/guides/tutorials/complete-installation.md +11 -12
  24. package/wiki/guides/tutorials/ecommerce-api.md +3 -3
  25. package/wiki/guides/tutorials/realtime-chat.md +6 -6
  26. package/wiki/guides/tutorials/testing.md +4 -5
  27. package/wiki/index.md +8 -14
  28. package/wiki/references/base/bootstrapping.md +0 -3
  29. package/wiki/references/base/components.md +2 -2
  30. package/wiki/references/base/controllers.md +0 -1
  31. package/wiki/references/base/datasources.md +1 -1
  32. package/wiki/references/base/dependency-injection.md +2 -2
  33. package/wiki/references/base/filter-system/default-filter.md +2 -3
  34. package/wiki/references/base/filter-system/index.md +1 -1
  35. package/wiki/references/base/filter-system/quick-reference.md +0 -14
  36. package/wiki/references/base/middlewares.md +0 -8
  37. package/wiki/references/base/providers.md +0 -9
  38. package/wiki/references/base/repositories/advanced.md +1 -1
  39. package/wiki/references/base/repositories/mixins.md +2 -3
  40. package/wiki/references/base/services.md +0 -1
  41. package/wiki/references/components/authentication/api.md +444 -0
  42. package/wiki/references/components/authentication/errors.md +177 -0
  43. package/wiki/references/components/authentication/index.md +571 -0
  44. package/wiki/references/components/authentication/usage.md +781 -0
  45. package/wiki/references/components/health-check.md +292 -103
  46. package/wiki/references/components/index.md +14 -12
  47. package/wiki/references/components/mail/api.md +505 -0
  48. package/wiki/references/components/mail/errors.md +176 -0
  49. package/wiki/references/components/mail/index.md +535 -0
  50. package/wiki/references/components/mail/usage.md +404 -0
  51. package/wiki/references/components/request-tracker.md +229 -25
  52. package/wiki/references/components/socket-io/api.md +1051 -0
  53. package/wiki/references/components/socket-io/errors.md +119 -0
  54. package/wiki/references/components/socket-io/index.md +410 -0
  55. package/wiki/references/components/socket-io/usage.md +322 -0
  56. package/wiki/references/components/static-asset/api.md +261 -0
  57. package/wiki/references/components/static-asset/errors.md +89 -0
  58. package/wiki/references/components/static-asset/index.md +617 -0
  59. package/wiki/references/components/static-asset/usage.md +364 -0
  60. package/wiki/references/components/swagger.md +390 -110
  61. package/wiki/references/components/template/api-page.md +125 -0
  62. package/wiki/references/components/template/errors-page.md +100 -0
  63. package/wiki/references/components/template/index.md +104 -0
  64. package/wiki/references/components/template/setup-page.md +134 -0
  65. package/wiki/references/components/template/single-page.md +132 -0
  66. package/wiki/references/components/template/usage-page.md +127 -0
  67. package/wiki/references/components/websocket/api.md +508 -0
  68. package/wiki/references/components/websocket/errors.md +123 -0
  69. package/wiki/references/components/websocket/index.md +453 -0
  70. package/wiki/references/components/websocket/usage.md +475 -0
  71. package/wiki/references/helpers/cron/index.md +224 -0
  72. package/wiki/references/helpers/crypto/index.md +537 -0
  73. package/wiki/references/helpers/env/index.md +214 -0
  74. package/wiki/references/helpers/error/index.md +232 -0
  75. package/wiki/references/helpers/index.md +16 -15
  76. package/wiki/references/helpers/inversion/index.md +608 -0
  77. package/wiki/references/helpers/logger/index.md +600 -0
  78. package/wiki/references/helpers/network/api.md +986 -0
  79. package/wiki/references/helpers/network/index.md +620 -0
  80. package/wiki/references/helpers/queue/index.md +589 -0
  81. package/wiki/references/helpers/redis/index.md +495 -0
  82. package/wiki/references/helpers/socket-io/api.md +497 -0
  83. package/wiki/references/helpers/socket-io/index.md +513 -0
  84. package/wiki/references/helpers/storage/api.md +705 -0
  85. package/wiki/references/helpers/storage/index.md +583 -0
  86. package/wiki/references/helpers/template/index.md +66 -0
  87. package/wiki/references/helpers/template/single-page.md +126 -0
  88. package/wiki/references/helpers/testing/index.md +510 -0
  89. package/wiki/references/helpers/types/index.md +512 -0
  90. package/wiki/references/helpers/uid/index.md +272 -0
  91. package/wiki/references/helpers/websocket/api.md +736 -0
  92. package/wiki/references/helpers/websocket/index.md +574 -0
  93. package/wiki/references/helpers/worker-thread/index.md +470 -0
  94. package/wiki/references/index.md +2 -9
  95. package/wiki/references/quick-reference.md +3 -18
  96. package/wiki/references/utilities/jsx.md +1 -8
  97. package/wiki/references/utilities/statuses.md +0 -7
  98. package/wiki/references/components/authentication.md +0 -476
  99. package/wiki/references/components/mail.md +0 -687
  100. package/wiki/references/components/socket-io.md +0 -562
  101. package/wiki/references/components/static-asset.md +0 -1277
  102. package/wiki/references/helpers/cron.md +0 -108
  103. package/wiki/references/helpers/crypto.md +0 -132
  104. package/wiki/references/helpers/env.md +0 -83
  105. package/wiki/references/helpers/error.md +0 -97
  106. package/wiki/references/helpers/inversion.md +0 -176
  107. package/wiki/references/helpers/logger.md +0 -296
  108. package/wiki/references/helpers/network.md +0 -396
  109. package/wiki/references/helpers/queue.md +0 -150
  110. package/wiki/references/helpers/redis.md +0 -142
  111. package/wiki/references/helpers/socket-io.md +0 -932
  112. package/wiki/references/helpers/storage.md +0 -665
  113. package/wiki/references/helpers/testing.md +0 -133
  114. package/wiki/references/helpers/types.md +0 -167
  115. package/wiki/references/helpers/uid.md +0 -167
  116. package/wiki/references/helpers/worker-thread.md +0 -178
  117. package/wiki/references/src-details/boot.md +0 -379
  118. package/wiki/references/src-details/core.md +0 -263
  119. package/wiki/references/src-details/dev-configs.md +0 -298
  120. package/wiki/references/src-details/docs.md +0 -71
  121. package/wiki/references/src-details/helpers.md +0 -211
  122. package/wiki/references/src-details/index.md +0 -86
  123. package/wiki/references/src-details/inversion.md +0 -340
@@ -0,0 +1,571 @@
1
+ # Authentication -- Setup & Configuration
2
+
3
+ > JWT and Basic HTTP authentication with AES-encrypted payloads, multi-strategy support, and built-in auth controller
4
+
5
+ ## Quick Reference
6
+
7
+ | Item | Value |
8
+ |------|-------|
9
+ | **Package** | `@venizia/ignis` |
10
+ | **Class** | `AuthenticateComponent` |
11
+ | **Runtimes** | Both |
12
+
13
+ ### Key Components
14
+
15
+ | Component | Purpose |
16
+ |-----------|---------|
17
+ | **AuthenticateComponent** | Main component registering auth services and controllers |
18
+ | **AuthenticationStrategyRegistry** | Singleton managing available auth strategies |
19
+ | **JWTAuthenticationStrategy** | JWT verification using `JWTTokenService` |
20
+ | **BasicAuthenticationStrategy** | Basic HTTP authentication using `BasicTokenService` |
21
+ | **JWTTokenService** | Generate, verify, encrypt/decrypt JWT tokens |
22
+ | **BasicTokenService** | Extract and verify Basic auth credentials |
23
+ | **IAuthService** | Interface for custom auth implementation (sign-in, sign-up) |
24
+ | **defineAuthController** | Factory function for creating custom auth controllers |
25
+ | **authenticate** | Standalone function wrapping `AuthenticationStrategyRegistry.getInstance().authenticate()` |
26
+
27
+ ### Environment Variables
28
+
29
+ | Variable | Purpose | Required |
30
+ |----------|---------|----------|
31
+ | `APP_ENV_APPLICATION_SECRET` | Encrypt JWT payload | Required for JWT |
32
+ | `APP_ENV_JWT_SECRET` | Sign and verify JWT signature | Required for JWT |
33
+ | `APP_ENV_JWT_EXPIRES_IN` | Token expiration (seconds) | Optional |
34
+
35
+ ### Auth Modes
36
+
37
+ | Mode | Behavior |
38
+ |------|----------|
39
+ | `'any'` | First successful strategy wins (fallback mode) |
40
+ | `'all'` | All strategies must pass (MFA mode) |
41
+
42
+ ### Token Types
43
+
44
+ | Constant | Value | Description |
45
+ |----------|-------|-------------|
46
+ | `AuthenticationTokenTypes.TYPE_AUTHORIZATION_CODE` | `'000_AUTHORIZATION_CODE'` | Authorization code grant type |
47
+ | `AuthenticationTokenTypes.TYPE_ACCESS_TOKEN` | `'100_ACCESS_TOKEN'` | Access token type |
48
+ | `AuthenticationTokenTypes.TYPE_REFRESH_TOKEN` | `'200_REFRESH_TOKEN'` | Refresh token type |
49
+
50
+ ### Authentication Constants
51
+
52
+ | Constant | Value | Description |
53
+ |----------|-------|-------------|
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
+ | `Authentication.AUTHENTICATION_STRATEGY` | `'authentication.strategy'` | Namespace prefix for strategy binding keys |
59
+ | `Authentication.STRATEGY_JWT` | `'jwt'` | JWT strategy name |
60
+ | `Authentication.STRATEGY_BASIC` | `'basic'` | Basic strategy name |
61
+ | `Authentication.TYPE_BEARER` | `'Bearer'` | Bearer token type prefix |
62
+ | `Authentication.TYPE_BASIC` | `'Basic'` | Basic token type prefix |
63
+ | `Authentication.SKIP_AUTHENTICATION` | `'authentication.skip'` | Context key to dynamically skip auth |
64
+ | `Authentication.CURRENT_USER` | `'auth.current.user'` | Context key for the authenticated user payload |
65
+ | `Authentication.AUDIT_USER_ID` | `'audit.user.id'` | Context key for the authenticated user ID |
66
+
67
+ #### Import Paths
68
+ ```typescript
69
+ import {
70
+ AuthenticateComponent,
71
+ AuthenticateBindingKeys,
72
+ Authentication,
73
+ AuthenticationModes,
74
+ AuthenticationTokenTypes,
75
+ AuthenticationStrategyRegistry,
76
+ JWTAuthenticationStrategy,
77
+ BasicAuthenticationStrategy,
78
+ JWTTokenService,
79
+ BasicTokenService,
80
+ defineAuthController,
81
+ authenticate,
82
+ } from '@venizia/ignis';
83
+
84
+ import type {
85
+ TAuthenticationRestOptions,
86
+ IJWTTokenServiceOptions,
87
+ IBasicTokenServiceOptions,
88
+ IAuthenticateOptions,
89
+ IAuthUser,
90
+ IJWTTokenPayload,
91
+ IAuthService,
92
+ IAuthenticationStrategy,
93
+ TDefineAuthControllerOpts,
94
+ TAuthStrategy,
95
+ TAuthMode,
96
+ TGetTokenExpiresFn,
97
+ } from '@venizia/ignis';
98
+ ```
99
+
100
+ #### Entity Column Helper Imports
101
+
102
+ ```typescript
103
+ import {
104
+ extraUserColumns,
105
+ extraRoleColumns,
106
+ extraPermissionColumns,
107
+ extraPermissionMappingColumns,
108
+ extraUserRoleColumns,
109
+ } from '@venizia/ignis';
110
+
111
+ import type {
112
+ TPermissionOptions,
113
+ TPermissionCommonColumns,
114
+ TPermissionMappingOptions,
115
+ TPermissionMappingCommonColumns,
116
+ TUserRoleOptions,
117
+ TUserRoleCommonColumns,
118
+ } from '@venizia/ignis';
119
+ ```
120
+
121
+ #### Status and Type Imports
122
+
123
+ ```typescript
124
+ import {
125
+ UserStatuses,
126
+ UserTypes,
127
+ RoleStatuses,
128
+ } from '@venizia/ignis';
129
+ ```
130
+
131
+ ## Setup
132
+
133
+ ### Step 1: Bind Configuration
134
+
135
+ Bind at least one of `JWT_OPTIONS` or `BASIC_OPTIONS` in your application's `preConfigure()`.
136
+
137
+ ### JWT Only (Primary Setup)
138
+
139
+ ```typescript
140
+ import {
141
+ AuthenticateBindingKeys,
142
+ IJWTTokenServiceOptions,
143
+ } from '@venizia/ignis';
144
+
145
+ // Bind JWT options
146
+ this.bind<IJWTTokenServiceOptions>({ key: AuthenticateBindingKeys.JWT_OPTIONS }).toValue({
147
+ applicationSecret: process.env.APP_ENV_APPLICATION_SECRET,
148
+ jwtSecret: process.env.APP_ENV_JWT_SECRET,
149
+ getTokenExpiresFn: () => Number(process.env.APP_ENV_JWT_EXPIRES_IN || 86400),
150
+ });
151
+ ```
152
+
153
+ **Example `.env` file:**
154
+
155
+ ```
156
+ APP_ENV_APPLICATION_SECRET=your-strong-application-secret
157
+ APP_ENV_JWT_SECRET=your-strong-jwt-secret
158
+ APP_ENV_JWT_EXPIRES_IN=86400
159
+ ```
160
+
161
+ ### Basic Auth Only (Alternative Setup)
162
+
163
+ ```typescript
164
+ import {
165
+ AuthenticateBindingKeys,
166
+ IBasicTokenServiceOptions,
167
+ } from '@venizia/ignis';
168
+
169
+ // Bind Basic auth options
170
+ this.bind<IBasicTokenServiceOptions>({ key: AuthenticateBindingKeys.BASIC_OPTIONS }).toValue({
171
+ verifyCredentials: async (opts) => {
172
+ const { credentials, context } = opts;
173
+ const user = await userRepo.findByUsername(credentials.username);
174
+ if (user && await bcrypt.compare(credentials.password, user.passwordHash)) {
175
+ return { userId: user.id, roles: user.roles };
176
+ }
177
+ return null;
178
+ },
179
+ });
180
+ ```
181
+
182
+ ### Combined JWT + Basic with Auth Controller (Full Setup)
183
+
184
+ ```typescript
185
+ import {
186
+ AuthenticateBindingKeys,
187
+ IJWTTokenServiceOptions,
188
+ IBasicTokenServiceOptions,
189
+ TAuthenticationRestOptions,
190
+ } from '@venizia/ignis';
191
+
192
+ // Bind REST options (enables auth controller)
193
+ this.bind<TAuthenticationRestOptions>({ key: AuthenticateBindingKeys.REST_OPTIONS }).toValue({
194
+ useAuthController: true,
195
+ controllerOpts: {
196
+ restPath: '/auth',
197
+ payload: {
198
+ signIn: {
199
+ request: { schema: SignInRequestSchema },
200
+ response: { schema: SignInResponseSchema },
201
+ },
202
+ signUp: {
203
+ request: { schema: SignUpRequestSchema },
204
+ response: { schema: SignUpResponseSchema },
205
+ },
206
+ },
207
+ },
208
+ });
209
+
210
+ // Bind JWT options
211
+ this.bind<IJWTTokenServiceOptions>({ key: AuthenticateBindingKeys.JWT_OPTIONS }).toValue({
212
+ applicationSecret: process.env.APP_ENV_APPLICATION_SECRET,
213
+ jwtSecret: process.env.APP_ENV_JWT_SECRET,
214
+ getTokenExpiresFn: () => Number(process.env.APP_ENV_JWT_EXPIRES_IN || 86400),
215
+ });
216
+
217
+ // Bind Basic auth options
218
+ this.bind<IBasicTokenServiceOptions>({ key: AuthenticateBindingKeys.BASIC_OPTIONS }).toValue({
219
+ verifyCredentials: async (opts) => {
220
+ const authenticateService = this.get<AuthenticationService>({
221
+ key: BindingKeys.build({
222
+ namespace: BindingNamespaces.SERVICE,
223
+ key: AuthenticationService.name,
224
+ }),
225
+ });
226
+ return authenticateService.signIn(opts.context, {
227
+ identifier: { scheme: 'username', value: opts.credentials.username },
228
+ credential: { scheme: 'basic', value: opts.credentials.password },
229
+ });
230
+ },
231
+ });
232
+ ```
233
+
234
+ ### Step 2: Register Component
235
+
236
+ ```typescript
237
+ import {
238
+ AuthenticateComponent,
239
+ Authentication,
240
+ AuthenticationStrategyRegistry,
241
+ JWTAuthenticationStrategy,
242
+ BasicAuthenticationStrategy,
243
+ BaseApplication,
244
+ ValueOrPromise,
245
+ } from '@venizia/ignis';
246
+
247
+ export class Application extends BaseApplication {
248
+ preConfigure(): ValueOrPromise<void> {
249
+ // Register your auth service (if using auth controller)
250
+ this.service(AuthenticationService);
251
+
252
+ // Step 1 bindings here...
253
+
254
+ // Register component
255
+ this.component(AuthenticateComponent);
256
+
257
+ // Register strategies
258
+ AuthenticationStrategyRegistry.getInstance().register({
259
+ container: this,
260
+ strategies: [
261
+ { name: Authentication.STRATEGY_JWT, strategy: JWTAuthenticationStrategy },
262
+ { name: Authentication.STRATEGY_BASIC, strategy: BasicAuthenticationStrategy },
263
+ ],
264
+ });
265
+ }
266
+ }
267
+ ```
268
+
269
+ > [!NOTE]
270
+ > Only register the strategies you need. JWT-only setups can omit `BasicAuthenticationStrategy` and vice versa.
271
+
272
+ ## Configuration
273
+
274
+ ### JWT Options
275
+
276
+ | Option | Type | Default | Description |
277
+ |--------|------|---------|-------------|
278
+ | `jwtSecret` | `string` | -- | Secret for signing and verifying JWT signature |
279
+ | `applicationSecret` | `string` | -- | Secret for AES-encrypting JWT payload fields |
280
+ | `getTokenExpiresFn` | `() => ValueOrPromise<number>` | -- | Function returning token expiration in seconds |
281
+ | `aesAlgorithm` | `AESAlgorithmType` | `'aes-256-cbc'` | AES algorithm for payload encryption |
282
+ | `headerAlgorithm` | `string` | `'HS256'` | JWT signing algorithm |
283
+
284
+ > [!WARNING]
285
+ > Both `applicationSecret` and `jwtSecret` are mandatory when using JWT authentication. They must be strong, unique secret values. The component will throw an error if either is missing or set to `'unknown_secret'`. Additionally, the error message from `defineJWTAuth` **includes the actual provided secret value** in the error output (e.g., <code v-pre>[defineJWTAuth] Invalid jwtSecret | Provided: {{jwtSecret}}</code>), so ensure these errors are never exposed to end users.
286
+
287
+ > [!NOTE]
288
+ > The `getTokenExpiresFn` is called on every token generation, not just once. This allows dynamic expiration (e.g., shorter tokens for mobile, longer for admin).
289
+
290
+ **Example `.env` file:**
291
+
292
+ ```
293
+ APP_ENV_APPLICATION_SECRET=your-strong-application-secret
294
+ APP_ENV_JWT_SECRET=your-strong-jwt-secret
295
+ APP_ENV_JWT_EXPIRES_IN=86400
296
+ ```
297
+
298
+ #### IJWTTokenServiceOptions -- Full Interface
299
+ ```typescript
300
+ interface IJWTTokenServiceOptions {
301
+ jwtSecret: string;
302
+ applicationSecret: string;
303
+ getTokenExpiresFn: () => ValueOrPromise<number>;
304
+ aesAlgorithm?: AESAlgorithmType;
305
+ headerAlgorithm?: string;
306
+ }
307
+ ```
308
+
309
+ ### Basic Auth Options
310
+
311
+ | Option | Type | Default | Description |
312
+ |--------|------|---------|-------------|
313
+ | `verifyCredentials` | `(opts: { credentials, context }) => Promise<IAuthUser \| null>` | -- | Callback to verify Basic auth credentials |
314
+
315
+ The `verifyCredentials` function receives an options object:
316
+
317
+ ```typescript
318
+ type TBasicAuthVerifyFn<E extends Env = Env> = (opts: {
319
+ credentials: { username: string; password: string };
320
+ context: TContext<E, string>;
321
+ }) => Promise<IAuthUser | null>;
322
+ ```
323
+
324
+ #### IBasicTokenServiceOptions -- Full Interface
325
+ ```typescript
326
+ interface IBasicTokenServiceOptions<E extends Env = Env> {
327
+ verifyCredentials: (opts: {
328
+ credentials: { username: string; password: string };
329
+ context: TContext<E, string>;
330
+ }) => Promise<IAuthUser | null>;
331
+ }
332
+ ```
333
+
334
+ ### REST Options
335
+
336
+ | Option | Type | Default | Description |
337
+ |--------|------|---------|-------------|
338
+ | `useAuthController` | `boolean` | `false` | Enable/disable built-in auth controller |
339
+ | `controllerOpts` | `TDefineAuthControllerOpts` | -- | Configuration for built-in auth controller (required when `useAuthController` is `true`) |
340
+
341
+ `TAuthenticationRestOptions` is a discriminated union type:
342
+
343
+ ```typescript
344
+ type TAuthenticationRestOptions = {} & (
345
+ | { useAuthController?: false | undefined }
346
+ | {
347
+ useAuthController: true;
348
+ controllerOpts: TDefineAuthControllerOpts;
349
+ }
350
+ );
351
+ ```
352
+
353
+ > [!IMPORTANT]
354
+ > When `useAuthController` is `true`, the `controllerOpts` field becomes required. The discriminated union enforces this at the type level -- you cannot set `useAuthController: true` without providing `controllerOpts`.
355
+
356
+ ### Controller Options
357
+
358
+ | Option | Type | Default | Description |
359
+ |--------|------|---------|-------------|
360
+ | `restPath` | `string` | `'/auth'` | Base path for auth endpoints |
361
+ | `serviceKey` | `string` | `'services.AuthenticationService'` | DI key for the auth service |
362
+ | `requireAuthenticatedSignUp` | `boolean` | `false` | Whether sign-up requires JWT authentication |
363
+ | `payload` | `object` | `{}` | Custom Zod schemas for request/response payloads |
364
+
365
+ #### TDefineAuthControllerOpts -- Full Interface
366
+ ```typescript
367
+ type TDefineAuthControllerOpts = {
368
+ restPath?: string;
369
+ serviceKey?: string;
370
+ requireAuthenticatedSignUp?: boolean;
371
+ payload?: {
372
+ signIn?: {
373
+ request: { schema: TAnyObjectSchema };
374
+ response: { schema: TAnyObjectSchema };
375
+ };
376
+ signUp?: {
377
+ request: { schema: TAnyObjectSchema };
378
+ response: { schema: TAnyObjectSchema };
379
+ };
380
+ changePassword?: {
381
+ request: { schema?: TAnyObjectSchema };
382
+ response: { schema: TAnyObjectSchema };
383
+ };
384
+ };
385
+ };
386
+ ```
387
+
388
+ ### Route Configuration Options
389
+
390
+ These options are used in route configs to control per-route authentication:
391
+
392
+ | Option | Type | Default | Description |
393
+ |--------|------|---------|-------------|
394
+ | `authStrategies` | `TAuthStrategy[]` | -- | Array of strategy names (e.g., `['jwt']`, `['jwt', 'basic']`) |
395
+ | `authMode` | `'any' \| 'all'` | `'any'` | How to handle multiple strategies |
396
+ | `skipAuth` | `boolean` | `false` | Skip authentication for this route |
397
+
398
+ ### IAuthUser Interface
399
+
400
+ The base authenticated user type returned by strategies and available on the context:
401
+
402
+ ```typescript
403
+ interface IAuthUser {
404
+ userId: IdType;
405
+ [extra: string | symbol]: any;
406
+ }
407
+ ```
408
+
409
+ > [!TIP]
410
+ > `IAuthUser` is intentionally minimal. Your `IAuthService` implementation can extend the user payload with additional fields (roles, email, provider, etc.) -- these extra fields will be preserved through JWT token generation and available after authentication via `Authentication.CURRENT_USER`.
411
+
412
+ ### SignInRequestSchema Field Constraints
413
+
414
+ The built-in `SignInRequestSchema` enforces the following validation constraints on sign-in request payloads:
415
+
416
+ | Field | Type | Constraints |
417
+ |-------|------|-------------|
418
+ | `identifier.scheme` | `string` | Non-empty, min 4 chars (required) |
419
+ | `identifier.value` | `string` | Non-empty, min 8 chars (required) |
420
+ | `credential.scheme` | `string` | Non-empty (required) |
421
+ | `credential.value` | `string` | Non-empty, min 8 chars (required) |
422
+ | `clientId` | `string` | Optional |
423
+
424
+ ### SignUpRequestSchema Field Constraints
425
+
426
+ The built-in `SignUpRequestSchema` uses a **flat structure** (not nested like `SignInRequestSchema`):
427
+
428
+ | Field | Type | Constraints |
429
+ |-------|------|-------------|
430
+ | `username` | `string` | Non-empty, min 8 chars (required) |
431
+ | `credential` | `string` | Non-empty, min 8 chars (required) |
432
+
433
+ ### ChangePasswordRequestSchema Field Constraints
434
+
435
+ The built-in `ChangePasswordRequestSchema` uses scheme-based credential naming:
436
+
437
+ | Field | Type | Constraints |
438
+ |-------|------|-------------|
439
+ | `scheme` | `string` | Required |
440
+ | `oldCredential` | `string` | Non-empty, min 8 chars (required) |
441
+ | `newCredential` | `string` | Non-empty, min 8 chars (required) |
442
+ | `userId` | `string \| number` | Required |
443
+
444
+ #### IAuthService -- Full Interface
445
+ ```typescript
446
+ interface IAuthService<
447
+ E extends Env = Env,
448
+ SIRQ extends TSignInRequest = TSignInRequest,
449
+ SIRS = AnyObject,
450
+ SURQ extends TSignUpRequest = TSignUpRequest,
451
+ SURS = AnyObject,
452
+ CPRQ extends TChangePasswordRequest = TChangePasswordRequest,
453
+ CPRS = AnyObject,
454
+ UIRQ = AnyObject,
455
+ UIRS = AnyObject,
456
+ > {
457
+ signIn(context: TContext<E>, opts: SIRQ): Promise<SIRS>;
458
+ signUp(context: TContext<E>, opts: SURQ): Promise<SURS>;
459
+ changePassword(context: TContext<E>, opts: CPRQ): Promise<CPRS>;
460
+ getUserInformation?(context: TContext<E>, opts: UIRQ): Promise<UIRS>;
461
+ }
462
+ ```
463
+
464
+ > [!NOTE]
465
+ > `IAuthService` is generic on the Hono `Env` type as well as all request/response types. The `getUserInformation` method is optional.
466
+
467
+ #### IJWTTokenPayload -- Full Interface
468
+ ```typescript
469
+ interface IJWTTokenPayload extends JWTPayload, IAuthUser {
470
+ userId: IdType;
471
+ roles: { id: IdType; identifier: string; priority: number }[];
472
+ clientId?: string;
473
+ provider?: string;
474
+ email?: string;
475
+ name?: string;
476
+ [extra: string | symbol]: any;
477
+ }
478
+ ```
479
+
480
+ ## Binding Keys
481
+
482
+ | Key | Constant | Type | Required | Default |
483
+ |-----|----------|------|----------|---------|
484
+ | `@app/authenticate/rest-options` | `AuthenticateBindingKeys.REST_OPTIONS` | `TAuthenticationRestOptions` | No | <code v-pre>{ useAuthController: false }</code> |
485
+ | `@app/authenticate/jwt-options` | `AuthenticateBindingKeys.JWT_OPTIONS` | `IJWTTokenServiceOptions` | Conditional | -- |
486
+ | `@app/authenticate/basic-options` | `AuthenticateBindingKeys.BASIC_OPTIONS` | `IBasicTokenServiceOptions` | Conditional | -- |
487
+
488
+ > [!IMPORTANT]
489
+ > 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
+
491
+ ### Context Variables
492
+
493
+ These values are set on the Hono `Context` during authentication and can be accessed via `context.get()`:
494
+
495
+ | Key | Constant | Type | Description |
496
+ |-----|----------|------|-------------|
497
+ | `auth.current.user` | `Authentication.CURRENT_USER` | `IAuthUser` | Authenticated user payload |
498
+ | `audit.user.id` | `Authentication.AUDIT_USER_ID` | `IdType` | Authenticated user's ID |
499
+ | `authentication.skip` | `Authentication.SKIP_AUTHENTICATION` | `boolean` | Dynamically skip auth |
500
+
501
+ ### Strategy Constants
502
+
503
+ | Constant | Value | Description |
504
+ |----------|-------|-------------|
505
+ | `Authentication.STRATEGY_JWT` | `'jwt'` | JWT strategy name |
506
+ | `Authentication.STRATEGY_BASIC` | `'basic'` | Basic strategy name |
507
+ | `Authentication.TYPE_BEARER` | `'Bearer'` | Bearer token type |
508
+ | `Authentication.TYPE_BASIC` | `'Basic'` | Basic token type |
509
+
510
+ ### AuthenticateStrategy Class
511
+
512
+ Utility class for validating strategy names:
513
+
514
+ ```typescript
515
+ class AuthenticateStrategy {
516
+ static readonly BASIC = 'basic';
517
+ static readonly JWT = 'jwt';
518
+ static readonly SCHEME_SET: Set<string>;
519
+ static isValid(input: string): boolean;
520
+ }
521
+ type TAuthStrategy = TConstValue<typeof AuthenticateStrategy>;
522
+ ```
523
+
524
+ | Member | Type | Description |
525
+ |--------|------|-------------|
526
+ | `BASIC` | `string` | Constant for basic strategy name |
527
+ | `JWT` | `string` | Constant for JWT strategy name |
528
+ | `SCHEME_SET` | `Set<string>` | Set containing all valid strategy names |
529
+ | `isValid(input)` | `(input: string) => boolean` | Returns `true` if the input is a recognized strategy name |
530
+
531
+ ### AuthenticationModes Class
532
+
533
+ Utility class for validating authentication modes:
534
+
535
+ ```typescript
536
+ class AuthenticationModes {
537
+ static readonly ANY = 'any';
538
+ static readonly ALL = 'all';
539
+ }
540
+ type TAuthMode = TConstValue<typeof AuthenticationModes>;
541
+ ```
542
+
543
+ | Member | Type | Description |
544
+ |--------|------|-------------|
545
+ | `ANY` | `string` | First successful strategy wins (fallback) |
546
+ | `ALL` | `string` | All strategies must pass (MFA) |
547
+
548
+ ## See Also
549
+
550
+ - [Usage & Examples](./usage) -- Securing routes, auth flows, and API endpoints
551
+ - [API Reference](./api) -- Architecture, service internals, and strategy registry
552
+ - [Error Reference](./errors) -- Error messages and troubleshooting
553
+
554
+ - **Guides:**
555
+ - [Components Overview](/guides/core-concepts/components) -- Component system basics
556
+ - [Controllers](/guides/core-concepts/controllers) -- Protecting routes with auth
557
+
558
+ - **Components:**
559
+ - [All Components](../index) -- Built-in components list
560
+
561
+ - **Helpers:**
562
+ - [Crypto Helper](/references/helpers/crypto/) -- Password hashing utilities
563
+
564
+ - **References:**
565
+ - [Middlewares](/references/base/middlewares) -- Custom authentication middleware
566
+
567
+ - **Best Practices:**
568
+ - [Security Guidelines](/best-practices/security-guidelines) -- Authentication best practices
569
+
570
+ - **Tutorials:**
571
+ - [Building a CRUD API](/guides/tutorials/building-a-crud-api) -- Adding authentication