@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.
Files changed (120) hide show
  1. package/README.md +125 -388
  2. package/dist/mcp-server/common/config.d.ts +0 -21
  3. package/dist/mcp-server/common/config.d.ts.map +1 -1
  4. package/dist/mcp-server/common/config.js +1 -36
  5. package/dist/mcp-server/common/config.js.map +1 -1
  6. package/dist/mcp-server/helpers/docs.helper.d.ts +0 -24
  7. package/dist/mcp-server/helpers/docs.helper.d.ts.map +1 -1
  8. package/dist/mcp-server/helpers/docs.helper.js +0 -25
  9. package/dist/mcp-server/helpers/docs.helper.js.map +1 -1
  10. package/dist/mcp-server/helpers/github.helper.d.ts +0 -13
  11. package/dist/mcp-server/helpers/github.helper.d.ts.map +1 -1
  12. package/dist/mcp-server/helpers/github.helper.js +3 -20
  13. package/dist/mcp-server/helpers/github.helper.js.map +1 -1
  14. package/dist/mcp-server/index.js +1 -20
  15. package/dist/mcp-server/index.js.map +1 -1
  16. package/dist/mcp-server/tools/base.tool.d.ts +4 -85
  17. package/dist/mcp-server/tools/base.tool.d.ts.map +1 -1
  18. package/dist/mcp-server/tools/base.tool.js +1 -38
  19. package/dist/mcp-server/tools/base.tool.js.map +1 -1
  20. package/dist/mcp-server/tools/docs/get-document-content.tool.d.ts +8 -2
  21. package/dist/mcp-server/tools/docs/get-document-content.tool.d.ts.map +1 -1
  22. package/dist/mcp-server/tools/docs/get-document-content.tool.js +1 -10
  23. package/dist/mcp-server/tools/docs/get-document-content.tool.js.map +1 -1
  24. package/dist/mcp-server/tools/docs/get-document-metadata.tool.d.ts +13 -2
  25. package/dist/mcp-server/tools/docs/get-document-metadata.tool.d.ts.map +1 -1
  26. package/dist/mcp-server/tools/docs/get-document-metadata.tool.js +1 -10
  27. package/dist/mcp-server/tools/docs/get-document-metadata.tool.js.map +1 -1
  28. package/dist/mcp-server/tools/docs/get-package-overview.tool.d.ts +16 -8
  29. package/dist/mcp-server/tools/docs/get-package-overview.tool.d.ts.map +1 -1
  30. package/dist/mcp-server/tools/docs/get-package-overview.tool.js +2 -25
  31. package/dist/mcp-server/tools/docs/get-package-overview.tool.js.map +1 -1
  32. package/dist/mcp-server/tools/docs/list-categories.tool.d.ts +5 -2
  33. package/dist/mcp-server/tools/docs/list-categories.tool.d.ts.map +1 -1
  34. package/dist/mcp-server/tools/docs/list-categories.tool.js +1 -10
  35. package/dist/mcp-server/tools/docs/list-categories.tool.js.map +1 -1
  36. package/dist/mcp-server/tools/docs/list-documents.tool.d.ts +11 -2
  37. package/dist/mcp-server/tools/docs/list-documents.tool.d.ts.map +1 -1
  38. package/dist/mcp-server/tools/docs/list-documents.tool.js +1 -10
  39. package/dist/mcp-server/tools/docs/list-documents.tool.js.map +1 -1
  40. package/dist/mcp-server/tools/docs/search-documents.tool.d.ts +13 -2
  41. package/dist/mcp-server/tools/docs/search-documents.tool.d.ts.map +1 -1
  42. package/dist/mcp-server/tools/docs/search-documents.tool.js +1 -10
  43. package/dist/mcp-server/tools/docs/search-documents.tool.js.map +1 -1
  44. package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +9 -2
  45. package/dist/mcp-server/tools/github/list-project-files.tool.d.ts.map +1 -1
  46. package/dist/mcp-server/tools/github/list-project-files.tool.js +1 -10
  47. package/dist/mcp-server/tools/github/list-project-files.tool.js.map +1 -1
  48. package/dist/mcp-server/tools/github/search-code.tool.d.ts +16 -2
  49. package/dist/mcp-server/tools/github/search-code.tool.d.ts.map +1 -1
  50. package/dist/mcp-server/tools/github/search-code.tool.js +2 -14
  51. package/dist/mcp-server/tools/github/search-code.tool.js.map +1 -1
  52. package/dist/mcp-server/tools/github/verify-dependencies.tool.d.ts +19 -6
  53. package/dist/mcp-server/tools/github/verify-dependencies.tool.d.ts.map +1 -1
  54. package/dist/mcp-server/tools/github/verify-dependencies.tool.js +2 -19
  55. package/dist/mcp-server/tools/github/verify-dependencies.tool.js.map +1 -1
  56. package/dist/mcp-server/tools/github/view-source-file.tool.d.ts +8 -2
  57. package/dist/mcp-server/tools/github/view-source-file.tool.d.ts.map +1 -1
  58. package/dist/mcp-server/tools/github/view-source-file.tool.js +1 -10
  59. package/dist/mcp-server/tools/github/view-source-file.tool.js.map +1 -1
  60. package/dist/mcp-server/tools/index.d.ts.map +1 -1
  61. package/dist/mcp-server/tools/index.js +0 -2
  62. package/dist/mcp-server/tools/index.js.map +1 -1
  63. package/package.json +68 -54
  64. package/wiki/best-practices/api-usage-examples.md +7 -5
  65. package/wiki/best-practices/code-style-standards/advanced-patterns.md +1 -1
  66. package/wiki/best-practices/code-style-standards/constants-configuration.md +1 -1
  67. package/wiki/best-practices/code-style-standards/control-flow.md +1 -1
  68. package/wiki/best-practices/code-style-standards/function-patterns.md +1 -1
  69. package/wiki/best-practices/common-pitfalls.md +1 -1
  70. package/wiki/best-practices/data-modeling.md +33 -1
  71. package/wiki/best-practices/error-handling.md +7 -4
  72. package/wiki/best-practices/performance-optimization.md +1 -1
  73. package/wiki/best-practices/security-guidelines.md +5 -4
  74. package/wiki/guides/core-concepts/components-guide.md +1 -1
  75. package/wiki/guides/core-concepts/controllers.md +14 -8
  76. package/wiki/guides/core-concepts/persistent/models.md +32 -0
  77. package/wiki/guides/core-concepts/services.md +2 -1
  78. package/wiki/guides/get-started/5-minute-quickstart.md +1 -1
  79. package/wiki/guides/reference/mcp-docs-server.md +0 -134
  80. package/wiki/guides/tutorials/building-a-crud-api.md +2 -1
  81. package/wiki/guides/tutorials/complete-installation.md +2 -2
  82. package/wiki/guides/tutorials/ecommerce-api.md +3 -3
  83. package/wiki/guides/tutorials/realtime-chat.md +7 -6
  84. package/wiki/index.md +2 -1
  85. package/wiki/references/base/components.md +2 -1
  86. package/wiki/references/base/controllers.md +19 -12
  87. package/wiki/references/base/middlewares.md +2 -1
  88. package/wiki/references/base/models.md +11 -2
  89. package/wiki/references/base/services.md +2 -1
  90. package/wiki/references/components/authentication/api.md +525 -205
  91. package/wiki/references/components/authentication/errors.md +502 -105
  92. package/wiki/references/components/authentication/index.md +388 -75
  93. package/wiki/references/components/authentication/usage.md +428 -266
  94. package/wiki/references/components/authorization/api.md +1213 -0
  95. package/wiki/references/components/authorization/errors.md +387 -0
  96. package/wiki/references/components/authorization/index.md +712 -0
  97. package/wiki/references/components/authorization/usage.md +758 -0
  98. package/wiki/references/components/health-check.md +2 -1
  99. package/wiki/references/components/index.md +2 -0
  100. package/wiki/references/components/socket-io/index.md +9 -4
  101. package/wiki/references/components/socket-io/usage.md +1 -1
  102. package/wiki/references/components/static-asset/index.md +3 -5
  103. package/wiki/references/components/swagger.md +2 -1
  104. package/wiki/references/configuration/environment-variables.md +2 -1
  105. package/wiki/references/configuration/index.md +2 -1
  106. package/wiki/references/helpers/error/index.md +1 -1
  107. package/wiki/references/helpers/index.md +1 -0
  108. package/wiki/references/helpers/inversion/index.md +1 -1
  109. package/wiki/references/helpers/kafka/index.md +305 -0
  110. package/wiki/references/helpers/redis/index.md +2 -9
  111. package/wiki/references/quick-reference.md +3 -5
  112. package/wiki/references/utilities/crypto.md +2 -2
  113. package/wiki/references/utilities/date.md +5 -5
  114. package/wiki/references/utilities/index.md +3 -11
  115. package/wiki/references/utilities/jsx.md +4 -2
  116. package/wiki/references/utilities/module.md +1 -1
  117. package/wiki/references/utilities/parse.md +4 -4
  118. package/wiki/references/utilities/performance.md +2 -2
  119. package/wiki/references/utilities/promise.md +4 -4
  120. package/wiki/references/utilities/request.md +2 -2
