@venizia/ignis-docs 0.0.8 → 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 +7 -7
- package/content/best-practices/api-usage-examples.md +15 -12
- package/content/best-practices/architectural-patterns.md +70 -78
- package/content/best-practices/architecture-decisions.md +91 -60
- package/content/best-practices/code-style-standards/advanced-patterns.md +56 -44
- package/content/best-practices/code-style-standards/constants-configuration.md +11 -11
- package/content/best-practices/code-style-standards/control-flow.md +5 -2
- package/content/best-practices/code-style-standards/documentation.md +13 -13
- package/content/best-practices/code-style-standards/function-patterns.md +9 -10
- package/content/best-practices/code-style-standards/index.md +1 -1
- package/content/best-practices/code-style-standards/naming-conventions.md +10 -8
- package/content/best-practices/code-style-standards/route-definitions.md +30 -12
- package/content/best-practices/code-style-standards/tooling.md +8 -5
- package/content/best-practices/code-style-standards/type-safety.md +13 -12
- package/content/best-practices/common-pitfalls.md +56 -37
- package/content/best-practices/contribution-workflow.md +13 -14
- package/content/best-practices/data-modeling.md +46 -22
- package/content/best-practices/deployment-strategies.md +28 -27
- package/content/best-practices/error-handling.md +48 -24
- package/content/best-practices/index.md +5 -5
- package/content/best-practices/performance-optimization.md +40 -31
- package/content/best-practices/security-guidelines.md +52 -23
- package/content/best-practices/testing-strategies.md +65 -51
- package/content/best-practices/troubleshooting-tips.md +24 -24
- package/content/extensions/components/{swagger.md → api-reference.md} +40 -31
- package/content/extensions/components/authentication/api.md +19 -19
- package/content/extensions/components/authentication/errors.md +7 -7
- package/content/extensions/components/authentication/index.md +10 -8
- package/content/extensions/components/authentication/usage.md +101 -6
- package/content/extensions/components/authorization/api.md +45 -25
- package/content/extensions/components/authorization/errors.md +6 -6
- package/content/extensions/components/authorization/index.md +11 -10
- package/content/extensions/components/authorization/usage.md +21 -21
- package/content/extensions/components/health-check.md +1 -1
- package/content/extensions/components/index.md +5 -5
- package/content/extensions/components/mail/errors.md +15 -15
- package/content/extensions/components/mail/index.md +1 -2
- package/content/extensions/components/mail/usage.md +1 -1
- package/content/extensions/components/request-tracker.md +1 -1
- package/content/extensions/components/socket-io/api.md +9 -9
- package/content/extensions/components/socket-io/errors.md +5 -5
- package/content/extensions/components/socket-io/index.md +8 -8
- package/content/extensions/components/socket-io/usage.md +1 -1
- package/content/extensions/components/static-asset/api.md +17 -4
- package/content/extensions/components/static-asset/errors.md +4 -4
- package/content/extensions/components/static-asset/index.md +26 -28
- package/content/extensions/components/static-asset/usage.md +13 -12
- package/content/extensions/components/template/index.md +2 -2
- package/content/extensions/components/template/setup-page.md +1 -1
- package/content/extensions/components/websocket/api.md +3 -3
- package/content/extensions/components/websocket/errors.md +5 -5
- package/content/extensions/components/websocket/index.md +5 -5
- package/content/extensions/components/websocket/usage.md +3 -3
- package/content/extensions/helpers/cron/index.md +2 -2
- package/content/extensions/helpers/crypto/index.md +1 -1
- package/content/extensions/helpers/env/index.md +27 -12
- package/content/extensions/helpers/error/index.md +81 -25
- package/content/extensions/helpers/index.md +2 -3
- package/content/extensions/helpers/inversion/index.md +15 -7
- package/content/extensions/helpers/kafka/compile-binary.md +92 -0
- package/content/extensions/helpers/kafka/examples.md +1 -1
- package/content/extensions/helpers/kafka/index.md +3 -0
- package/content/extensions/helpers/logger/index.md +32 -2
- package/content/extensions/helpers/network/index.md +6 -0
- package/content/extensions/helpers/queue/index.md +14 -17
- package/content/extensions/helpers/redis/index.md +548 -323
- package/content/extensions/helpers/socket-io/index.md +14 -10
- package/content/extensions/helpers/storage/api.md +44 -8
- package/content/extensions/helpers/storage/index.md +43 -7
- package/content/extensions/helpers/template/index.md +6 -3
- package/content/extensions/helpers/types/index.md +11 -8
- package/content/extensions/helpers/websocket/api.md +9 -9
- package/content/extensions/helpers/websocket/index.md +7 -7
- package/content/extensions/helpers/worker-thread/index.md +2 -2
- package/content/extensions/index.md +3 -4
- package/content/extensions/src-details/mcp-server.md +18 -24
- package/content/guides/core-concepts/application/bootstrapping.md +11 -14
- package/content/guides/core-concepts/application/index.md +3 -3
- package/content/guides/core-concepts/components.md +19 -10
- package/content/guides/core-concepts/dependency-injection.md +6 -3
- package/content/guides/core-concepts/grpc-controllers.md +6 -5
- package/content/guides/core-concepts/persistent/datasources.md +42 -43
- package/content/guides/core-concepts/persistent/index.md +16 -7
- package/content/guides/core-concepts/persistent/models.md +24 -20
- package/content/guides/core-concepts/persistent/postgres-drivers.md +201 -0
- package/content/guides/core-concepts/persistent/repositories.md +40 -23
- package/content/guides/core-concepts/persistent/search-meilisearch.md +185 -0
- package/content/guides/core-concepts/persistent/search-typesense.md +431 -0
- package/content/guides/core-concepts/persistent/transactions.md +61 -25
- package/content/guides/core-concepts/rest-controllers.md +12 -9
- package/content/guides/core-concepts/services.md +330 -60
- package/content/guides/get-started/5-minute-quickstart.md +15 -15
- package/content/guides/get-started/philosophy.md +36 -36
- package/content/guides/get-started/setup.md +3 -3
- package/content/guides/index.md +3 -3
- package/content/guides/migrations/redis-helpers-migration.md +177 -0
- package/content/guides/migrations/scoped-rbac-migration.md +17 -17
- package/content/guides/migrations/unified-connectors-migration.md +113 -0
- package/content/guides/reference/glossary.md +19 -12
- package/content/guides/reference/mcp-docs-server.md +22 -18
- package/content/guides/tutorials/building-a-crud-api.md +37 -44
- package/content/guides/tutorials/complete-installation.md +17 -17
- package/content/guides/tutorials/ecommerce-api.md +163 -124
- package/content/guides/tutorials/realtime-chat.md +181 -135
- package/content/guides/tutorials/testing.md +65 -523
- package/content/index.md +2 -180
- package/content/public/apple-touch-icon.png +0 -0
- package/content/public/og-image.png +0 -0
- package/content/public/site.webmanifest +11 -0
- package/content/references/base/application.md +4 -5
- package/content/references/base/bootstrapping.md +18 -5
- package/content/references/base/components.md +149 -120
- package/content/references/base/connectors.md +178 -0
- package/content/references/base/controllers.md +41 -30
- package/content/references/base/datasources.md +163 -92
- package/content/references/base/dependency-injection.md +34 -22
- package/content/references/base/filter-system/application-usage.md +17 -14
- package/content/references/base/filter-system/array-operators.md +7 -2
- package/content/references/base/filter-system/comparison-operators.md +3 -0
- package/content/references/base/filter-system/default-filter.md +89 -71
- package/content/references/base/filter-system/fields-order-pagination.md +22 -22
- package/content/references/base/filter-system/index.md +6 -3
- package/content/references/base/filter-system/json-filtering.md +20 -1
- package/content/references/base/filter-system/list-operators.md +1 -1
- package/content/references/base/filter-system/logical-operators.md +33 -1
- package/content/references/base/filter-system/null-operators.md +30 -1
- package/content/references/base/filter-system/quick-reference.md +23 -4
- package/content/references/base/filter-system/tips.md +5 -5
- package/content/references/base/filter-system/use-cases.md +12 -12
- package/content/references/base/grpc-controllers.md +13 -13
- package/content/references/base/index.md +24 -12
- package/content/references/base/middlewares.md +265 -327
- package/content/references/base/models.md +63 -49
- package/content/references/base/providers.md +136 -130
- package/content/references/base/repositories/advanced.md +59 -58
- package/content/references/base/repositories/index.md +115 -91
- package/content/references/base/repositories/mixins.md +55 -291
- package/content/references/base/repositories/relations.md +54 -64
- package/content/references/base/repositories/soft-deletable.md +31 -30
- package/content/references/base/services.md +296 -93
- package/content/references/configuration/environment-variables.md +49 -31
- package/content/references/configuration/index.md +6 -6
- package/content/references/index.md +17 -12
- package/content/references/quick-reference.md +65 -106
- package/content/references/utilities/crypto.md +65 -23
- package/content/references/utilities/index.md +3 -3
- package/content/references/utilities/jsx.md +6 -4
- package/content/references/utilities/module.md +68 -20
- package/content/references/utilities/parse.md +4 -14
- package/content/references/utilities/promise.md +9 -7
- package/content/references/utilities/schema.md +5 -3
- package/dist/mcp-server/common/guards.d.ts +8 -0
- package/dist/mcp-server/common/guards.d.ts.map +1 -0
- package/dist/mcp-server/common/guards.js +14 -0
- package/dist/mcp-server/common/guards.js.map +1 -0
- package/dist/mcp-server/common/index.d.ts +1 -0
- package/dist/mcp-server/common/index.d.ts.map +1 -1
- package/dist/mcp-server/common/index.js +1 -0
- package/dist/mcp-server/common/index.js.map +1 -1
- package/dist/mcp-server/helpers/docs.helper.d.ts.map +1 -1
- package/dist/mcp-server/helpers/docs.helper.js +4 -2
- package/dist/mcp-server/helpers/docs.helper.js.map +1 -1
- package/dist/mcp-server/helpers/github.helper.js +1 -1
- package/dist/mcp-server/index.js +7 -2
- package/dist/mcp-server/index.js.map +1 -1
- package/dist/mcp-server/tools/base.tool.d.ts +6 -2
- package/dist/mcp-server/tools/base.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/base.tool.js.map +1 -1
- package/dist/mcp-server/tools/docs/search-documents.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/search-code.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/search-code.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/search-code.tool.js +4 -1
- package/dist/mcp-server/tools/github/search-code.tool.js.map +1 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js +3 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js.map +1 -1
- package/package.json +9 -9
- package/content/extensions/helpers/testing/index.md +0 -510
- package/content/references/base/middleware.md +0 -347
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Troubleshooting Tips
|
|
2
2
|
|
|
3
|
-
Common issues and their solutions when building
|
|
3
|
+
Common issues and their solutions when building IGNIS applications.
|
|
4
4
|
|
|
5
5
|
## 1. Application Fails to Start
|
|
6
6
|
|
|
@@ -31,8 +31,9 @@ lsof -ti:3000 | xargs kill -9
|
|
|
31
31
|
```typescript
|
|
32
32
|
// In application.ts config
|
|
33
33
|
export const appConfigs: IApplicationConfigs = {
|
|
34
|
+
path: { base: '/api', isStrict: true },
|
|
34
35
|
debug: {
|
|
35
|
-
|
|
36
|
+
shouldShowRoutes: process.env.NODE_ENV !== 'production',
|
|
36
37
|
},
|
|
37
38
|
};
|
|
38
39
|
```
|
|
@@ -90,8 +91,8 @@ class UserService {
|
|
|
90
91
|
// Output: [UserService-createUser] Creating user: {...}
|
|
91
92
|
|
|
92
93
|
try {
|
|
93
|
-
const user = await this.
|
|
94
|
-
this.logger.for('createUser').info('User created: %s', user.id);
|
|
94
|
+
const user = await this.userRepository.create({ data });
|
|
95
|
+
this.logger.for('createUser').info('User created: %s', user.data.id);
|
|
95
96
|
return user;
|
|
96
97
|
} catch (error) {
|
|
97
98
|
this.logger.for('createUser').error('Failed: %s', error);
|
|
@@ -122,21 +123,19 @@ cat .env | grep APP_ENV
|
|
|
122
123
|
|
|
123
124
|
## 6. Request ID Tracking
|
|
124
125
|
|
|
125
|
-
Every request in
|
|
126
|
+
Every request in IGNIS is automatically assigned a unique `requestId` for log correlation (via `RequestTrackerComponent`, which registers Hono's `requestId()` middleware plus a request-spy middleware). The spy middleware logs this ID when a request starts (`[=>]`) and finishes (`[<=]`).
|
|
126
127
|
|
|
127
128
|
**Log output format:**
|
|
128
129
|
```
|
|
129
|
-
[
|
|
130
|
-
[
|
|
130
|
+
[SpyMW] [abc123][192.168.1.1][=>] GET /api/users | query: {}
|
|
131
|
+
[SpyMW] [abc123][192.168.1.1][<=] GET /api/users | Took: 45.20 (ms)
|
|
131
132
|
```
|
|
132
133
|
|
|
133
134
|
**Access request ID in handlers:**
|
|
134
135
|
```typescript
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
// Inside a controller method
|
|
136
|
+
// Inside a controller method - 'requestId' is the Hono request-id context variable
|
|
138
137
|
async getUser(c: Context) {
|
|
139
|
-
const requestId = c.get(
|
|
138
|
+
const requestId = c.get('requestId');
|
|
140
139
|
this.logger.info('[%s] Processing user request', requestId);
|
|
141
140
|
// ...
|
|
142
141
|
}
|
|
@@ -148,53 +147,54 @@ async getUser(c: Context) {
|
|
|
148
147
|
grep "abc123" logs/app.log
|
|
149
148
|
|
|
150
149
|
# Extract request timing
|
|
151
|
-
grep "\[
|
|
150
|
+
grep "\[abc123\]" logs/app.log | grep "Took:"
|
|
152
151
|
```
|
|
153
152
|
|
|
154
153
|
**Why this matters:**
|
|
155
154
|
- Correlate logs across services in distributed systems
|
|
156
155
|
- Debug specific user issues by their request ID
|
|
157
|
-
- Measure request duration from
|
|
156
|
+
- Measure request duration from the `[=>]` / `[<=]` log pair
|
|
158
157
|
|
|
159
158
|
## 7. Validation Error Debugging
|
|
160
159
|
|
|
161
|
-
When Zod validation fails,
|
|
160
|
+
When Zod validation fails, IGNIS returns a structured error response. Understanding this format helps debug client-side issues.
|
|
162
161
|
|
|
163
|
-
**Error response structure
|
|
162
|
+
**Error response structure** (top-level `message`/`messageCode` come from the first issue; the fallback message is `ValidationError`):
|
|
164
163
|
```json
|
|
165
164
|
{
|
|
166
165
|
"statusCode": 422,
|
|
167
|
-
"message": "
|
|
166
|
+
"message": "Invalid email address",
|
|
167
|
+
"messageCode": "invalid_format",
|
|
168
168
|
"requestId": "abc123",
|
|
169
169
|
"details": {
|
|
170
|
+
"url": "http://localhost:3000/api/users",
|
|
171
|
+
"path": "/api/users",
|
|
170
172
|
"cause": [
|
|
171
173
|
{
|
|
172
174
|
"path": "email",
|
|
173
|
-
"message": "Invalid email",
|
|
174
|
-
"code": "
|
|
175
|
-
"expected": "email",
|
|
176
|
-
"received": "string"
|
|
175
|
+
"message": "Invalid email address",
|
|
176
|
+
"code": "invalid_format"
|
|
177
177
|
}
|
|
178
178
|
]
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
181
|
```
|
|
182
182
|
|
|
183
|
-
**Common validation error codes:**
|
|
183
|
+
**Common validation error codes (Zod v4):**
|
|
184
184
|
|
|
185
185
|
| Code | Meaning | Example |
|
|
186
186
|
|------|---------|---------|
|
|
187
187
|
| `invalid_type` | Wrong data type | Expected `number`, got `string` |
|
|
188
|
-
| `
|
|
188
|
+
| `invalid_format` | String format invalid | Invalid email or UUID format |
|
|
189
189
|
| `too_small` | Value below minimum | String shorter than min length |
|
|
190
190
|
| `too_big` | Value above maximum | Number exceeds max value |
|
|
191
|
-
| `
|
|
191
|
+
| `invalid_value` | Value not in enum/literal | Status must be 'ACTIVE' or 'INACTIVE' |
|
|
192
192
|
| `unrecognized_keys` | Extra fields in request | Strict schema rejects unknown fields |
|
|
193
193
|
|
|
194
194
|
**Debugging tips:**
|
|
195
195
|
|
|
196
196
|
1. **Check the `path` field** - Shows which field failed validation
|
|
197
|
-
2. **Compare `expected` vs `received`** -
|
|
197
|
+
2. **Compare `expected` vs `received`** - Present on `invalid_type` issues, identifies type mismatches
|
|
198
198
|
3. **Review schema definition** - Ensure client sends correct format
|
|
199
199
|
|
|
200
200
|
**Example: Debugging nested validation errors:**
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
#
|
|
1
|
+
# API Reference
|
|
2
2
|
|
|
3
3
|
Automatic interactive API documentation generation using OpenAPI specifications, powered by Scalar or Swagger UI.
|
|
4
4
|
|
|
5
|
+
> [!NOTE] Renamed from SwaggerComponent
|
|
6
|
+
> Swagger UI is just one of the pluggable UI providers, so the component carries a vendor-neutral name. `SwaggerComponent`, `ISwaggerOptions`, and `SwaggerBindingKeys` remain available as deprecated aliases - existing applications keep working unchanged.
|
|
7
|
+
|
|
5
8
|
## Quick Reference
|
|
6
9
|
|
|
7
10
|
| Item | Value |
|
|
8
11
|
|------|-------|
|
|
9
12
|
| **Package** | `@venizia/ignis` |
|
|
10
|
-
| **Class** | `
|
|
13
|
+
| **Class** | `ApiReferenceComponent` |
|
|
11
14
|
| **UI Factory** | `UIProviderFactory` |
|
|
12
15
|
| **Runtimes** | Both |
|
|
13
16
|
|
|
@@ -18,8 +21,8 @@ Automatic interactive API documentation generation using OpenAPI specifications,
|
|
|
18
21
|
|
|
19
22
|
#### Import Paths
|
|
20
23
|
```typescript
|
|
21
|
-
import {
|
|
22
|
-
import type {
|
|
24
|
+
import { ApiReferenceComponent, ApiReferenceBindingKeys, UIProviderFactory } from '@venizia/ignis';
|
|
25
|
+
import type { IApiReferenceOptions, IUIProvider, IUIConfig, IGetProviderParams } from '@venizia/ignis';
|
|
23
26
|
```
|
|
24
27
|
|
|
25
28
|
## Setup
|
|
@@ -30,10 +33,10 @@ Skip this step to use the defaults (Scalar UI at `/doc/explorer`). To customize:
|
|
|
30
33
|
|
|
31
34
|
```typescript
|
|
32
35
|
// In your Application class's preConfigure method (src/application.ts)
|
|
33
|
-
import {
|
|
36
|
+
import { ApiReferenceBindingKeys, IApiReferenceOptions } from '@venizia/ignis';
|
|
34
37
|
|
|
35
|
-
this.bind<
|
|
36
|
-
key:
|
|
38
|
+
this.bind<IApiReferenceOptions>({
|
|
39
|
+
key: ApiReferenceBindingKeys.API_REFERENCE_OPTIONS,
|
|
37
40
|
}).toValue({
|
|
38
41
|
restOptions: {
|
|
39
42
|
base: { path: '/doc' },
|
|
@@ -50,12 +53,12 @@ this.bind<ISwaggerOptions>({
|
|
|
50
53
|
|
|
51
54
|
```typescript
|
|
52
55
|
// src/application.ts
|
|
53
|
-
import {
|
|
56
|
+
import { ApiReferenceComponent, BaseApplication, ValueOrPromise } from '@venizia/ignis';
|
|
54
57
|
|
|
55
58
|
export class Application extends BaseApplication {
|
|
56
59
|
preConfigure(): ValueOrPromise<void> {
|
|
57
60
|
// ...
|
|
58
|
-
this.component(
|
|
61
|
+
this.component(ApiReferenceComponent);
|
|
59
62
|
}
|
|
60
63
|
}
|
|
61
64
|
```
|
|
@@ -89,7 +92,7 @@ export class HelloController extends BaseRestController {
|
|
|
89
92
|
},
|
|
90
93
|
},
|
|
91
94
|
handler: (c) => {
|
|
92
|
-
return c.json({ message: 'Hello, `
|
|
95
|
+
return c.json({ message: 'Hello, `IGNIS`!' }, HTTP.ResultCodes.RS_2.Ok);
|
|
93
96
|
},
|
|
94
97
|
});
|
|
95
98
|
}
|
|
@@ -116,9 +119,9 @@ export class HelloController extends BaseRestController {
|
|
|
116
119
|
> [!NOTE]
|
|
117
120
|
> The `explorer.servers` field is auto-populated only when empty. If you provide `explorer.servers` with at least one entry, the component preserves your values. When no servers are configured, it creates a default entry from `application.getServerAddress()` plus the application base path.
|
|
118
121
|
|
|
119
|
-
####
|
|
122
|
+
#### IApiReferenceOptions -- Full Reference
|
|
120
123
|
```typescript
|
|
121
|
-
export interface
|
|
124
|
+
export interface IApiReferenceOptions {
|
|
122
125
|
restOptions: {
|
|
123
126
|
base: { path: string };
|
|
124
127
|
doc: { path: string };
|
|
@@ -183,9 +186,9 @@ This interface is exported for use when building custom tooling around the `UIPr
|
|
|
183
186
|
|
|
184
187
|
### Component Lifecycle
|
|
185
188
|
|
|
186
|
-
The `
|
|
189
|
+
The `ApiReferenceComponent` executes the following during `binding()`:
|
|
187
190
|
|
|
188
|
-
1. **Resolve options** -- reads `
|
|
191
|
+
1. **Resolve options** -- reads `ApiReferenceBindingKeys.API_REFERENCE_OPTIONS` from DI using `application.get()` with `isOptional: true`, then deep-merges what it finds over `DEFAULT_API_REFERENCE_OPTIONS` group by group, so an application that overrides one path keeps the defaults for the rest
|
|
189
192
|
2. **Overwrite info** -- unconditionally reads `package.json` via `application.getAppInfo()` and overwrites `explorer.info` with `{ title: appInfo.name, version: appInfo.version, description: appInfo.description, contact: appInfo.author }`
|
|
190
193
|
3. **Auto-detect servers** -- if `explorer.servers` is empty or unset, creates one entry from `http://` + `application.getServerAddress()` + `configs.path.base`
|
|
191
194
|
4. **Normalize paths** -- all path segments (`base.path`, `doc.path`, `ui.path`) are normalized to ensure a leading `/` is present, handling both `/path` and `path` inputs
|
|
@@ -201,7 +204,7 @@ The `SwaggerComponent` executes the following during `binding()`:
|
|
|
201
204
|
|
|
202
205
|
| Component | Class | Role |
|
|
203
206
|
|-----------|-------|------|
|
|
204
|
-
| **
|
|
207
|
+
| **ApiReferenceComponent** | `extends BaseComponent` | Orchestrates binding, overwrites OpenAPI metadata from `package.json` |
|
|
205
208
|
| **UIProviderFactory** | `extends MemoryStorageHelper` (singleton) | Registry for UI providers, validates and instantiates |
|
|
206
209
|
| **SwaggerUIProvider** | `implements IUIProvider` | Renders Swagger UI via `@hono/swagger-ui` |
|
|
207
210
|
| **ScalarUIProvider** | `implements IUIProvider` | Renders Scalar UI via `@scalar/hono-api-reference` |
|
|
@@ -314,24 +317,30 @@ This ensures routes using `authStrategies: ['jwt']` or `authStrategies: ['basic'
|
|
|
314
317
|
|
|
315
318
|
| Key | Constant | Type | Required | Default |
|
|
316
319
|
|-----|----------|------|----------|---------|
|
|
317
|
-
| `@app/
|
|
320
|
+
| `@app/api-reference/options` | `ApiReferenceBindingKeys.API_REFERENCE_OPTIONS` | `IApiReferenceOptions` | No | See below |
|
|
321
|
+
|
|
322
|
+
The deprecated `SwaggerBindingKeys.SWAGGER_OPTIONS` still resolves - it is an alias whose **value** is that same `'@app/api-reference/options'` string. There is no binding under the literal `'@app/swagger/options'`; binding that raw string does nothing.
|
|
318
323
|
|
|
319
|
-
The
|
|
324
|
+
The constructor registers the default through `super()`, so the binding is in the container from the start:
|
|
320
325
|
|
|
321
326
|
```typescript
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
+
super({
|
|
328
|
+
scope: ApiReferenceComponent.name,
|
|
329
|
+
initDefault: { enable: true, container: application },
|
|
330
|
+
bindings: {
|
|
331
|
+
[ApiReferenceBindingKeys.API_REFERENCE_OPTIONS]: Binding.bind<IApiReferenceOptions>({
|
|
332
|
+
key: ApiReferenceBindingKeys.API_REFERENCE_OPTIONS,
|
|
333
|
+
}).toValue(DEFAULT_API_REFERENCE_OPTIONS),
|
|
334
|
+
},
|
|
335
|
+
});
|
|
327
336
|
```
|
|
328
337
|
|
|
329
|
-
|
|
338
|
+
`binding()` then reads the key back with `isOptional: true` and **deep-merges** whatever the application bound over the defaults, group by group (`base`, `doc`, `ui`, `explorer`) - so overriding one path does not wipe the others. The merge builds a fresh `explorer` object per application; mutating the bound one would leak this application's info into every later application in the same process.
|
|
330
339
|
|
|
331
340
|
**Default value:**
|
|
332
341
|
|
|
333
342
|
```typescript
|
|
334
|
-
const
|
|
343
|
+
const DEFAULT_API_REFERENCE_OPTIONS: IApiReferenceOptions = {
|
|
335
344
|
restOptions: {
|
|
336
345
|
base: { path: '/doc' },
|
|
337
346
|
doc: { path: '/openapi.json' },
|
|
@@ -349,7 +358,7 @@ const DEFAULT_SWAGGER_OPTIONS: ISwaggerOptions = {
|
|
|
349
358
|
```
|
|
350
359
|
|
|
351
360
|
> [!NOTE]
|
|
352
|
-
> The `explorer.info` values in `
|
|
361
|
+
> The `explorer.info` values in `DEFAULT_API_REFERENCE_OPTIONS` are never used at runtime because `binding()` unconditionally overwrites `explorer.info` with data from `package.json`. They exist only as structural defaults.
|
|
353
362
|
|
|
354
363
|
### Type Definitions
|
|
355
364
|
|
|
@@ -401,8 +410,8 @@ Returns the raw OpenAPI JSON specification generated from all registered control
|
|
|
401
410
|
**Fix:** Use a valid UI type:
|
|
402
411
|
|
|
403
412
|
```typescript
|
|
404
|
-
this.bind<
|
|
405
|
-
key:
|
|
413
|
+
this.bind<IApiReferenceOptions>({
|
|
414
|
+
key: ApiReferenceBindingKeys.API_REFERENCE_OPTIONS,
|
|
406
415
|
}).toValue({
|
|
407
416
|
restOptions: {
|
|
408
417
|
base: { path: '/doc' },
|
|
@@ -439,17 +448,17 @@ this.defineRoute({
|
|
|
439
448
|
|
|
440
449
|
**Cause:** The `UIProviderFactory.getProvider()` was called with a type that has not been registered. This typically happens if the component binding phase failed silently.
|
|
441
450
|
|
|
442
|
-
**Fix:** Ensure the `
|
|
451
|
+
**Fix:** Ensure the `ApiReferenceComponent` is registered in `preConfigure()` and that no errors occur during its `binding()` phase. Check the application logs for warnings from `UIProviderFactory`.
|
|
443
452
|
|
|
444
453
|
### OpenAPI spec missing authentication schemes
|
|
445
454
|
|
|
446
|
-
**Cause:** The `
|
|
455
|
+
**Cause:** The `ApiReferenceComponent` auto-registers JWT and Basic security schemes. If the `AuthenticationComponent` is not registered, authenticated routes will not show auth UI in the documentation.
|
|
447
456
|
|
|
448
|
-
**Fix:** Register `AuthenticationComponent` before `
|
|
457
|
+
**Fix:** Register `AuthenticationComponent` before `ApiReferenceComponent` in `preConfigure()` to ensure auth strategies are available when the Swagger component configures security schemes.
|
|
449
458
|
|
|
450
459
|
### explorer.info values not matching custom configuration
|
|
451
460
|
|
|
452
|
-
**Cause:** The `
|
|
461
|
+
**Cause:** The `ApiReferenceComponent` unconditionally overwrites `explorer.info` with values from `package.json` during its `binding()` phase. Any values you set in `explorer.info` via the DI binding are discarded.
|
|
453
462
|
|
|
454
463
|
**Fix:** Update your project's `package.json` fields (`name`, `version`, `description`, `author`) to control what appears in the API documentation info section. The component reads these via `application.getAppInfo()`.
|
|
455
464
|
|
|
@@ -91,7 +91,7 @@ The `AuthenticateComponent` uses five methods during its `binding()` lifecycle (
|
|
|
91
91
|
| Method | Purpose |
|
|
92
92
|
|--------|---------|
|
|
93
93
|
| `defineJWSAuth(opts)` | Validates JWS secrets (rejects falsy values and `'unknown_secret'`), validates `getTokenExpiresFn`, binds `IJWSTokenServiceOptions` to `JWT_OPTIONS`, registers `JWSTokenService`. |
|
|
94
|
-
| `defineJWKSAuth(opts)` | Switches on `mode`: **Issuer**
|
|
94
|
+
| `defineJWKSAuth(opts)` | Switches on `mode`: **Issuer** - validates keys, format, kid, getTokenExpiresFn; binds to `JWKS_OPTIONS`; registers `JWKSIssuerTokenService` + `JWKSController`. **Verifier** - validates jwksUrl; binds to `JWKS_OPTIONS`; registers `JWKSVerifierTokenService`. |
|
|
95
95
|
| `defineBasicAuth(opts)` | Validates `verifyCredentials` callback presence, binds `BasicTokenService` as a service. Logs debug if skipped. |
|
|
96
96
|
| `defineControllers(opts)` | Requires `jwtOptions` when `useAuthController: true`. Calls `defineAuthController()` factory and registers the generated controller. |
|
|
97
97
|
| `defineOAuth2()` | **Public** stub method -- not yet implemented. Called during `binding()` but performs no action. |
|
|
@@ -133,8 +133,8 @@ AuthenticationStrategyRegistry.getInstance().register({
|
|
|
133
133
|
**Middleware creation:**
|
|
134
134
|
|
|
135
135
|
The `authenticate()` function returns a Hono middleware that:
|
|
136
|
-
1. Checks if `Authentication.SKIP_AUTHENTICATION` is set on context
|
|
137
|
-
2. Checks if `Authentication.CURRENT_USER` is already set on context
|
|
136
|
+
1. Checks if `Authentication.SKIP_AUTHENTICATION` is set on context - if true, skips entirely (logs debug)
|
|
137
|
+
2. Checks if `Authentication.CURRENT_USER` is already set on context - if true, skips (already authenticated)
|
|
138
138
|
3. Reads `strategies` and `mode` from the provided options
|
|
139
139
|
4. Executes strategies based on mode (`any` or `all`)
|
|
140
140
|
5. On success, sets `Authentication.CURRENT_USER` and `Authentication.AUDIT_USER_ID` on context
|
|
@@ -179,7 +179,7 @@ export const authenticate = (opts: { strategies: string[]; mode?: TAuthMode }) =
|
|
|
179
179
|
This is the primary export for creating auth middleware. It creates an `AuthenticationProvider` instance and calls `.value()` to get the middleware factory. The provider uses `AuthenticationStrategyRegistry.getInstance()` internally to resolve strategies.
|
|
180
180
|
|
|
181
181
|
> [!NOTE]
|
|
182
|
-
> In `all` mode, the **first** strategy's user payload is used as the identity source
|
|
182
|
+
> In `all` mode, the **first** strategy's user payload is used as the identity source - all strategies must succeed but the first one wins for identity. If every strategy passes but the first user payload has no `userId`, the middleware throws a `401` with message `"Failed to identify authenticated user!"`. The `any` mode **discards errors** from each failing strategy (logs at debug level) and only throws after all strategies are exhausted.
|
|
183
183
|
|
|
184
184
|
## Service Class Hierarchy
|
|
185
185
|
|
|
@@ -259,8 +259,8 @@ Base class for all Bearer token services. Extends `BaseService`. Generic on <cod
|
|
|
259
259
|
|--------|-----------|-------------|
|
|
260
260
|
| `configurePayloadEncryption` | <code v-pre>(opts: { aesAlgorithm?: AESAlgorithmType; applicationSecret?: string; fieldCodecs?: IPayloadFieldCodec[] }) => void</code> | Configures optional AES encryption and field codecs. Codecs are converted to a Map keyed by `codec.key` for O(1) lookup. |
|
|
261
261
|
| `extractCredentials` | <code v-pre>(context: TContext<E, string>) => { type: string; token: string }</code> | Extracts Bearer token from Authorization header |
|
|
262
|
-
| `verify` | <code v-pre>(opts: { type: string; token: string }) => Promise<IJWTTokenPayload></code> | Template method
|
|
263
|
-
| `generate` | <code v-pre>(opts: { payload: IJWTTokenPayload; getTokenExpiresFn?: TGetTokenExpiresFn }) => Promise<string></code> | Template method
|
|
262
|
+
| `verify` | <code v-pre>(opts: { type: string; token: string }) => Promise<IJWTTokenPayload></code> | Template method - calls `doVerify()` |
|
|
263
|
+
| `generate` | <code v-pre>(opts: { payload: IJWTTokenPayload; getTokenExpiresFn?: TGetTokenExpiresFn }) => Promise<string></code> | Template method - calls `getSigner()` + `getSigningKey()` |
|
|
264
264
|
| `serializeField` | <code v-pre>(opts: { key: string; value: any }) => string</code> | Serializes a single field: codec → `JSON.stringify` fallback |
|
|
265
265
|
| `deserializeField` | <code v-pre>(opts: { key: string; value: string }) => any</code> | Deserializes a single field: codec → `JSON.parse` fallback |
|
|
266
266
|
| `encryptPayload` | <code v-pre>(payload: IJWTTokenPayload) => Record<string, any></code> | AES-encrypts non-standard JWT fields using `serializeField`. Returns payload unchanged if AES not configured. |
|
|
@@ -421,17 +421,17 @@ constructor(
|
|
|
421
421
|
protected options: IJWKSIssuerOptions,
|
|
422
422
|
) {
|
|
423
423
|
// Calls configurePayloadEncryption({ aesAlgorithm, applicationSecret })
|
|
424
|
-
// Keys are NOT loaded here
|
|
424
|
+
// Keys are NOT loaded here - loaded lazily via ensureInitialized()
|
|
425
425
|
}
|
|
426
426
|
```
|
|
427
427
|
|
|
428
428
|
### Initialization Flow
|
|
429
429
|
|
|
430
430
|
The `initialize()` method:
|
|
431
|
-
1. **Resolves key content**
|
|
432
|
-
2. **Parses key material**
|
|
433
|
-
3. **Exports public JWK**
|
|
434
|
-
4. **Caches JWKS**
|
|
431
|
+
1. **Resolves key content** - reads from file (`readFile` from `node:fs/promises`) or uses inline text, based on `keys.driver`
|
|
432
|
+
2. **Parses key material** - imports keys using `importPKCS8`/`importSPKI` (PEM format) or `importJWK` (JWK format), based on `keys.format`
|
|
433
|
+
3. **Exports public JWK** - calls `exportJWK()` and adds `kid`, `alg`, `use: 'sig'` metadata
|
|
434
|
+
4. **Caches JWKS** - stores `{ keys: [publicJWK] }` for the `/certs` endpoint
|
|
435
435
|
5. **Sets `initialized = true`**
|
|
436
436
|
|
|
437
437
|
### Overridden Methods
|
|
@@ -447,8 +447,8 @@ The `initialize()` method:
|
|
|
447
447
|
|
|
448
448
|
| Method | Signature | Description |
|
|
449
449
|
|--------|-----------|-------------|
|
|
450
|
-
| `getJWKS` | `() => { keys: JWK[] }` | Synchronous
|
|
451
|
-
| `getJWKSAsync` | `() => Promise<{ keys: JWK[] }>` | Async
|
|
450
|
+
| `getJWKS` | `() => { keys: JWK[] }` | Synchronous - returns cached JWKS. Throws if not yet initialized. |
|
|
451
|
+
| `getJWKSAsync` | `() => Promise<{ keys: JWK[] }>` | Async - calls `ensureInitialized()` first, then returns JWKS. |
|
|
452
452
|
|
|
453
453
|
### Internal Methods
|
|
454
454
|
|
|
@@ -504,7 +504,7 @@ constructor(
|
|
|
504
504
|
protected options: IJWKSVerifierOptions,
|
|
505
505
|
) {
|
|
506
506
|
// Calls configurePayloadEncryption({ aesAlgorithm, applicationSecret })
|
|
507
|
-
// Remote JWKS is NOT fetched here
|
|
507
|
+
// Remote JWKS is NOT fetched here - fetched lazily via ensureInitialized()
|
|
508
508
|
}
|
|
509
509
|
```
|
|
510
510
|
|
|
@@ -520,13 +520,13 @@ The `initialize()` method:
|
|
|
520
520
|
| Method | Behavior |
|
|
521
521
|
|--------|----------|
|
|
522
522
|
| `doVerify(token)` | Calls `ensureInitialized()`, then `jwtVerify(token, this.jwksVerifier!)`, then `this.decryptPayload()` |
|
|
523
|
-
| `getSigner(opts)` | Throws
|
|
524
|
-
| `getSigningKey()` | Throws
|
|
525
|
-
| `getDefaultTokenExpiresFn()` | Throws
|
|
523
|
+
| `getSigner(opts)` | Throws - verifier mode cannot sign tokens |
|
|
524
|
+
| `getSigningKey()` | Throws - verifier mode cannot sign tokens |
|
|
525
|
+
| `getDefaultTokenExpiresFn()` | Throws - verifier mode has no token expiry |
|
|
526
526
|
|
|
527
527
|
## JWKSController
|
|
528
528
|
|
|
529
|
-
Serves the JWKS endpoint (default path `/certs`). This endpoint is **intentionally unauthenticated**
|
|
529
|
+
Serves the JWKS endpoint (default path `/certs`). This endpoint is **intentionally unauthenticated** - it serves the public keys needed by external verifiers.
|
|
530
530
|
|
|
531
531
|
**File:** `packages/core/src/components/auth/authenticate/controllers/jwks/controller.ts`
|
|
532
532
|
|
|
@@ -689,7 +689,7 @@ function defineAuthController(opts: TDefineAuthControllerOpts): typeof AuthContr
|
|
|
689
689
|
```
|
|
690
690
|
|
|
691
691
|
> [!NOTE]
|
|
692
|
-
> The factory also exports `JWTTokenPayloadSchema`, a Zod schema used for the `/who-am-i` response validation.
|
|
692
|
+
> The factory also exports `JWTTokenPayloadSchema`, a Zod schema used for the `/who-am-i` response validation. For `/who-am-i`, it is extended with an optional `userInformation` field that is populated when the request sets `?withUserInformation=true`. The same `getUserInformation` service method backs the dedicated `GET /me` route.
|
|
693
693
|
|
|
694
694
|
**Service resolution:**
|
|
695
695
|
|
|
@@ -49,7 +49,7 @@ Thrown during `binding()` when validating options and configuring services.
|
|
|
49
49
|
| `[defineJWSAuth] getTokenExpiresFn is required` | 400 | `defineJWSAuth` | `getTokenExpiresFn` not provided in JWS options |
|
|
50
50
|
|
|
51
51
|
::: info applicationSecret is no longer validated
|
|
52
|
-
`applicationSecret` was previously required and validated by the component. It is now **optional**
|
|
52
|
+
`applicationSecret` was previously required and validated by the component. It is now **optional** - omitting it simply disables AES payload encryption.
|
|
53
53
|
:::
|
|
54
54
|
|
|
55
55
|
#### `defineJWKSAuth` Errors (Issuer Mode)
|
|
@@ -104,10 +104,10 @@ Base class errors shared by `JWSTokenService`, `JWKSIssuerTokenService`, and `JW
|
|
|
104
104
|
| Error Message | Status | Method | When |
|
|
105
105
|
|---------------|--------|--------|------|
|
|
106
106
|
| `[verify] Invalid request token!` | 401 | `verify` | Token value is empty/falsy |
|
|
107
|
-
| `[verify] Invalid or expired token` | 401 | `verify` | `doVerify()` threw
|
|
107
|
+
| `[verify] Invalid or expired token` | 401 | `verify` | `doVerify()` threw - token is expired, malformed, or signature invalid |
|
|
108
108
|
|
|
109
109
|
::: tip Sanitized error messages
|
|
110
|
-
The `verify()` and `generate()` methods use **sanitized error messages**
|
|
110
|
+
The `verify()` and `generate()` methods use **sanitized error messages** - they do NOT include the original `error.message` in the thrown error. The full error is logged at `error` level for debugging but not exposed to clients.
|
|
111
111
|
:::
|
|
112
112
|
|
|
113
113
|
#### `generate` Errors
|
|
@@ -150,7 +150,7 @@ Errors thrown during lazy initialization (`ensureInitialized()`) and key operati
|
|
|
150
150
|
| <code v-pre>[JWKSIssuerTokenService] Unknown key format: {{format}}</code> | 500 | `parseKeyMaterial` | `keys.format` is not `'pem'` or `'jwk'` |
|
|
151
151
|
|
|
152
152
|
::: warning File read errors
|
|
153
|
-
When using `JWKSKeyDrivers.FILE`, file read errors from `readFile()` propagate as Node.js filesystem errors (e.g., `ENOENT`, `EACCES`). These are **not** wrapped
|
|
153
|
+
When using `JWKSKeyDrivers.FILE`, file read errors from `readFile()` propagate as Node.js filesystem errors (e.g., `ENOENT`, `EACCES`). These are **not** wrapped - the raw error surfaces during initialization.
|
|
154
154
|
:::
|
|
155
155
|
|
|
156
156
|
#### Runtime Errors
|
|
@@ -208,7 +208,7 @@ The middleware that executes strategies in the configured mode.
|
|
|
208
208
|
|
|
209
209
|
| Error Message | Status | Method | When |
|
|
210
210
|
|---------------|--------|--------|------|
|
|
211
|
-
| <code v-pre>Authentication failed. Tried strategies: {{strategies}}</code> | 401 | `executeAnyMode` | All strategies failed in `'any'` mode
|
|
211
|
+
| <code v-pre>Authentication failed. Tried strategies: {{strategies}}</code> | 401 | `executeAnyMode` | All strategies failed in `'any'` mode - each strategy threw during `authenticate()` |
|
|
212
212
|
| `Failed to identify authenticated user!` | 401 | `executeAllMode` | All strategies succeeded in `'all'` mode but the first strategy's `authUser.userId` is falsy |
|
|
213
213
|
| <code v-pre>Invalid authentication mode | mode: {{mode}}</code> | 500 | `createAuthenticateMiddleware` | `mode` is not `'any'` or `'all'` |
|
|
214
214
|
|
|
@@ -391,7 +391,7 @@ The built-in `JWKSController` already uses `getJWKSAsync()`, so this error only
|
|
|
391
391
|
|
|
392
392
|
**Cause:** `generate()` was called on a `JWKSVerifierTokenService`. The verifier mode only has access to public keys (via the remote JWKS URL) and cannot sign tokens.
|
|
393
393
|
|
|
394
|
-
**Fix:** Token generation should only happen on the **issuer** service. If you need both signing and verification in the same application, use `JWKSModes.ISSUER`
|
|
394
|
+
**Fix:** Token generation should only happen on the **issuer** service. If you need both signing and verification in the same application, use `JWKSModes.ISSUER` - the issuer can both sign and verify.
|
|
395
395
|
|
|
396
396
|
### "Authentication failed. Tried strategies: jwt, jwks"
|
|
397
397
|
|
|
@@ -471,7 +471,7 @@ this.bind<TBasicTokenServiceOptions>({ key: AuthenticateBindingKeys.BASIC_OPTION
|
|
|
471
471
|
|
|
472
472
|
### "[verify] Invalid or expired token"
|
|
473
473
|
|
|
474
|
-
**Cause:** Token verification failed. This is a sanitized error
|
|
474
|
+
**Cause:** Token verification failed. This is a sanitized error - the original error (expired, wrong signature, malformed) is logged internally but not exposed to clients.
|
|
475
475
|
|
|
476
476
|
**Fix:** Check the application logs for the full error. Common causes:
|
|
477
477
|
- Token has expired (check `exp` claim)
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
| **JWKSVerifierAuthenticationStrategy** | JWT verification via remote JWKS URL |
|
|
22
22
|
| **BasicAuthenticationStrategy** | Basic HTTP authentication using `BasicTokenService` |
|
|
23
23
|
| **AbstractBearerTokenService** | Base class for all Bearer token services (JWS, JWKS Issuer, JWKS Verifier) |
|
|
24
|
-
| **JWSTokenService** | Symmetric JWT
|
|
25
|
-
| **JWKSIssuerTokenService** | Asymmetric JWT
|
|
26
|
-
| **JWKSVerifierTokenService** | Asymmetric JWT
|
|
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 |
|
|
27
27
|
| **BasicTokenService** | Extract and verify Basic auth credentials |
|
|
28
28
|
| **JWKSController** | Serves `/.well-known/jwks.json`-style endpoint at `/certs` |
|
|
29
29
|
| **IAuthService** | Interface for custom auth implementation (sign-in, sign-up) |
|
|
@@ -97,8 +97,8 @@ The authentication module supports two JOSE (JSON Object Signing and Encryption)
|
|
|
97
97
|
| `JWKSKeyFormats` | `JWK` | `'jwk'` | JSON Web Key format |
|
|
98
98
|
|
|
99
99
|
Each constants class also provides:
|
|
100
|
-
- `SCHEME_SET: Set<string>`
|
|
101
|
-
- `isValid(input: string): boolean`
|
|
100
|
+
- `SCHEME_SET: Set<string>` - set of all valid values
|
|
101
|
+
- `isValid(input: string): boolean` - check if a value is recognized
|
|
102
102
|
|
|
103
103
|
#### Import Paths
|
|
104
104
|
|
|
@@ -244,7 +244,7 @@ this.bind<TJWTTokenServiceOptions>({ key: AuthenticateBindingKeys.JWT_OPTIONS })
|
|
|
244
244
|
standard: JOSEStandards.JWS,
|
|
245
245
|
options: {
|
|
246
246
|
jwtSecret: process.env.APP_ENV_JWT_SECRET,
|
|
247
|
-
applicationSecret: process.env.APP_ENV_APPLICATION_SECRET, // Optional
|
|
247
|
+
applicationSecret: process.env.APP_ENV_APPLICATION_SECRET, // Optional - enables AES payload encryption
|
|
248
248
|
getTokenExpiresFn: () => Number(process.env.APP_ENV_JWT_EXPIRES_IN || 86400),
|
|
249
249
|
},
|
|
250
250
|
});
|
|
@@ -495,7 +495,7 @@ type TJWTTokenServiceOptions =
|
|
|
495
495
|
| { standard: typeof JOSEStandards.JWKS; options: TJWKSTokenServiceOptions };
|
|
496
496
|
```
|
|
497
497
|
|
|
498
|
-
This enables clean TypeScript narrowing
|
|
498
|
+
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`.
|
|
499
499
|
|
|
500
500
|
### JWS Options (IJWSTokenServiceOptions)
|
|
501
501
|
|
|
@@ -759,16 +759,18 @@ interface IAuthService<
|
|
|
759
759
|
CPRS = AnyObject,
|
|
760
760
|
UIRQ = AnyObject,
|
|
761
761
|
UIRS = AnyObject,
|
|
762
|
+
RTRS = AnyObject,
|
|
762
763
|
> {
|
|
763
764
|
signIn(context: TContext<E>, opts: SIRQ): Promise<SIRS>;
|
|
764
765
|
signUp(context: TContext<E>, opts: SURQ): Promise<SURS>;
|
|
765
766
|
changePassword(context: TContext<E>, opts: CPRQ): Promise<CPRS>;
|
|
766
767
|
getUserInformation?(context: TContext<E>, opts: UIRQ): Promise<UIRS>;
|
|
768
|
+
refreshToken?(context: TContext<E>): Promise<RTRS>;
|
|
767
769
|
}
|
|
768
770
|
```
|
|
769
771
|
|
|
770
772
|
> [!NOTE]
|
|
771
|
-
> `IAuthService` is generic on the Hono `Env` type as well as all request/response types. The `getUserInformation` method is
|
|
773
|
+
> `IAuthService` is generic on the Hono `Env` type as well as all request/response types. The `getUserInformation` and `refreshToken` methods are both optional -- the auth controller factory returns a 501 (`core.not_supported`) when an endpoint that depends on one is called but the method is not implemented.
|
|
772
774
|
|
|
773
775
|
#### IJWTTokenPayload -- Full Interface
|
|
774
776
|
```typescript
|