@@ -2,173 +2,570 @@
2
2
 
3
3
  > Complete error messages and troubleshooting for the authentication module. See [Setup & Configuration](./) for initial setup.
4
4
 
5
+ ## Error Flow Overview
6
+
7
+ ```mermaid
8
+ flowchart LR
9
+ REQ["Incoming Request"] --> MW["Auth Middleware"]
10
+ MW --> SKIP{"Skip auth?"}
11
+ SKIP -->|"Yes"| PASS["Pass through"]
12
+ SKIP -->|"No"| EXTRACT["Extract credentials"]
13
+ EXTRACT -->|"Missing header"| E401A["401 Missing header"]
14
+ EXTRACT -->|"Wrong scheme"| E401B["401 Invalid scheme"]
15
+ EXTRACT -->|"Bad format"| E401C["401 Invalid format"]
16
+ EXTRACT -->|"OK"| VERIFY["Verify token"]
17
+ VERIFY -->|"Expired/invalid"| E401D["401 Invalid token"]
18
+ VERIFY -->|"Valid"| USER["Set CURRENT_USER"]
19
+ USER --> NEXT["Next middleware"]
20
+
21
+ style E401A fill:#f8d7da,stroke:#dc3545
22
+ style E401B fill:#f8d7da,stroke:#dc3545
23
+ style E401C fill:#f8d7da,stroke:#dc3545
24
+ style E401D fill:#f8d7da,stroke:#dc3545
25
+ style PASS fill:#d4edda,stroke:#28a745
26
+ style NEXT fill:#d4edda,stroke:#28a745
27
+ ```
28
+
5
29
  ## Complete Error Reference
6
30
 
7
- All error messages from the authentication module, organized by source:
8
-
9
- ### Component Errors (AuthenticateComponent)
10
-
11
- | Error Message | Status | Method |
12
- |---------------|--------|--------|
13
- | `[AuthenticateComponent] At least one of jwtOptions or basicOptions must be provided` | 500 | `validateOptions` |
14
- | <code v-pre>[defineJWTAuth] Invalid jwtSecret &#124; Provided: {{jwtSecret}}</code> | 500 | `defineJWTAuth` |
15
- | <code v-pre>[defineJWTAuth] Invalid applicationSecret &#124; Provided: {{applicationSecret}}</code> | 500 | `defineJWTAuth` |
16
- | `[defineJWTAuth] getTokenExpiresFn is required` | 500 | `defineJWTAuth` |
17
- | `[defineBasicAuth] verifyCredentials function is required` | 500 | `defineBasicAuth` |
18
- | `[defineControllers] Auth controller requires jwtOptions to be configured` | 500 | `defineControllers` |
19
-
20
- ### JWTTokenService Errors
21
-
22
- | Error Message | Status | Method |
23
- |---------------|--------|--------|
24
- | `[JWTTokenService] Invalid jwtSecret` | 500 | `constructor` |
25
- | `[JWTTokenService] Invalid applicationSecret` | 500 | `constructor` |
26
- | `[JWTTokenService] Invalid getTokenExpiresFn` | 500 | `constructor` |
27
- | `Unauthorized user! Missing authorization header` | 401 | `extractCredentials` |
28
- | `Unauthorized user! Invalid schema of request token!` | 401 | `extractCredentials` |
29
- | <code v-pre>Authorization header value is invalid format. It must follow the pattern: 'Bearer xx.yy.zz' where xx.yy.zz is a valid JWT token.</code> | 401 | `extractCredentials` |
30
- | `[verify] Invalid request token!` | 401 | `verify` |
31
- | <code v-pre>[verify] Failed to verify token &#124; Message: {{error.message}}</code> | 401 | `verify` |
32
- | `[generate] Invalid token payload!` | 401 | `generate` |
33
- | <code v-pre>[generate] Failed to generate token &#124; Error: {{error.message}}</code> | 500 | `generate` |
34
-
35
- ### BasicTokenService Errors
36
-
37
- | Error Message | Status | Method |
38
- |---------------|--------|--------|
39
- | `[BasicTokenService] Invalid verifyCredentials function` | 500 | `constructor` |
40
- | `Unauthorized! Missing authorization header` | 401 | `extractCredentials` |
41
- | `Unauthorized! Invalid authorization schema, expected Basic` | 401 | `extractCredentials` |
42
- | `Unauthorized! Invalid authorization header format` | 401 | `extractCredentials` |
43
- | `Unauthorized! Invalid base64 credentials format` | 401 | `extractCredentials` |
44
- | `Unauthorized! Invalid username or password` | 401 | `verify` |
45
-
46
- ### Strategy Registry Errors
47
-
48
- | Error Message | Status | Method |
49
- |---------------|--------|--------|
50
- | <code v-pre>[getStrategyKey] Invalid strategy name &#124; name: {{name}}</code> | 500 | `getStrategyKey` |
51
- | <code v-pre>[executeStrategy] Strategy not found: {{strategyName}}</code> | 500 | `executeStrategy` |
52
- | <code v-pre>[executeStrategy] strategy: {{strategyName}} &#124; Authentication Strategy NOT FOUND</code> | 500 | `executeStrategy` |
53
- | <code v-pre>Authentication failed. Tried strategies: {{strategies}}</code> | 401 | `authenticate` (any mode) |
54
- | `Failed to identify authenticated user!` | 401 | `authenticate` (all mode) |
55
- | <code v-pre>Invalid authentication mode &#124; mode: {{mode}}</code> | 500 | `authenticate` (default) |
56
-
57
- ### Controller Factory Errors
58
-
59
- | Error Message | Status | Method |
60
- |---------------|--------|--------|
61
- | `[AuthController] Failed to init auth controller | Invalid injectable authentication service!` | 500 | `constructor` |
31
+ All error messages from the authentication module, organized by source.
32
+
33
+ ---
34
+
35
+ ### Component Errors (`AuthenticateComponent`)
36
+
37
+ Thrown during `binding()` when validating options and configuring services.
38
+
39
+ | Error Message | Status | Method | When |
40
+ |---------------|--------|--------|------|
41
+ | `[AuthenticateComponent] At least one of jwtOptions or basicOptions must be provided` | 400 | `binding` | Neither `JWT_OPTIONS` nor `BASIC_OPTIONS` bound in DI container |
42
+ | <code v-pre>[AuthenticateComponent] Unknown JOSE standard: {{standard}}</code> | 400 | `binding` | `jwtOptions.standard` is not `'JWS'` or `'JWKS'` |
43
+
44
+ #### `defineJWSAuth` Errors
45
+
46
+ | Error Message | Status | Method | When |
47
+ |---------------|--------|--------|------|
48
+ | <code v-pre>[defineJWSAuth] Invalid jwtSecret &#124; Provided: {{jwtSecret}}</code> | 400 | `defineJWSAuth` | `jwtSecret` is falsy or equals `'unknown_secret'` |
49
+ | `[defineJWSAuth] getTokenExpiresFn is required` | 400 | `defineJWSAuth` | `getTokenExpiresFn` not provided in JWS options |
50
+
51
+ ::: info applicationSecret is no longer validated
52
+ `applicationSecret` was previously required and validated by the component. It is now **optional** — omitting it simply disables AES payload encryption.
53
+ :::
54
+
55
+ #### `defineJWKSAuth` Errors (Issuer Mode)
56
+
57
+ | Error Message | Status | Method | When |
58
+ |---------------|--------|--------|------|
59
+ | `[defineJWKSAuth] keys.private and keys.public are required for issuer mode` | 400 | `defineJWKSAuth` | `keys.private` or `keys.public` missing |
60
+ | <code v-pre>[defineJWKSAuth] keys.format is required and must be one of: pem, jwk</code> | 400 | `defineJWKSAuth` | `keys.format` missing or not in `JWKSKeyFormats.SCHEME_SET` |
61
+ | `[defineJWKSAuth] kid is required for issuer mode` | 400 | `defineJWKSAuth` | `kid` (Key ID) not provided |
62
+ | `[defineJWKSAuth] getTokenExpiresFn is required for issuer mode` | 400 | `defineJWKSAuth` | `getTokenExpiresFn` not provided |
63
+
64
+ #### `defineJWKSAuth` Errors (Verifier Mode)
65
+
66
+ | Error Message | Status | Method | When |
67
+ |---------------|--------|--------|------|
68
+ | `[defineJWKSAuth] jwksUrl is required for verifier mode` | 400 | `defineJWKSAuth` | `jwksUrl` not provided for verifier mode |
69
+
70
+ #### `defineJWKSAuth` Errors (General)
71
+
72
+ | Error Message | Status | Method | When |
73
+ |---------------|--------|--------|------|
74
+ | <code v-pre>[defineJWKSAuth] Invalid JWKS mode: {{mode}}</code> | 400 | `defineJWKSAuth` | `mode` is not `'issuer'` or `'verifier'` |
75
+
76
+ #### `defineBasicAuth` Errors
77
+
78
+ | Error Message | Status | Method | When |
79
+ |---------------|--------|--------|------|
80
+ | `[defineBasicAuth] verifyCredentials function is required` | 400 | `defineBasicAuth` | `BASIC_OPTIONS` bound without a `verifyCredentials` callback |
81
+
82
+ #### `defineControllers` Errors
83
+
84
+ | Error Message | Status | Method | When |
85
+ |---------------|--------|--------|------|
86
+ | `[defineControllers] Auth controller requires jwtOptions to be configured` | 400 | `defineControllers` | `useAuthController: true` but no `jwtOptions` provided |
87
+
88
+ ---
89
+
90
+ ### Bearer Token Service Errors (`AbstractBearerTokenService`)
91
+
92
+ Base class errors shared by `JWSTokenService`, `JWKSIssuerTokenService`, and `JWKSVerifierTokenService`.
93
+
94
+ #### `extractCredentials` Errors
95
+
96
+ | Error Message | Status | Method | When |
97
+ |---------------|--------|--------|------|
98
+ | `Unauthorized user! Missing authorization header` | 401 | `extractCredentials` | Request has no `Authorization` header |
99
+ | `Unauthorized user! Invalid schema of request token!` | 401 | `extractCredentials` | `Authorization` header doesn't start with `Bearer` |
100
+ | <code v-pre>Authorization header value is invalid format. It must follow the pattern: 'Bearer xx.yy.zz' where xx.yy.zz is a valid JWT token.</code> | 401 | `extractCredentials` | `Authorization` header doesn't have exactly 2 parts (type + token) |
101
+
102
+ #### `verify` Errors
103
+
104
+ | Error Message | Status | Method | When |
105
+ |---------------|--------|--------|------|
106
+ | `[verify] Invalid request token!` | 401 | `verify` | Token value is empty/falsy |
107
+ | `[verify] Invalid or expired token` | 401 | `verify` | `doVerify()` threw — token is expired, malformed, or signature invalid |
108
+
109
+ ::: tip 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
+ :::
112
+
113
+ #### `generate` Errors
114
+
115
+ | Error Message | Status | Method | When |
116
+ |---------------|--------|--------|------|
117
+ | `[generate] Invalid token payload!` | 401 | `generate` | Payload is null/undefined |
118
+ | `[generate] Failed to generate token` | 500 | `generate` | Signing failed (key issue, algorithm mismatch, etc.) |
119
+
120
+ ---
121
+
122
+ ### JWS Token Service Errors (`JWSTokenService`)
123
+
124
+ Constructor validation errors thrown during DI resolution.
125
+
126
+ | Error Message | Status | Method | When |
127
+ |---------------|--------|--------|------|
128
+ | `[JWSTokenService] Invalid jwtSecret` | 500 | `constructor` | `jwtSecret` is falsy in injected `IJWSTokenServiceOptions` |
129
+ | `[JWSTokenService] Invalid getTokenExpiresFn` | 500 | `constructor` | `getTokenExpiresFn` is falsy in injected options |
130
+ | `[getSigningKey] Invalid jwtSecret!` | 400 | `getSigningKey` | `jwtSecret` Uint8Array is null (should not happen after constructor validation) |
131
+
132
+ ::: info applicationSecret no longer validated
133
+ `JWSTokenService` no longer validates `applicationSecret` in its constructor. If not provided, AES payload encryption is simply disabled.
134
+ :::
135
+
136
+ ---
137
+
138
+ ### JWKS Issuer Token Service Errors (`JWKSIssuerTokenService`)
139
+
140
+ Errors thrown during lazy initialization (`ensureInitialized()`) and key operations.
141
+
142
+ #### Initialization Errors
143
+
144
+ | Error Message | Status | Method | When |
145
+ |---------------|--------|--------|------|
146
+ | <code v-pre>[JWKSIssuerTokenService] Unknown key driver: {{driver}}</code> | 500 | `resolveKeyContent` | `keys.driver` is not `'text'` or `'file'` |
147
+ | `[JWKSIssuerTokenService] Invalid raw.priv key!` | 500 | `parseKeyMaterial` | Resolved private key content is empty |
148
+ | `[JWKSIssuerTokenService] Invalid raw.pub key!` | 500 | `parseKeyMaterial` | Resolved public key content is empty |
149
+ | `[JWKSIssuerTokenService] Invalid JWK key material` | 500 | `parseKeyMaterial` | JWK JSON parsing or `importJWK()` failed (PEM format works, JWK content is invalid) |
150
+ | <code v-pre>[JWKSIssuerTokenService] Unknown key format: {{format}}</code> | 500 | `parseKeyMaterial` | `keys.format` is not `'pem'` or `'jwk'` |
151
+
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 — the raw error surfaces during initialization.
154
+ :::
155
+
156
+ #### Runtime Errors
157
+
158
+ | Error Message | Status | Method | When |
159
+ |---------------|--------|--------|------|
160
+ | `[getSigningKey] Invalid privateKey!` | 400 | `getSigningKey` | Private key is null (initialization incomplete or failed) |
161
+ | `[JWKSIssuerTokenService] JWKS not initialized yet. Call getJWKSAsync() instead.` | 500 | `getJWKS` | Sync `getJWKS()` called before lazy init completed |
162
+
163
+ ---
164
+
165
+ ### JWKS Verifier Token Service Errors (`JWKSVerifierTokenService`)
166
+
167
+ | Error Message | Status | Method | When |
168
+ |---------------|--------|--------|------|
169
+ | `[JWKSVerifierTokenService] Verifier mode cannot sign tokens` | 500 | `getSigner` | Attempt to call `generate()` on a verify-only service |
170
+ | `[JWKSVerifierTokenService] Verifier mode cannot sign tokens` | 500 | `getSigningKey` | Attempt to access signing key on a verify-only service |
171
+ | `[JWKSVerifierTokenService] Verifier mode has no token expiry` | 500 | `getDefaultTokenExpiresFn` | Attempt to access token expiry on a verify-only service |
172
+
173
+ ::: tip Verifier mode is read-only
174
+ `JWKSVerifierTokenService` **cannot** generate tokens. Calling `generate()` throws because both `getSigner()` and `getSigningKey()` throw. Only `verify()` and `extractCredentials()` are functional.
175
+ :::
176
+
177
+ ---
178
+
179
+ ### Basic Token Service Errors (`BasicTokenService`)
180
+
181
+ | Error Message | Status | Method | When |
182
+ |---------------|--------|--------|------|
183
+ | `[BasicTokenService] Invalid verifyCredentials function` | 500 | `constructor` | `verifyCredentials` not provided in injected `TBasicTokenServiceOptions` |
184
+ | `Unauthorized! Missing authorization header` | 401 | `extractCredentials` | Request has no `Authorization` header |
185
+ | `Unauthorized! Invalid authorization schema, expected Basic` | 401 | `extractCredentials` | `Authorization` header doesn't start with `Basic` |
186
+ | `Unauthorized! Invalid authorization header format` | 401 | `extractCredentials` | Header doesn't have exactly 2 parts (`Basic` + base64 value) |
187
+ | `Unauthorized! Invalid base64 credentials format` | 401 | `extractCredentials` | Base64 decoding failed, no colon separator, or empty username |
188
+ | `Unauthorized! Invalid username or password` | 401 | `verify` | `verifyCredentials` callback returned null/falsy |
189
+
190
+ ---
191
+
192
+ ### Strategy Registry Errors (`AuthenticationStrategyRegistry`)
193
+
194
+ Inherited from `AbstractAuthRegistry`.
195
+
196
+ | Error Message | Status | Method | When |
197
+ |---------------|--------|--------|------|
198
+ | <code v-pre>[getKey] Invalid name &#124; name: {{name}}</code> | 400 | `getKey` | Strategy name is empty or falsy |
199
+ | <code v-pre>[AuthenticationStrategyRegistry] No items registered</code> | 400 | `getDefaultName` | No strategies have been registered |
200
+ | <code v-pre>[AuthenticationStrategyRegistry] Descriptor not found: {{name}}</code> | 400 | `resolveDescriptor` | Strategy with given name is not registered |
201
+ | <code v-pre>[AuthenticationStrategyRegistry] Failed to resolve: {{name}}</code> | 400 | `resolveDescriptor` | Strategy registered but DI container returned null |
202
+
203
+ ---
204
+
205
+ ### Authentication Provider Errors (`AuthenticationProvider`)
206
+
207
+ The middleware that executes strategies in the configured mode.
208
+
209
+ | Error Message | Status | Method | When |
210
+ |---------------|--------|--------|------|
211
+ | <code v-pre>Authentication failed. Tried strategies: {{strategies}}</code> | 401 | `executeAnyMode` | All strategies failed in `'any'` mode — each strategy threw during `authenticate()` |
212
+ | `Failed to identify authenticated user!` | 401 | `executeAllMode` | All strategies succeeded in `'all'` mode but the final `authUser.userId` is falsy |
213
+ | <code v-pre>Invalid authentication mode &#124; mode: {{mode}}</code> | 500 | `createAuthenticateMiddleware` | `mode` is not `'any'` or `'all'` |
214
+
215
+ ---
216
+
217
+ ### Auth Controller Factory Errors
218
+
219
+ | Error Message | Status | Method | When |
220
+ |---------------|--------|--------|------|
221
+ | `[AuthController] Failed to init auth controller \| Invalid injectable authentication service!` | 400 | `constructor` | DI could not resolve the authentication service (service key not bound) |
222
+
223
+ ---
62
224
 
63
225
  ## Troubleshooting
64
226
 
65
227
  ### "[AuthenticateComponent] At least one of jwtOptions or basicOptions must be provided"
66
228
 
67
- **Cause:** The `AuthenticateComponent` requires at least one authentication method to be configured. Neither `JWT_OPTIONS` nor `BASIC_OPTIONS` was bound in the DI container.
229
+ **Cause:** The component requires at least one authentication method. Neither `JWT_OPTIONS` nor `BASIC_OPTIONS` was bound before calling `this.component(AuthenticateComponent)`.
68
230
 
69
231
  **Fix:** Bind at least one set of options before registering the component:
70
232
 
71
233
  ```typescript
72
- this.bind<IJWTTokenServiceOptions>({ key: AuthenticateBindingKeys.JWT_OPTIONS }).toValue({
73
- applicationSecret: process.env.APP_ENV_APPLICATION_SECRET,
74
- jwtSecret: process.env.APP_ENV_JWT_SECRET,
75
- getTokenExpiresFn: () => Number(process.env.APP_ENV_JWT_EXPIRES_IN || 86400),
234
+ // Option A: JWS (symmetric JWT)
235
+ this.bind<TJWTTokenServiceOptions>({ key: AuthenticateBindingKeys.JWT_OPTIONS }).toValue({
236
+ standard: JOSEStandards.JWS,
237
+ options: {
238
+ jwtSecret: env.get('JWT_SECRET'),
239
+ getTokenExpiresFn: () => 86_400,
240
+ },
241
+ });
242
+
243
+ // Option B: JWKS Issuer (asymmetric JWT)
244
+ this.bind<TJWTTokenServiceOptions>({ key: AuthenticateBindingKeys.JWT_OPTIONS }).toValue({
245
+ standard: JOSEStandards.JWKS,
246
+ options: {
247
+ mode: JWKSModes.ISSUER,
248
+ algorithm: 'RS256',
249
+ kid: 'my-key-1',
250
+ keys: { driver: JWKSKeyDrivers.FILE, format: JWKSKeyFormats.PEM, private: './keys/private.pem', public: './keys/public.pem' },
251
+ getTokenExpiresFn: () => 86_400,
252
+ },
76
253
  });
254
+
255
+ // Then register the component
256
+ this.component(AuthenticateComponent);
77
257
  ```
78
258
 
79
- ### "[defineJWTAuth] Invalid jwtSecret" / "[defineJWTAuth] Invalid applicationSecret"
259
+ ### "[defineJWSAuth] Invalid jwtSecret"
80
260
 
81
- **Cause:** The JWT secret or application secret is missing, empty, or set to the default placeholder `'unknown_secret'`. The component's `defineJWTAuth()` method validates these values during binding. The error message includes the actual provided value (e.g., <code v-pre>[defineJWTAuth] Invalid jwtSecret | Provided: {{jwtSecret}}</code>).
261
+ **Cause:** `jwtSecret` is missing, empty, or set to the default placeholder `'unknown_secret'`. The component validates this during `defineJWSAuth()`.
82
262
 
83
- **Fix:** Set strong, unique values for both secrets in your environment variables:
263
+ **Fix:** Set a strong, unique JWT secret:
84
264
 
265
+ ```bash
266
+ # .env
267
+ JWT_SECRET=your-strong-jwt-secret-at-least-32-chars
85
268
  ```
86
- APP_ENV_APPLICATION_SECRET=your-strong-application-secret
87
- APP_ENV_JWT_SECRET=your-strong-jwt-secret
269
+
270
+ ```typescript
271
+ this.bind<TJWTTokenServiceOptions>({ key: AuthenticateBindingKeys.JWT_OPTIONS }).toValue({
272
+ standard: JOSEStandards.JWS,
273
+ options: {
274
+ jwtSecret: env.get('JWT_SECRET'),
275
+ getTokenExpiresFn: () => 86_400,
276
+ },
277
+ });
88
278
  ```
89
279
 
90
- ### "[defineJWTAuth] getTokenExpiresFn is required"
280
+ ### "[defineJWSAuth] getTokenExpiresFn is required"
91
281
 
92
- **Cause:** The `getTokenExpiresFn` function was not provided in the JWT options.
282
+ **Cause:** `getTokenExpiresFn` was not provided in the JWS options.
93
283
 
94
- **Fix:** Include a `getTokenExpiresFn` in your JWT options binding:
284
+ **Fix:** Include a function that returns the token expiry time in seconds:
95
285
 
96
286
  ```typescript
97
- this.bind<IJWTTokenServiceOptions>({ key: AuthenticateBindingKeys.JWT_OPTIONS }).toValue({
98
- applicationSecret: process.env.APP_ENV_APPLICATION_SECRET,
99
- jwtSecret: process.env.APP_ENV_JWT_SECRET,
100
- getTokenExpiresFn: () => Number(process.env.APP_ENV_JWT_EXPIRES_IN || 86400),
101
- });
287
+ options: {
288
+ jwtSecret: env.get('JWT_SECRET'),
289
+ getTokenExpiresFn: () => Number(env.get('JWT_EXPIRES_IN') || 86_400),
290
+ }
102
291
  ```
103
292
 
104
- ### "[defineBasicAuth] verifyCredentials function is required"
293
+ ### "[defineJWKSAuth] keys.private and keys.public are required for issuer mode"
105
294
 
106
- **Cause:** `BASIC_OPTIONS` was bound but without a `verifyCredentials` callback function.
295
+ **Cause:** JWKS issuer mode requires both a private key (for signing) and a public key (for the `/certs` JWKS endpoint). One or both were not provided.
107
296
 
108
- **Fix:** Provide a `verifyCredentials` function in the Basic options:
297
+ **Fix:** Provide both keys in the options:
109
298
 
110
299
  ```typescript
111
- this.bind<IBasicTokenServiceOptions>({ key: AuthenticateBindingKeys.BASIC_OPTIONS }).toValue({
112
- verifyCredentials: async (opts) => {
113
- // Your credential verification logic
114
- return { userId: user.id };
300
+ options: {
301
+ mode: JWKSModes.ISSUER,
302
+ algorithm: 'RS256',
303
+ kid: 'my-key-1',
304
+ keys: {
305
+ driver: JWKSKeyDrivers.FILE,
306
+ format: JWKSKeyFormats.PEM,
307
+ private: './keys/private.pem',
308
+ public: './keys/public.pem',
115
309
  },
116
- });
310
+ getTokenExpiresFn: () => 86_400,
311
+ }
117
312
  ```
118
313
 
119
- ### "[defineControllers] Auth controller requires jwtOptions to be configured"
314
+ ### "[defineJWKSAuth] keys.format is required and must be one of: pem, jwk"
120
315
 
121
- **Cause:** The built-in auth controller (`useAuthController: true`) was enabled without binding JWT options. The auth controller requires JWT for token generation.
316
+ **Cause:** `keys.format` is missing or invalid. The component validates against `JWKSKeyFormats.SCHEME_SET` (values are lowercase: `'pem'`, `'jwk'`).
122
317
 
123
- **Fix:** Always bind `JWT_OPTIONS` when using the auth controller:
318
+ **Fix:** Use one of the supported formats:
124
319
 
125
320
  ```typescript
126
- this.bind<TAuthenticationRestOptions>({ key: AuthenticateBindingKeys.REST_OPTIONS }).toValue({
127
- useAuthController: true,
128
- controllerOpts: { restPath: '/auth' },
129
- });
321
+ keys: {
322
+ driver: JWKSKeyDrivers.FILE,
323
+ format: JWKSKeyFormats.PEM, // or JWKSKeyFormats.JWK
324
+ private: './keys/private.pem',
325
+ public: './keys/public.pem',
326
+ }
327
+ ```
328
+
329
+ ### "[defineJWKSAuth] kid is required for issuer mode"
330
+
331
+ **Cause:** The Key ID (`kid`) is required for the issuer to include in the JWKS and JWT headers. It allows verifiers to identify which key was used to sign a token.
130
332
 
131
- // This is required when useAuthController is true
132
- this.bind<IJWTTokenServiceOptions>({ key: AuthenticateBindingKeys.JWT_OPTIONS }).toValue({
133
- applicationSecret: process.env.APP_ENV_APPLICATION_SECRET,
134
- jwtSecret: process.env.APP_ENV_JWT_SECRET,
135
- getTokenExpiresFn: () => Number(process.env.APP_ENV_JWT_EXPIRES_IN || 86400),
333
+ **Fix:** Provide a unique key identifier:
334
+
335
+ ```typescript
336
+ options: {
337
+ mode: JWKSModes.ISSUER,
338
+ kid: 'my-service-key-2024',
339
+ // ...
340
+ }
341
+ ```
342
+
343
+ ### "[defineJWKSAuth] jwksUrl is required for verifier mode"
344
+
345
+ **Cause:** JWKS verifier mode needs the URL of the issuer's `/certs` endpoint to fetch the public key set.
346
+
347
+ **Fix:** Provide the JWKS endpoint URL:
348
+
349
+ ```typescript
350
+ this.bind<TJWTTokenServiceOptions>({ key: AuthenticateBindingKeys.JWT_OPTIONS }).toValue({
351
+ standard: JOSEStandards.JWKS,
352
+ options: {
353
+ mode: JWKSModes.VERIFIER,
354
+ jwksUrl: 'https://auth-service.example.com/certs',
355
+ },
136
356
  });
137
357
  ```
138
358
 
139
- ### "Authentication failed. Tried strategies: jwt, basic"
359
+ ### "[JWKSIssuerTokenService] Invalid JWK key material"
140
360
 
141
- **Cause:** All configured strategies failed to authenticate the request. In `'any'` mode, every strategy is tried in order; if none succeeds, this error is thrown with a `401 Unauthorized` status.
361
+ **Cause:** When using `JWKSKeyFormats.JWK`, the private or public key content failed to parse as valid JSON, or `importJWK()` rejected it. The full error is logged at `error` level.
362
+
363
+ **Fix:** Ensure your JWK keys are valid JSON objects:
364
+
365
+ ```json
366
+ {
367
+ "kty": "RSA",
368
+ "n": "...",
369
+ "e": "AQAB",
370
+ "d": "...",
371
+ "alg": "RS256",
372
+ "use": "sig"
373
+ }
374
+ ```
375
+
376
+ If stored as files, ensure the file contains valid JSON (not PEM). If stored as text (`JWKSKeyDrivers.TEXT`), ensure the string is parseable JSON.
377
+
378
+ ### "[JWKSIssuerTokenService] JWKS not initialized yet. Call getJWKSAsync() instead."
379
+
380
+ **Cause:** `getJWKS()` (synchronous) was called before the lazy initialization completed. The issuer loads keys asynchronously on first use.
381
+
382
+ **Fix:** Use the async variant:
383
+
384
+ ```typescript
385
+ const jwks = await issuerService.getJWKSAsync();
386
+ ```
387
+
388
+ The built-in `JWKSController` already uses `getJWKSAsync()`, so this error only occurs if you call `getJWKS()` directly in custom code.
389
+
390
+ ### "[JWKSVerifierTokenService] Verifier mode cannot sign tokens"
391
+
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
+
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
+
396
+ ### "Authentication failed. Tried strategies: jwt, jwks"
397
+
398
+ **Cause:** All configured strategies failed in `'any'` mode. Each strategy attempted to authenticate the request and threw.
142
399
 
143
400
  **Fix:** Verify the client is sending the correct `Authorization` header:
144
- - For JWT: `Authorization: Bearer <token>`
401
+ - For Bearer (JWS/JWKS): `Authorization: Bearer <token>`
145
402
  - For Basic: `Authorization: Basic <base64(username:password)>`
146
403
 
147
- Check that the token is not expired and the credentials are valid.
404
+ Common causes:
405
+ - Token expired
406
+ - Token signed with a different key
407
+ - Wrong strategy name in route config (e.g., `'jwt'` when using JWKS)
408
+ - Strategy not registered (see below)
409
+
410
+ ### "[AuthenticationStrategyRegistry] Descriptor not found: jwt"
411
+
412
+ **Cause:** A route references strategy name `'jwt'` but no strategy with that name has been registered in the `AuthenticationStrategyRegistry`.
413
+
414
+ **Fix:** Strategies are **not auto-registered** by `AuthenticateComponent`. You must manually register them after the component:
415
+
416
+ ```typescript
417
+ // In preConfigure() or after component registration
418
+ this.component(AuthenticateComponent);
419
+
420
+ // Manual strategy registration
421
+ AuthenticationStrategyRegistry.getInstance().register({
422
+ container: this,
423
+ strategies: [
424
+ { strategy: JWSAuthenticationStrategy, name: 'jwt' },
425
+ ],
426
+ });
427
+ ```
428
+
429
+ See [Usage & Examples](./usage#strategy-registration) for the full registration flow.
148
430
 
149
431
  ### "[AuthController] Failed to init auth controller | Invalid injectable authentication service!"
150
432
 
151
- **Cause:** The auth controller factory could not resolve the auth service from the DI container. The service key (default `'services.AuthenticationService'`) is not bound.
433
+ **Cause:** The auth controller factory could not resolve the authentication service from DI. The service key (configured via `controllerOpts.serviceKey`) is not bound.
152
434
 
153
435
  **Fix:** Register your `AuthenticationService` before registering the component:
154
436
 
155
437
  ```typescript
438
+ // 1. Register your auth service
156
439
  this.service(AuthenticationService);
157
- // Then register the component
440
+
441
+ // 2. Configure REST options with matching service key
442
+ this.bind<TAuthenticationRestOptions>({ key: AuthenticateBindingKeys.REST_OPTIONS }).toValue({
443
+ useAuthController: true,
444
+ controllerOpts: {
445
+ restPath: '/auth',
446
+ serviceKey: 'services.AuthenticationService',
447
+ },
448
+ });
449
+
450
+ // 3. Register component
158
451
  this.component(AuthenticateComponent);
159
452
  ```
160
453
 
161
- ### "[JWTTokenService] Invalid jwtSecret" / "[JWTTokenService] Invalid applicationSecret" / "[JWTTokenService] Invalid getTokenExpiresFn"
454
+ ### "[defineBasicAuth] verifyCredentials function is required"
455
+
456
+ **Cause:** `BASIC_OPTIONS` was bound but without a `verifyCredentials` callback.
457
+
458
+ **Fix:** Provide a `verifyCredentials` function:
459
+
460
+ ```typescript
461
+ this.bind<TBasicTokenServiceOptions>({ key: AuthenticateBindingKeys.BASIC_OPTIONS }).toValue({
462
+ verifyCredentials: async ({ credentials, context }) => {
463
+ const user = await userRepo.findByUsername(credentials.username);
464
+ if (user && await bcrypt.compare(credentials.password, user.passwordHash)) {
465
+ return { userId: user.id };
466
+ }
467
+ return null;
468
+ },
469
+ });
470
+ ```
471
+
472
+ ### "[verify] Invalid or expired token"
473
+
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
+
476
+ **Fix:** Check the application logs for the full error. Common causes:
477
+ - Token has expired (check `exp` claim)
478
+ - Token signed with a different secret/key
479
+ - Token was tampered with
480
+ - Algorithm mismatch between signing and verification
481
+
482
+ ```bash
483
+ # Look for the full error in logs
484
+ grep "Failed to verify token" logs/application.log
485
+ ```
486
+
487
+ ---
488
+
489
+ ## Error Categories
490
+
491
+ ```mermaid
492
+ flowchart TB
493
+ subgraph S400["Startup Errors (400)"]
494
+ direction TB
495
+ A1["Missing options"]
496
+ A2["Invalid secrets"]
497
+ A3["Missing functions"]
498
+ A4["JWKS key validation"]
499
+ A5["Mode validation"]
500
+ A6["DI resolution"]
501
+ end
502
+
503
+ subgraph S401["Runtime Errors (401)"]
504
+ direction TB
505
+ B1["Missing header"]
506
+ B2["Wrong scheme"]
507
+ B3["Invalid format"]
508
+ B4["Token verification"]
509
+ B5["Credential verification"]
510
+ B6["Strategy exhaustion"]
511
+ end
512
+
513
+ subgraph S500["Structural Errors (500)"]
514
+ direction TB
515
+ C1["Unsupported operation"]
516
+ C2["Uninitialized state"]
517
+ C3["Key/file I/O errors"]
518
+ C4["Invalid auth mode"]
519
+ end
520
+
521
+ style S400 fill:#fff3cd,stroke:#ffc107
522
+ style S401 fill:#f8d7da,stroke:#dc3545
523
+ style S500 fill:#d1ecf1,stroke:#0dcaf0
524
+ ```
525
+
526
+ ### Startup Errors (400)
527
+
528
+ These errors prevent the application from starting. They occur during component binding or DI resolution. The component uses `getError()` without an explicit status code, which defaults to **400**.
529
+
530
+ | Category | Errors | When |
531
+ |----------|--------|------|
532
+ | Missing options | `At least one of jwtOptions or basicOptions` | No auth options bound |
533
+ | Invalid secrets | `Invalid jwtSecret` | JWS secret missing or placeholder |
534
+ | Missing functions | `getTokenExpiresFn is required` | No expiry function |
535
+ | JWKS key validation | `keys.private and keys.public are required` | Missing key material |
536
+ | JWKS format validation | `keys.format is required` | Invalid key format |
537
+ | Mode validation | `Unknown JOSE standard`, `Invalid JWKS mode` | Invalid discriminated union value |
538
+ | DI resolution | `Invalid injectable authentication service` | Service not registered |
539
+
540
+ ::: info Why 400 and not 500?
541
+ The `AuthenticateComponent` and `AbstractAuthRegistry` use `getError({ message })` without specifying `statusCode`. The `getError()` helper defaults to `statusCode: 400`. Service-level initialization errors (file I/O, key parsing) explicitly set `statusCode: 500`.
542
+ :::
543
+
544
+ ### Runtime Errors (401)
545
+
546
+ These errors occur during request processing and return `401 Unauthorized` to clients.
162
547
 
163
- **Cause:** The `JWTTokenService` constructor validates its injected options. These errors (status 500) occur when the service is instantiated with missing or falsy values. This is separate from the component-level `defineJWTAuth` validation and fires during DI resolution.
548
+ | Category | Errors | When |
549
+ |----------|--------|------|
550
+ | Missing header | `Missing authorization header` | No `Authorization` header |
551
+ | Wrong scheme | `Invalid schema of request token` | Header uses wrong auth type |
552
+ | Invalid format | `Invalid authorization header format` | Malformed header value |
553
+ | Token verification | `Invalid or expired token` | JWT verification failed |
554
+ | Credential verification | `Invalid username or password` | Basic auth credentials rejected |
555
+ | Strategy exhaustion | `Authentication failed. Tried strategies:` | All strategies failed |
164
556
 
165
- **Fix:** Ensure the bound `IJWTTokenServiceOptions` has all required fields populated with valid values.
557
+ ### Structural Errors (500)
166
558
 
167
- ### "[BasicTokenService] Invalid verifyCredentials function"
559
+ These errors indicate programming mistakes, I/O failures, or misconfiguration that should be fixed in code.
168
560
 
169
- **Cause:** The `BasicTokenService` constructor validates that the injected `verifyCredentials` option is present. This error (status 500) fires during DI resolution.
561
+ | Category | Errors | When |
562
+ |----------|--------|------|
563
+ | Unsupported operation | `Verifier mode cannot sign tokens` | Wrong service used for signing |
564
+ | Uninitialized state | `JWKS not initialized yet` | Sync access before async init |
565
+ | Key/file I/O errors | `Unknown key driver`, `Invalid raw.priv key`, `Invalid JWK key material` | JWKS key loading/parsing failed |
566
+ | Invalid mode | `Invalid authentication mode` | Unknown mode passed to provider |
170
567
 
171
- **Fix:** Ensure the bound `IBasicTokenServiceOptions` includes a `verifyCredentials` function.
568
+ ---
172
569
 
173
570
  ## See Also
174
571