@nauth-toolkit/core 0.1.98 → 0.1.99
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/dist/openapi/components.schemas.json +4109 -0
- package/dist/openapi/generate-openapi.d.ts +28 -0
- package/dist/openapi/generate-openapi.d.ts.map +1 -0
- package/dist/openapi/generate-openapi.js +247 -0
- package/dist/openapi/generate-openapi.js.map +1 -0
- package/dist/openapi/index.d.ts +77 -0
- package/dist/openapi/index.d.ts.map +1 -0
- package/dist/openapi/index.js +46 -0
- package/dist/openapi/index.js.map +1 -0
- package/package.json +13 -4
|
@@ -0,0 +1,4109 @@
|
|
|
1
|
+
{
|
|
2
|
+
"openapi": "3.0.3",
|
|
3
|
+
"components": {
|
|
4
|
+
"schemas": {
|
|
5
|
+
"AdminGetMFAStatusDTO": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"sub": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "User's unique identifier (UUID v4)\n\nValidation:\n- Must be a valid UUID v4 format\n- Matches DB constraint: char(36) or uuid\n\nSanitization:\n- Trimmed\n- Lowercased for consistency",
|
|
11
|
+
"examples": [
|
|
12
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"required": [
|
|
17
|
+
"sub"
|
|
18
|
+
],
|
|
19
|
+
"additionalProperties": false,
|
|
20
|
+
"description": "Admin request DTO for getting MFA status (includes target user sub)"
|
|
21
|
+
},
|
|
22
|
+
"AdminGetUserAuthHistoryDTO": {
|
|
23
|
+
"type": "object",
|
|
24
|
+
"properties": {
|
|
25
|
+
"page": {
|
|
26
|
+
"type": "number",
|
|
27
|
+
"description": "Page number (1-indexed)",
|
|
28
|
+
"default": 1
|
|
29
|
+
},
|
|
30
|
+
"limit": {
|
|
31
|
+
"type": "number",
|
|
32
|
+
"description": "Number of records per page",
|
|
33
|
+
"default": 50
|
|
34
|
+
},
|
|
35
|
+
"startDate": {
|
|
36
|
+
"type": "string",
|
|
37
|
+
"format": "date-time",
|
|
38
|
+
"description": "Filter events from this date onwards"
|
|
39
|
+
},
|
|
40
|
+
"endDate": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"format": "date-time",
|
|
43
|
+
"description": "Filter events up to this date"
|
|
44
|
+
},
|
|
45
|
+
"eventTypes": {
|
|
46
|
+
"type": "array",
|
|
47
|
+
"items": {
|
|
48
|
+
"$ref": "#/components/schemas/AuthAuditEventType"
|
|
49
|
+
},
|
|
50
|
+
"description": "Filter by specific event types\n\nIf provided, only events matching these types will be returned."
|
|
51
|
+
},
|
|
52
|
+
"eventStatus": {
|
|
53
|
+
"type": "array",
|
|
54
|
+
"items": {
|
|
55
|
+
"$ref": "#/components/schemas/AuthAuditEventStatus"
|
|
56
|
+
},
|
|
57
|
+
"description": "Filter by event status\n\nIf provided, only events matching these statuses will be returned."
|
|
58
|
+
},
|
|
59
|
+
"sub": {
|
|
60
|
+
"type": "string",
|
|
61
|
+
"description": "User's unique identifier (UUID v4)\n\nValidation:\n- Must be a valid UUID v4 format\n- Matches DB constraint: char(36) or uuid\n\nSanitization:\n- Trimmed\n- Lowercased for consistency\n\nRequired for admin operations.",
|
|
62
|
+
"examples": [
|
|
63
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"required": [
|
|
68
|
+
"sub"
|
|
69
|
+
],
|
|
70
|
+
"additionalProperties": false,
|
|
71
|
+
"description": "Request DTO for getting user authentication history (admin-only)\n\nAdmin DTO - requires sub field. Used by AdminAuthService."
|
|
72
|
+
},
|
|
73
|
+
"AuthAuditEventType": {
|
|
74
|
+
"type": "string",
|
|
75
|
+
"enum": [
|
|
76
|
+
"LOGIN_ATTEMPT",
|
|
77
|
+
"LOGIN_SUCCESS",
|
|
78
|
+
"LOGIN_FAILED",
|
|
79
|
+
"LOGIN_BLOCKED",
|
|
80
|
+
"SESSION_CREATED",
|
|
81
|
+
"SESSION_REVOKED",
|
|
82
|
+
"GLOBAL_SIGNOUT",
|
|
83
|
+
"PASSWORD_CHANGED",
|
|
84
|
+
"PASSWORD_RESET_REQUESTED",
|
|
85
|
+
"PASSWORD_RESET_COMPLETED",
|
|
86
|
+
"PASSWORD_FORCE_CHANGE_SET",
|
|
87
|
+
"PASSWORD_FORCE_CHANGE_COMPLETED",
|
|
88
|
+
"ADMIN_PASSWORD_RESET_INITIATED",
|
|
89
|
+
"ADMIN_PASSWORD_RESET_COMPLETED",
|
|
90
|
+
"ADMIN_PASSWORD_RESET_FAILED",
|
|
91
|
+
"MFA_ENABLED",
|
|
92
|
+
"MFA_DISABLED",
|
|
93
|
+
"MFA_DEVICE_ADDED",
|
|
94
|
+
"MFA_DEVICE_REMOVED",
|
|
95
|
+
"MFA_DEVICE_UPDATED",
|
|
96
|
+
"MFA_VERIFICATION_SUCCESS",
|
|
97
|
+
"MFA_VERIFICATION_FAILED",
|
|
98
|
+
"MFA_EXEMPTION_GRANTED",
|
|
99
|
+
"MFA_EXEMPTION_REVOKED",
|
|
100
|
+
"MFA_BACKUP_CODES_GENERATED",
|
|
101
|
+
"MFA_BACKUP_CODE_USED",
|
|
102
|
+
"MFA_PREFERRED_METHOD_UPDATED",
|
|
103
|
+
"DEVICE_TRUSTED",
|
|
104
|
+
"DEVICE_UNTRUSTED",
|
|
105
|
+
"ADAPTIVE_MFA_RISK_ASSESSED",
|
|
106
|
+
"ADAPTIVE_MFA_TRIGGERED",
|
|
107
|
+
"ADAPTIVE_MFA_BYPASSED",
|
|
108
|
+
"EMAIL_VERIFIED",
|
|
109
|
+
"EMAIL_VERIFICATION_REQUESTED",
|
|
110
|
+
"EMAIL_VERIFICATION_FAILED",
|
|
111
|
+
"PHONE_VERIFIED",
|
|
112
|
+
"PHONE_VERIFICATION_REQUESTED",
|
|
113
|
+
"PHONE_VERIFICATION_FAILED",
|
|
114
|
+
"ACCOUNT_CREATED",
|
|
115
|
+
"ACCOUNT_ACTIVATED",
|
|
116
|
+
"ACCOUNT_DEACTIVATED",
|
|
117
|
+
"ACCOUNT_LOCKED",
|
|
118
|
+
"ACCOUNT_UNLOCKED",
|
|
119
|
+
"ACCOUNT_DISABLED",
|
|
120
|
+
"ACCOUNT_ENABLED",
|
|
121
|
+
"ACCOUNT_DELETED",
|
|
122
|
+
"PROFILE_UPDATED",
|
|
123
|
+
"EMAIL_CHANGED",
|
|
124
|
+
"PHONE_CHANGED",
|
|
125
|
+
"USERNAME_CHANGED",
|
|
126
|
+
"SOCIAL_LOGIN",
|
|
127
|
+
"SOCIAL_ACCOUNT_LINKED",
|
|
128
|
+
"SOCIAL_ACCOUNT_UNLINKED",
|
|
129
|
+
"CHALLENGE_CREATED",
|
|
130
|
+
"CHALLENGE_COMPLETED",
|
|
131
|
+
"CHALLENGE_ATTEMPT_FAILED",
|
|
132
|
+
"SUSPICIOUS_ACTIVITY"
|
|
133
|
+
],
|
|
134
|
+
"description": "Authentication Audit Event Types\n\nComprehensive enumeration of all authentication and security events that are recorded in the audit trail.\n\n**Organization:**\n- Login events (success, failure, blocked)\n- Session management events\n- Password operations\n- Multi-Factor Authentication (MFA) events\n- Adaptive MFA events (risk-based)\n- Verification events (email, phone)\n- Account management events\n- Profile update events\n- Social authentication events\n- Challenge flow events\n- Security violation events\n\n**Note:** TOKEN_REFRESHED is intentionally excluded as it occurs too frequently and would create excessive audit noise. Only security-relevant token operations are audited."
|
|
135
|
+
},
|
|
136
|
+
"AuthAuditEventStatus": {
|
|
137
|
+
"type": "string",
|
|
138
|
+
"enum": [
|
|
139
|
+
"SUCCESS",
|
|
140
|
+
"FAILURE",
|
|
141
|
+
"INFO",
|
|
142
|
+
"SUSPICIOUS"
|
|
143
|
+
],
|
|
144
|
+
"description": "Authentication Audit Event Status\n\nClassification of event outcomes for filtering and analysis."
|
|
145
|
+
},
|
|
146
|
+
"AdminLogoutAllDTO": {
|
|
147
|
+
"type": "object",
|
|
148
|
+
"properties": {
|
|
149
|
+
"sub": {
|
|
150
|
+
"type": "string",
|
|
151
|
+
"description": "User's unique identifier (UUID v4)\n\nValidation:\n- Must be a valid UUID v4 format\n- Matches DB constraint: char(36) or uuid\n\nSanitization:\n- Trimmed\n- Lowercased for consistency",
|
|
152
|
+
"examples": [
|
|
153
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
154
|
+
]
|
|
155
|
+
},
|
|
156
|
+
"forgetDevices": {
|
|
157
|
+
"type": "boolean",
|
|
158
|
+
"description": "Whether to also forget/revoke all trusted devices\n\nIf true, all trusted devices for this user will be revoked, requiring MFA on next login from any device.\n\nDefault: false (devices remain trusted)",
|
|
159
|
+
"examples": [
|
|
160
|
+
false
|
|
161
|
+
]
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
"required": [
|
|
165
|
+
"sub"
|
|
166
|
+
],
|
|
167
|
+
"additionalProperties": false,
|
|
168
|
+
"description": "Request DTO for admin logout all sessions"
|
|
169
|
+
},
|
|
170
|
+
"AdminRemoveDevicesDTO": {
|
|
171
|
+
"type": "object",
|
|
172
|
+
"properties": {
|
|
173
|
+
"methodType": {
|
|
174
|
+
"type": "string",
|
|
175
|
+
"description": "MFA method type to remove\n\nValidation:\n- Must be one of: totp, sms, email, passkey\n- Max 50 characters\n\nSanitization:\n- Trimmed and lowercased",
|
|
176
|
+
"examples": [
|
|
177
|
+
"totp"
|
|
178
|
+
]
|
|
179
|
+
},
|
|
180
|
+
"sub": {
|
|
181
|
+
"type": "string",
|
|
182
|
+
"description": "Target user's unique identifier (UUID v4)",
|
|
183
|
+
"examples": [
|
|
184
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
185
|
+
]
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
"required": [
|
|
189
|
+
"methodType",
|
|
190
|
+
"sub"
|
|
191
|
+
],
|
|
192
|
+
"additionalProperties": false,
|
|
193
|
+
"description": "Admin DTO for removing MFA devices for a specific user\n\nAdmin APIs must explicitly target a user via `sub`. This DTO mirrors {@link RemoveDevicesDTO } but adds `sub`."
|
|
194
|
+
},
|
|
195
|
+
"AdminResetPasswordDTO": {
|
|
196
|
+
"type": "object",
|
|
197
|
+
"properties": {
|
|
198
|
+
"sub": {
|
|
199
|
+
"type": "string",
|
|
200
|
+
"description": "User sub (UUID)\n\nValidation:\n- Must be a valid UUID v4\n\nSanitization:\n- Trimmed\n- Lowercased for consistency",
|
|
201
|
+
"examples": [
|
|
202
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
203
|
+
]
|
|
204
|
+
},
|
|
205
|
+
"deliveryMethod": {
|
|
206
|
+
"type": "string",
|
|
207
|
+
"enum": [
|
|
208
|
+
"email",
|
|
209
|
+
"sms"
|
|
210
|
+
],
|
|
211
|
+
"description": "Delivery method for reset code\n\nValidation:\n- Must be 'email' or 'sms'\n- Optional (defaults to 'email')",
|
|
212
|
+
"default": "email"
|
|
213
|
+
},
|
|
214
|
+
"baseUrl": {
|
|
215
|
+
"type": "string",
|
|
216
|
+
"description": "Base URL for building reset link\n\nValidation:\n- Must be valid URL with http:// or https://\n- Supports localhost URLs (e.g., http://localhost:4200)\n- Max 2048 characters\n- Optional\n\nSanitization:\n- Trimmed\n\nWHY: Allows consumer apps to build custom reset UI (e.g., myapp.com/reset-password?token=xxx) Like email verification, supports both code AND link delivery",
|
|
217
|
+
"examples": [
|
|
218
|
+
"https://myapp.com/reset-password",
|
|
219
|
+
"http://localhost:4200"
|
|
220
|
+
]
|
|
221
|
+
},
|
|
222
|
+
"codeExpiresIn": {
|
|
223
|
+
"type": "number",
|
|
224
|
+
"description": "Code expiry in seconds\n\nValidation:\n- Must be number\n- Min 300 seconds (5 minutes)\n- Max 86400 seconds (24 hours)\n- Optional",
|
|
225
|
+
"examples": [
|
|
226
|
+
3600
|
|
227
|
+
],
|
|
228
|
+
"default": "3600 (1 hour - longer than user-initiated 15min)"
|
|
229
|
+
},
|
|
230
|
+
"revokeSessions": {
|
|
231
|
+
"type": "boolean",
|
|
232
|
+
"description": "Revoke all active sessions immediately (before sending email)\n\nValidation:\n- Must be boolean\n- Optional\n\nWHY: Admin can lock user out immediately while sending reset email Different from confirmAdminResetPassword which always revokes on completion",
|
|
233
|
+
"examples": [
|
|
234
|
+
true
|
|
235
|
+
],
|
|
236
|
+
"default": false
|
|
237
|
+
},
|
|
238
|
+
"reason": {
|
|
239
|
+
"type": "string",
|
|
240
|
+
"description": "Reason for admin-initiated reset (for audit trail)\n\nValidation:\n- Must be string\n- Max 500 characters\n- Optional\n\nSanitization:\n- Trimmed",
|
|
241
|
+
"examples": [
|
|
242
|
+
"User reported account compromise"
|
|
243
|
+
]
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
"required": [
|
|
247
|
+
"sub"
|
|
248
|
+
],
|
|
249
|
+
"additionalProperties": false,
|
|
250
|
+
"description": "Request DTO for admin password reset"
|
|
251
|
+
},
|
|
252
|
+
"AdminResetPasswordResponseDTO": {
|
|
253
|
+
"type": "object",
|
|
254
|
+
"properties": {
|
|
255
|
+
"success": {
|
|
256
|
+
"type": "boolean",
|
|
257
|
+
"description": "Success indicator Always true on successful request"
|
|
258
|
+
},
|
|
259
|
+
"destination": {
|
|
260
|
+
"type": "string",
|
|
261
|
+
"description": "Masked destination where code was sent"
|
|
262
|
+
},
|
|
263
|
+
"deliveryMedium": {
|
|
264
|
+
"type": "string",
|
|
265
|
+
"enum": [
|
|
266
|
+
"email",
|
|
267
|
+
"sms"
|
|
268
|
+
],
|
|
269
|
+
"description": "Delivery medium used"
|
|
270
|
+
},
|
|
271
|
+
"expiresIn": {
|
|
272
|
+
"type": "number",
|
|
273
|
+
"description": "Code expiry in seconds",
|
|
274
|
+
"examples": [
|
|
275
|
+
3600
|
|
276
|
+
]
|
|
277
|
+
},
|
|
278
|
+
"sessionsRevoked": {
|
|
279
|
+
"type": "number",
|
|
280
|
+
"description": "Number of sessions revoked (if revokeSessions was true)",
|
|
281
|
+
"examples": [
|
|
282
|
+
3
|
|
283
|
+
]
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
"required": [
|
|
287
|
+
"success"
|
|
288
|
+
],
|
|
289
|
+
"additionalProperties": false,
|
|
290
|
+
"description": "Admin Reset Password Response DTO\n\nResponse DTO for admin-initiated password reset request."
|
|
291
|
+
},
|
|
292
|
+
"AdminRevokeSessionDTO": {
|
|
293
|
+
"type": "object",
|
|
294
|
+
"properties": {
|
|
295
|
+
"sub": {
|
|
296
|
+
"type": "string",
|
|
297
|
+
"description": "User sub (UUID) - must match the session owner"
|
|
298
|
+
},
|
|
299
|
+
"sessionId": {
|
|
300
|
+
"type": "string",
|
|
301
|
+
"description": "Session ID to revoke"
|
|
302
|
+
}
|
|
303
|
+
},
|
|
304
|
+
"required": [
|
|
305
|
+
"sub",
|
|
306
|
+
"sessionId"
|
|
307
|
+
],
|
|
308
|
+
"additionalProperties": false,
|
|
309
|
+
"description": "DTO for revoking a specific user session (admin-only)"
|
|
310
|
+
},
|
|
311
|
+
"AdminSetPasswordDTO": {
|
|
312
|
+
"type": "object",
|
|
313
|
+
"properties": {
|
|
314
|
+
"sub": {
|
|
315
|
+
"type": "string",
|
|
316
|
+
"description": "User sub (UUID)\n\nValidation:\n- Must be a valid UUID v4\n\nSanitization:\n- Trimmed\n- Lowercased for consistency",
|
|
317
|
+
"examples": [
|
|
318
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
319
|
+
]
|
|
320
|
+
},
|
|
321
|
+
"newPassword": {
|
|
322
|
+
"type": "string",
|
|
323
|
+
"description": "New password\n\nValidation:\n- Must be a string\n- Min 8 characters (security requirement)\n- Max 128 characters (prevents DoS)\n\nNote: NOT trimmed (passwords can have leading/trailing spaces) Additional checks in service layer:\n- Password strength (if configured)\n- Password history (prevent reuse)"
|
|
324
|
+
},
|
|
325
|
+
"mustChangePassword": {
|
|
326
|
+
"type": "boolean",
|
|
327
|
+
"description": "Require user to change password on next login\n\nDefault: true (security best practice)",
|
|
328
|
+
"examples": [
|
|
329
|
+
true
|
|
330
|
+
]
|
|
331
|
+
},
|
|
332
|
+
"revokeSessions": {
|
|
333
|
+
"type": "boolean",
|
|
334
|
+
"description": "Revoke all active sessions after password reset\n\nDefault: true (security best practice)",
|
|
335
|
+
"examples": [
|
|
336
|
+
true
|
|
337
|
+
]
|
|
338
|
+
}
|
|
339
|
+
},
|
|
340
|
+
"required": [
|
|
341
|
+
"sub",
|
|
342
|
+
"newPassword"
|
|
343
|
+
],
|
|
344
|
+
"additionalProperties": false,
|
|
345
|
+
"description": "Request DTO for admin password reset"
|
|
346
|
+
},
|
|
347
|
+
"AdminSetPasswordResponseDTO": {
|
|
348
|
+
"type": "object",
|
|
349
|
+
"properties": {
|
|
350
|
+
"success": {
|
|
351
|
+
"type": "boolean",
|
|
352
|
+
"description": "Success indicator Always true on successful password reset"
|
|
353
|
+
},
|
|
354
|
+
"mustChangePassword": {
|
|
355
|
+
"type": "boolean",
|
|
356
|
+
"description": "Whether user must change password on next login"
|
|
357
|
+
},
|
|
358
|
+
"sessionsRevoked": {
|
|
359
|
+
"type": "number",
|
|
360
|
+
"description": "Number of sessions revoked"
|
|
361
|
+
}
|
|
362
|
+
},
|
|
363
|
+
"required": [
|
|
364
|
+
"success",
|
|
365
|
+
"mustChangePassword",
|
|
366
|
+
"sessionsRevoked"
|
|
367
|
+
],
|
|
368
|
+
"additionalProperties": false,
|
|
369
|
+
"description": "Admin Set Password Response DTO\n\nResponse DTO for admin password reset operation."
|
|
370
|
+
},
|
|
371
|
+
"AdminSetPreferredMethodDTO": {
|
|
372
|
+
"type": "object",
|
|
373
|
+
"properties": {
|
|
374
|
+
"methodType": {
|
|
375
|
+
"type": "string",
|
|
376
|
+
"description": "MFA method type to set as preferred\n\nValidation:\n- Must be one of: totp, sms, email, passkey\n- Max 50 characters\n\nSanitization:\n- Trimmed and lowercased",
|
|
377
|
+
"examples": [
|
|
378
|
+
"totp"
|
|
379
|
+
]
|
|
380
|
+
},
|
|
381
|
+
"sub": {
|
|
382
|
+
"type": "string",
|
|
383
|
+
"description": "Target user's unique identifier (UUID v4)",
|
|
384
|
+
"examples": [
|
|
385
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
386
|
+
]
|
|
387
|
+
}
|
|
388
|
+
},
|
|
389
|
+
"required": [
|
|
390
|
+
"methodType",
|
|
391
|
+
"sub"
|
|
392
|
+
],
|
|
393
|
+
"additionalProperties": false,
|
|
394
|
+
"description": "Admin DTO for setting preferred MFA method for a specific user\n\nAdmin APIs must explicitly target a user via `sub`. This DTO mirrors {@link SetPreferredMethodDTO } but adds `sub`."
|
|
395
|
+
},
|
|
396
|
+
"AdminSignupDTO": {
|
|
397
|
+
"type": "object",
|
|
398
|
+
"properties": {
|
|
399
|
+
"email": {
|
|
400
|
+
"type": "string",
|
|
401
|
+
"description": "User email address\n\nValidation:\n- Valid email format (RFC 5322)\n- Max 255 characters (matches DB limit)\n\nSanitization:\n- Trimmed and lowercased"
|
|
402
|
+
},
|
|
403
|
+
"password": {
|
|
404
|
+
"type": "string",
|
|
405
|
+
"description": "User password\n\nRequired unless `generatePassword` is true.\n\nValidation:\n- Min 8 characters\n- Max 128 characters (prevents DoS via bcrypt)\n- Additional policy checks in service layer\n\nNote: NOT trimmed (passwords can have leading/trailing spaces)"
|
|
406
|
+
},
|
|
407
|
+
"username": {
|
|
408
|
+
"type": "string",
|
|
409
|
+
"description": "Optional username\n\nValidation:\n- 3-50 characters\n- Alphanumeric, underscores, and hyphens only\n- Max 255 characters (DB limit)\n\nSanitization:\n- Trimmed\n- Case preserved (username can be case-sensitive per config)"
|
|
410
|
+
},
|
|
411
|
+
"firstName": {
|
|
412
|
+
"type": "string",
|
|
413
|
+
"description": "Optional first name\n\nValidation:\n- 1-100 characters\n- Max 100 characters (DB limit)\n\nSanitization:\n- Trimmed\n- Title case preserved"
|
|
414
|
+
},
|
|
415
|
+
"lastName": {
|
|
416
|
+
"type": "string",
|
|
417
|
+
"description": "Optional last name\n\nValidation:\n- 1-100 characters\n- Max 100 characters (DB limit)\n\nSanitization:\n- Trimmed\n- Title case preserved"
|
|
418
|
+
},
|
|
419
|
+
"phone": {
|
|
420
|
+
"type": "string",
|
|
421
|
+
"description": "Optional phone number\n\nValidation:\n- E.164 format (international standard)\n- MUST start with + (required for security)\n- Max 20 characters (DB limit)\n- Example: +14155552671, +61444567890\n\nSanitization:\n- Whitespace removed\n- Only digits and leading + preserved\n\nSecurity:\n- Strict E.164 validation prevents SQL injection\n- Max length prevents oversized inputs"
|
|
422
|
+
},
|
|
423
|
+
"metadata": {
|
|
424
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E",
|
|
425
|
+
"description": "Optional metadata (custom fields)\n\nSecurity:\n- Validated in service layer if used\n- Max depth/size limits should be enforced"
|
|
426
|
+
},
|
|
427
|
+
"isEmailVerified": {
|
|
428
|
+
"type": "boolean",
|
|
429
|
+
"description": "Bypass email verification requirement\n\nIf true, user's email is marked as verified without sending verification email. If false (default), user must verify email through normal flow.\n\nDefault: false"
|
|
430
|
+
},
|
|
431
|
+
"isPhoneVerified": {
|
|
432
|
+
"type": "boolean",
|
|
433
|
+
"description": "Bypass phone verification requirement\n\nIf true, user's phone is marked as verified without sending verification SMS. If false (default), user must verify phone through normal flow.\n\nDefault: false"
|
|
434
|
+
},
|
|
435
|
+
"mustChangePassword": {
|
|
436
|
+
"type": "boolean",
|
|
437
|
+
"description": "Force password change on first login\n\nIf true, user will be required to change password on next login. Useful when auto-generating passwords or when admin sets temporary passwords.\n\nDefault: false"
|
|
438
|
+
},
|
|
439
|
+
"generatePassword": {
|
|
440
|
+
"type": "boolean",
|
|
441
|
+
"description": "Auto-generate secure password\n\nIf true, a cryptographically secure random password will be generated. The generated password will be returned in the response (returned once only). Password field is not required when this is true.\n\nDefault: false\n\nSecurity: Generated passwords are 16 characters, mixed case, numbers, and special characters. They are returned once in the response and never stored in plain text."
|
|
442
|
+
}
|
|
443
|
+
},
|
|
444
|
+
"required": [
|
|
445
|
+
"email"
|
|
446
|
+
],
|
|
447
|
+
"additionalProperties": false,
|
|
448
|
+
"description": "DTO for administrative user creation with override capabilities\n\nAllows administrators to create user accounts with:\n- Bypass email/phone verification requirements\n- Force password change on first login\n- Auto-generate secure passwords\n\nSecurity:\n- All fields validated against DB constraints\n- Input sanitization applied automatically\n- Password strength enforced (8-128 chars) unless auto-generated\n- Email/username uniqueness checked in service layer\n- Audit trail records admin-created accounts\n\nWarning: This endpoint should be protected by admin authentication. The service does not enforce authorization - it is the responsibility of the framework adapter (NestJS/Express/Fastify) to protect the endpoint."
|
|
449
|
+
},
|
|
450
|
+
"Record<string,unknown>": {
|
|
451
|
+
"type": "object",
|
|
452
|
+
"additionalProperties": {}
|
|
453
|
+
},
|
|
454
|
+
"AdminSignupResponseDTO": {
|
|
455
|
+
"type": "object",
|
|
456
|
+
"properties": {
|
|
457
|
+
"user": {
|
|
458
|
+
"$ref": "#/components/schemas/UserResponseDto",
|
|
459
|
+
"description": "Created user object (sanitized)\n\nUses UserResponseDto which excludes sensitive fields:\n- No passwordHash\n- No internal database ID (uses 'sub' UUID instead)\n- No MFA secrets\n- No internal tracking fields"
|
|
460
|
+
},
|
|
461
|
+
"generatedPassword": {
|
|
462
|
+
"type": "string",
|
|
463
|
+
"description": "Generated password (only present if generatePassword was true)\n\nSecurity: This is returned once and never stored in plain text. The admin should securely deliver this to the user."
|
|
464
|
+
}
|
|
465
|
+
},
|
|
466
|
+
"required": [
|
|
467
|
+
"user"
|
|
468
|
+
],
|
|
469
|
+
"additionalProperties": false,
|
|
470
|
+
"description": "Response DTO for admin signup\n\nReturns the created user object (sanitized, excludes sensitive fields like passwordHash) and optionally the generated password (only if generatePassword was true in the request)."
|
|
471
|
+
},
|
|
472
|
+
"UserResponseDto": {
|
|
473
|
+
"type": "object",
|
|
474
|
+
"properties": {
|
|
475
|
+
"sub": {
|
|
476
|
+
"type": "string",
|
|
477
|
+
"description": "External user identifier (UUID v4) This is the 'sub' (subject) field from JWT tokens"
|
|
478
|
+
},
|
|
479
|
+
"email": {
|
|
480
|
+
"type": "string",
|
|
481
|
+
"description": "User's email address"
|
|
482
|
+
},
|
|
483
|
+
"username": {
|
|
484
|
+
"type": [
|
|
485
|
+
"string",
|
|
486
|
+
"null"
|
|
487
|
+
],
|
|
488
|
+
"description": "User's username (optional)"
|
|
489
|
+
},
|
|
490
|
+
"firstName": {
|
|
491
|
+
"type": [
|
|
492
|
+
"string",
|
|
493
|
+
"null"
|
|
494
|
+
],
|
|
495
|
+
"description": "User's first name (optional)"
|
|
496
|
+
},
|
|
497
|
+
"lastName": {
|
|
498
|
+
"type": [
|
|
499
|
+
"string",
|
|
500
|
+
"null"
|
|
501
|
+
],
|
|
502
|
+
"description": "User's last name (optional)"
|
|
503
|
+
},
|
|
504
|
+
"phone": {
|
|
505
|
+
"type": [
|
|
506
|
+
"string",
|
|
507
|
+
"null"
|
|
508
|
+
],
|
|
509
|
+
"description": "User's phone number (optional) E.164 format validated in service layer if present"
|
|
510
|
+
},
|
|
511
|
+
"isEmailVerified": {
|
|
512
|
+
"type": "boolean",
|
|
513
|
+
"description": "Email verification status"
|
|
514
|
+
},
|
|
515
|
+
"isPhoneVerified": {
|
|
516
|
+
"type": "boolean",
|
|
517
|
+
"description": "Phone verification status"
|
|
518
|
+
},
|
|
519
|
+
"isActive": {
|
|
520
|
+
"type": "boolean",
|
|
521
|
+
"description": "Account active status"
|
|
522
|
+
},
|
|
523
|
+
"isLocked": {
|
|
524
|
+
"type": "boolean",
|
|
525
|
+
"description": "Account lock status Locked accounts cannot login until unlocked"
|
|
526
|
+
},
|
|
527
|
+
"mfaEnabled": {
|
|
528
|
+
"type": "boolean",
|
|
529
|
+
"description": "MFA enabled status"
|
|
530
|
+
},
|
|
531
|
+
"mfaExempt": {
|
|
532
|
+
"type": "boolean",
|
|
533
|
+
"description": "MFA exemption status (admin-granted bypass of MFA at login)"
|
|
534
|
+
},
|
|
535
|
+
"socialProviders": {
|
|
536
|
+
"anyOf": [
|
|
537
|
+
{
|
|
538
|
+
"type": "array",
|
|
539
|
+
"items": {
|
|
540
|
+
"type": "string"
|
|
541
|
+
}
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
"type": "null"
|
|
545
|
+
}
|
|
546
|
+
],
|
|
547
|
+
"description": "Array of social providers linked to this account\n\nExamples: ['google', 'apple', 'facebook'] null/undefined means no social auth, only password-based"
|
|
548
|
+
},
|
|
549
|
+
"hasPasswordHash": {
|
|
550
|
+
"type": "boolean",
|
|
551
|
+
"description": "Whether this user has a password set Used to determine if user can use password-based authentication or is a pure social signup (no password, only social auth)"
|
|
552
|
+
},
|
|
553
|
+
"createdAt": {
|
|
554
|
+
"type": "string",
|
|
555
|
+
"format": "date-time",
|
|
556
|
+
"description": "Account creation timestamp"
|
|
557
|
+
},
|
|
558
|
+
"updatedAt": {
|
|
559
|
+
"type": "string",
|
|
560
|
+
"format": "date-time",
|
|
561
|
+
"description": "Last account update timestamp"
|
|
562
|
+
}
|
|
563
|
+
},
|
|
564
|
+
"required": [
|
|
565
|
+
"sub",
|
|
566
|
+
"email",
|
|
567
|
+
"isEmailVerified",
|
|
568
|
+
"isPhoneVerified",
|
|
569
|
+
"isActive",
|
|
570
|
+
"isLocked",
|
|
571
|
+
"mfaEnabled",
|
|
572
|
+
"mfaExempt",
|
|
573
|
+
"hasPasswordHash",
|
|
574
|
+
"createdAt",
|
|
575
|
+
"updatedAt"
|
|
576
|
+
],
|
|
577
|
+
"additionalProperties": false,
|
|
578
|
+
"description": "User Response DTO\n\nSanitized user object for API responses. Excludes all sensitive and internal fields.\n\nSecurity:\n- Never exposes password hash\n- Never exposes MFA secrets\n- Never exposes internal tracking fields\n- Exposes 'sub' (external UUID) instead of internal 'id'\n\nNo validators needed - this is generated internally by the library via fromEntity()."
|
|
579
|
+
},
|
|
580
|
+
"AdminSignupSocialDTO": {
|
|
581
|
+
"type": "object",
|
|
582
|
+
"properties": {
|
|
583
|
+
"email": {
|
|
584
|
+
"type": "string",
|
|
585
|
+
"description": "User email address\n\nValidation:\n- Valid email format (RFC 5322)\n- Max 255 characters (matches DB limit)\n\nSanitization:\n- Trimmed and lowercased"
|
|
586
|
+
},
|
|
587
|
+
"firstName": {
|
|
588
|
+
"type": "string",
|
|
589
|
+
"description": "Optional first name\n\nValidation:\n- 1-100 characters\n- Max 100 characters (DB limit)\n\nSanitization:\n- Trimmed\n- Title case preserved"
|
|
590
|
+
},
|
|
591
|
+
"isPhoneVerified": {
|
|
592
|
+
"type": "boolean",
|
|
593
|
+
"description": "Bypass phone verification requirement\n\nIf true, user's phone is marked as verified without sending verification SMS. If false (default), user must verify phone through normal flow.\n\nDefault: false"
|
|
594
|
+
},
|
|
595
|
+
"lastName": {
|
|
596
|
+
"type": "string",
|
|
597
|
+
"description": "Optional last name\n\nValidation:\n- 1-100 characters\n- Max 100 characters (DB limit)\n\nSanitization:\n- Trimmed\n- Title case preserved"
|
|
598
|
+
},
|
|
599
|
+
"metadata": {
|
|
600
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E",
|
|
601
|
+
"description": "Optional metadata (custom fields)\n\nSecurity:\n- Validated in service layer if used\n- Max depth/size limits should be enforced"
|
|
602
|
+
},
|
|
603
|
+
"mustChangePassword": {
|
|
604
|
+
"type": "boolean",
|
|
605
|
+
"description": "Force password change on first login\n\nIf true, user will be required to change password on next login. Only relevant if password is provided (hybrid social+password account).\n\nDefault: false"
|
|
606
|
+
},
|
|
607
|
+
"password": {
|
|
608
|
+
"type": "string",
|
|
609
|
+
"description": "Optional password for hybrid social+password accounts\n\nValidation:\n- Min 8 characters\n- Max 128 characters (prevents DoS via bcrypt)\n- Additional policy checks in service layer\n\nNote: NOT trimmed (passwords can have leading/trailing spaces)\n\nSecurity: If not provided, user will be social-only (no password login). Password can be set later via setPasswordForSocialUser()."
|
|
610
|
+
},
|
|
611
|
+
"phone": {
|
|
612
|
+
"type": "string",
|
|
613
|
+
"description": "Optional phone number\n\nValidation:\n- E.164 format (international standard)\n- MUST start with + (required for security)\n- Max 20 characters (DB limit)\n- Example: +14155552671, +61444567890\n\nSanitization:\n- Whitespace removed\n- Only digits and leading + preserved\n\nSecurity:\n- Strict E.164 validation prevents SQL injection\n- Max length prevents oversized inputs"
|
|
614
|
+
},
|
|
615
|
+
"provider": {
|
|
616
|
+
"type": "string",
|
|
617
|
+
"enum": [
|
|
618
|
+
"google",
|
|
619
|
+
"apple",
|
|
620
|
+
"facebook"
|
|
621
|
+
],
|
|
622
|
+
"description": "Social provider name\n\nThe OAuth provider that the user authenticated with. Must match one of the supported providers.\n\nValidation:\n- Must be 'google', 'apple', or 'facebook'\n- Required field"
|
|
623
|
+
},
|
|
624
|
+
"providerEmail": {
|
|
625
|
+
"type": "string",
|
|
626
|
+
"description": "Provider's email address\n\nThe email address associated with the user's social account. May differ from primary email if user has multiple email addresses. Used for audit trails and account linking verification.\n\nValidation:\n- Valid email format\n- Max 255 characters\n\nOptional: Some providers (like Apple with private relay) may not expose email."
|
|
627
|
+
},
|
|
628
|
+
"providerId": {
|
|
629
|
+
"type": "string",
|
|
630
|
+
"description": "Provider's unique user identifier\n\nThe unique ID assigned by the OAuth provider (e.g., Google sub, Apple user ID). Used to link the social account to the user record.\n\nValidation:\n- Required field\n- Max 255 characters (DB limit)\n- Unique per provider (enforced at DB level)\n\nSecurity: provider+providerId combination must be unique across all users."
|
|
631
|
+
},
|
|
632
|
+
"socialMetadata": {
|
|
633
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E",
|
|
634
|
+
"description": "Raw OAuth profile data from provider\n\nStores the complete OAuth profile response from the provider. Useful for debugging, audit trails, and extracting additional user attributes.\n\nSecurity:\n- Stored as JSON in database\n- Not exposed in public APIs\n- Used internally for troubleshooting"
|
|
635
|
+
},
|
|
636
|
+
"username": {
|
|
637
|
+
"type": "string",
|
|
638
|
+
"description": "Optional username\n\nValidation:\n- 3-50 characters\n- Alphanumeric, underscores, and hyphens only\n- Max 255 characters (DB limit)\n\nSanitization:\n- Trimmed\n- Lowercased"
|
|
639
|
+
}
|
|
640
|
+
},
|
|
641
|
+
"required": [
|
|
642
|
+
"email",
|
|
643
|
+
"provider",
|
|
644
|
+
"providerId"
|
|
645
|
+
],
|
|
646
|
+
"additionalProperties": false,
|
|
647
|
+
"description": "DTO for administrative social user import with override capabilities\n\nAllows administrators to import existing social users from external platforms (e.g., Cognito, Auth0) into nauth with:\n- Automatic email verification (like normal social signup)\n- Optional phone verification bypass\n- Optional password for hybrid social+password accounts\n- Social account linkage (provider + providerId)\n- Automatic user flag updates (hasSocialAuth)\n\nUse case: Migrating users from external authentication platforms while preserving their social login connections for transparent future logins.\n\nSecurity:\n- All fields validated against DB constraints\n- Input sanitization applied automatically\n- Email/username uniqueness checked in service layer\n- Provider+providerId uniqueness enforced (one social account per provider per user)\n- Audit trail records admin-imported social accounts\n\nWarning: This endpoint should be protected by admin authentication. The service does not enforce authorization - it is the responsibility of the framework adapter (NestJS/Express/Fastify) to protect the endpoint."
|
|
648
|
+
},
|
|
649
|
+
"AdminSignupSocialResponseDTO": {
|
|
650
|
+
"type": "object",
|
|
651
|
+
"properties": {
|
|
652
|
+
"socialAccount": {
|
|
653
|
+
"type": "object",
|
|
654
|
+
"properties": {
|
|
655
|
+
"provider": {
|
|
656
|
+
"type": "string",
|
|
657
|
+
"description": "Social provider name"
|
|
658
|
+
},
|
|
659
|
+
"providerId": {
|
|
660
|
+
"type": "string",
|
|
661
|
+
"description": "Provider's unique user identifier"
|
|
662
|
+
},
|
|
663
|
+
"providerEmail": {
|
|
664
|
+
"type": [
|
|
665
|
+
"string",
|
|
666
|
+
"null"
|
|
667
|
+
],
|
|
668
|
+
"description": "Provider's email address (if available)"
|
|
669
|
+
}
|
|
670
|
+
},
|
|
671
|
+
"required": [
|
|
672
|
+
"provider",
|
|
673
|
+
"providerId",
|
|
674
|
+
"providerEmail"
|
|
675
|
+
],
|
|
676
|
+
"additionalProperties": false,
|
|
677
|
+
"description": "Social account information\n\nConfirms the social account linkage for the imported user."
|
|
678
|
+
},
|
|
679
|
+
"user": {
|
|
680
|
+
"$ref": "#/components/schemas/UserResponseDto",
|
|
681
|
+
"description": "Created user object (sanitized)\n\nUses UserResponseDto which excludes sensitive fields:\n- No passwordHash\n- No internal database ID (uses 'sub' UUID instead)\n- No MFA secrets\n- No internal tracking fields"
|
|
682
|
+
}
|
|
683
|
+
},
|
|
684
|
+
"required": [
|
|
685
|
+
"socialAccount",
|
|
686
|
+
"user"
|
|
687
|
+
],
|
|
688
|
+
"additionalProperties": false,
|
|
689
|
+
"description": "Response DTO for admin social signup\n\nReturns the created user object (sanitized, excludes sensitive fields like passwordHash) and social account information for confirmation."
|
|
690
|
+
},
|
|
691
|
+
"AdminUpdateUserAttributesDTO": {
|
|
692
|
+
"type": "object",
|
|
693
|
+
"properties": {
|
|
694
|
+
"username": {
|
|
695
|
+
"type": "string",
|
|
696
|
+
"description": "Optional username update\n\nValidation:\n- 3-50 characters\n- Alphanumeric, underscores, and hyphens only\n- Max 255 characters (DB limit)\n- Uniqueness checked in service layer\n\nSanitization:\n- Trimmed\n- Case preserved (username can be case-sensitive per config)"
|
|
697
|
+
},
|
|
698
|
+
"firstName": {
|
|
699
|
+
"type": "string",
|
|
700
|
+
"description": "Optional first name update\n\nValidation:\n- 1-100 characters\n- Max 100 characters (DB limit)\n\nSanitization:\n- Trimmed\n- Title case preserved"
|
|
701
|
+
},
|
|
702
|
+
"lastName": {
|
|
703
|
+
"type": "string",
|
|
704
|
+
"description": "Optional last name update\n\nValidation:\n- 1-100 characters\n- Max 100 characters (DB limit)\n\nSanitization:\n- Trimmed\n- Title case preserved"
|
|
705
|
+
},
|
|
706
|
+
"email": {
|
|
707
|
+
"type": "string",
|
|
708
|
+
"description": "Optional email address update\n\nValidation:\n- Valid email format (RFC 5322)\n- Max 255 characters (matches DB limit)\n- Uniqueness checked in service layer\n\nSanitization:\n- Trimmed and lowercased"
|
|
709
|
+
},
|
|
710
|
+
"phone": {
|
|
711
|
+
"type": "string",
|
|
712
|
+
"description": "Optional phone number update\n\nValidation:\n- E.164 format (international standard)\n- MUST start with + (required for security)\n- Max 20 characters (DB limit)\n- Uniqueness checked in service layer\n\nSanitization:\n- Whitespace removed\n- Only digits and leading + preserved\n\nSecurity:\n- Strict E.164 validation prevents SQL injection\n- Max length prevents oversized inputs"
|
|
713
|
+
},
|
|
714
|
+
"metadata": {
|
|
715
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E",
|
|
716
|
+
"description": "Optional metadata update (custom fields)\n\nBehavior:\n- Existing metadata is merged with new values\n- To delete a metadata key, set it to null\n- To update a value, provide the new value\n- To add a new key, include it in the object\n\nSecurity:\n- Validated in service layer if used\n- Max depth/size limits should be enforced"
|
|
717
|
+
},
|
|
718
|
+
"preferredMfaMethod": {
|
|
719
|
+
"$ref": "#/components/schemas/MFADeviceMethod",
|
|
720
|
+
"description": "Optional preferred MFA method\n\nSets the user's preferred MFA method for authentication. Must be one of the MFA device methods the user has configured.\n\nValidation:\n- Must be one of: totp, sms, email, passkey\n- Max 50 characters (matches typical method name length)"
|
|
721
|
+
},
|
|
722
|
+
"retainVerification": {
|
|
723
|
+
"type": "boolean",
|
|
724
|
+
"description": "Optional flag to retain verification status when updating email/phone\n\nWhen true:\n- Email verification status is preserved when email is updated\n- Phone verification status is preserved when phone is updated\n- Useful when verification was done externally or outside nauth-toolkit\n\nWhen false or undefined (default):\n- Email verification is reset to false when email is updated\n- Phone verification is reset to false when phone is updated\n- User must re-verify the new email/phone"
|
|
725
|
+
},
|
|
726
|
+
"sub": {
|
|
727
|
+
"type": "string",
|
|
728
|
+
"description": "User's unique identifier (UUID v4)\n\nValidation:\n- Must be a valid UUID v4 format\n- Matches DB constraint: char(36) or uuid\n\nSanitization:\n- Trimmed\n- Lowercased for consistency",
|
|
729
|
+
"examples": [
|
|
730
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
731
|
+
]
|
|
732
|
+
}
|
|
733
|
+
},
|
|
734
|
+
"required": [
|
|
735
|
+
"sub"
|
|
736
|
+
],
|
|
737
|
+
"additionalProperties": false,
|
|
738
|
+
"description": "Request DTO for admin updating user attributes (includes sub)"
|
|
739
|
+
},
|
|
740
|
+
"MFADeviceMethod": {
|
|
741
|
+
"anyOf": [
|
|
742
|
+
{
|
|
743
|
+
"$ref": "#/components/schemas/MFAMethod.TOTP"
|
|
744
|
+
},
|
|
745
|
+
{
|
|
746
|
+
"$ref": "#/components/schemas/MFAMethod.SMS"
|
|
747
|
+
},
|
|
748
|
+
{
|
|
749
|
+
"$ref": "#/components/schemas/MFAMethod.EMAIL"
|
|
750
|
+
},
|
|
751
|
+
{
|
|
752
|
+
"$ref": "#/components/schemas/MFAMethod.PASSKEY"
|
|
753
|
+
}
|
|
754
|
+
],
|
|
755
|
+
"description": "Device MFA methods (methods that require device setup)\n\nExcludes BACKUP as it's not a device method."
|
|
756
|
+
},
|
|
757
|
+
"MFAMethod.TOTP": {
|
|
758
|
+
"type": "string",
|
|
759
|
+
"const": "totp",
|
|
760
|
+
"description": "Time-based One-Time Password Authenticator apps (Google Authenticator, Authy, Microsoft Authenticator, etc.)"
|
|
761
|
+
},
|
|
762
|
+
"MFAMethod.SMS": {
|
|
763
|
+
"type": "string",
|
|
764
|
+
"const": "sms",
|
|
765
|
+
"description": "SMS verification codes Sends one-time codes via text message"
|
|
766
|
+
},
|
|
767
|
+
"MFAMethod.EMAIL": {
|
|
768
|
+
"type": "string",
|
|
769
|
+
"const": "email",
|
|
770
|
+
"description": "Email verification codes Sends one-time codes via email"
|
|
771
|
+
},
|
|
772
|
+
"MFAMethod.PASSKEY": {
|
|
773
|
+
"type": "string",
|
|
774
|
+
"const": "passkey",
|
|
775
|
+
"description": "WebAuthn/FIDO2 passkeys Biometric authentication (Face ID, Touch ID, Windows Hello) Hardware security keys (YubiKey, etc.)"
|
|
776
|
+
},
|
|
777
|
+
"AuthChallenge": {
|
|
778
|
+
"type": "string",
|
|
779
|
+
"enum": [
|
|
780
|
+
"VERIFY_EMAIL",
|
|
781
|
+
"VERIFY_PHONE",
|
|
782
|
+
"MFA_REQUIRED",
|
|
783
|
+
"MFA_SETUP_REQUIRED",
|
|
784
|
+
"FORCE_CHANGE_PASSWORD"
|
|
785
|
+
],
|
|
786
|
+
"description": "Authentication Challenge Types\n\nRepresents different challenges that must be completed before a user can gain full access to the system. This is similar to AWS Cognito's challenge system."
|
|
787
|
+
},
|
|
788
|
+
"AuthChallengeResponseDTO": {
|
|
789
|
+
"type": "object",
|
|
790
|
+
"properties": {
|
|
791
|
+
"challengeName": {
|
|
792
|
+
"$ref": "#/components/schemas/AuthChallenge",
|
|
793
|
+
"description": "The challenge that must be completed\n\nValidation:\n- Must be a valid AuthChallenge enum value"
|
|
794
|
+
},
|
|
795
|
+
"session": {
|
|
796
|
+
"type": "string",
|
|
797
|
+
"description": "Temporary session identifier for challenge completion (UUID v4) This is NOT a full JWT token - only used for challenge verification\n\nValidation:\n- Must be a valid UUID v4 format\n- Generated using randomUUID() in challenge service",
|
|
798
|
+
"examples": [
|
|
799
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
800
|
+
]
|
|
801
|
+
},
|
|
802
|
+
"challengeParameters": {
|
|
803
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E",
|
|
804
|
+
"description": "Challenge-specific parameters Contains information needed to complete the challenge\n\nValidation:\n- Must be an object"
|
|
805
|
+
},
|
|
806
|
+
"sub": {
|
|
807
|
+
"type": "string",
|
|
808
|
+
"description": "User's unique identifier (UUID v4) Provided so the client knows which user is completing challenges\n\nValidation:\n- Must be a valid UUID v4 format\n- Matches DB constraint: char(36) or uuid",
|
|
809
|
+
"examples": [
|
|
810
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
811
|
+
]
|
|
812
|
+
}
|
|
813
|
+
},
|
|
814
|
+
"required": [
|
|
815
|
+
"challengeName",
|
|
816
|
+
"session",
|
|
817
|
+
"challengeParameters",
|
|
818
|
+
"sub"
|
|
819
|
+
],
|
|
820
|
+
"additionalProperties": false,
|
|
821
|
+
"description": "Challenge Response DTO\n\nUsed when a user's authentication is incomplete due to pending challenges. Contains minimal information about the user and what challenges they must complete.\n\nNote: This is primarily a response DTO, but validation is included for completeness."
|
|
822
|
+
},
|
|
823
|
+
"AuthResponseDTO": {
|
|
824
|
+
"type": "object",
|
|
825
|
+
"properties": {
|
|
826
|
+
"accessToken": {
|
|
827
|
+
"type": "string",
|
|
828
|
+
"description": "JWT access token for API authentication Short-lived (typically 15 minutes)\n\nNOTE: Only present when authentication is complete (no pending challenges)"
|
|
829
|
+
},
|
|
830
|
+
"refreshToken": {
|
|
831
|
+
"type": "string",
|
|
832
|
+
"description": "JWT refresh token for obtaining new access tokens Long-lived (typically 30 days)\n\nNOTE: Only present when authentication is complete (no pending challenges)"
|
|
833
|
+
},
|
|
834
|
+
"accessTokenExpiresAt": {
|
|
835
|
+
"type": "number",
|
|
836
|
+
"description": "Access token expiration timestamp Unix timestamp in seconds"
|
|
837
|
+
},
|
|
838
|
+
"refreshTokenExpiresAt": {
|
|
839
|
+
"type": "number",
|
|
840
|
+
"description": "Refresh token expiration timestamp Unix timestamp in seconds"
|
|
841
|
+
},
|
|
842
|
+
"authMethod": {
|
|
843
|
+
"type": "string",
|
|
844
|
+
"description": "Authentication method used to create the current session (when authentication succeeds).\n\nSemantics:\n- `password`: email/username/phone + password login, or password-first flows\n- `<provider>`: social login provider that created the session (e.g., `google`, `apple`, `facebook`)\n\nNotes:\n- This is session-scoped state (not account capability). Account capabilities are expressed via: - `user.hasPasswordHash` - `user.socialProviders`\n- Only present when authentication is complete (no pending challenges)."
|
|
845
|
+
},
|
|
846
|
+
"trusted": {
|
|
847
|
+
"type": "boolean",
|
|
848
|
+
"description": "Whether the current device is already trusted\n\nWhen true, the device has a valid trusted device token and UI should NOT show \"trust device\" popup.\n\nWhen false and rememberDevices === 'user_opt_in', UI can show popup after login to allow user to opt-in for device trust.\n\nWhen rememberDevices === 'always', this will always be true after successful login.\n\nNOTE: Only present when authentication is complete (no pending challenges)"
|
|
849
|
+
},
|
|
850
|
+
"deviceToken": {
|
|
851
|
+
"type": "string",
|
|
852
|
+
"description": "Device token for trusted device feature (UUID v4)\n\nServer-generated UUID token for identifying trusted devices. Only returned when rememberDevices is not 'never' and device is trusted.\n\nDelivery by mode:\n- **cookies mode**: Token set as `nauth_device_token` httpOnly cookie (not in response body)\n- **json/hybrid mode**: Token returned in response body for mobile apps\n\nMobile apps should:\n- Store token in secure storage (iOS Keychain / Android EncryptedSharedPreferences)\n- Send token in `X-Device-Token` header on subsequent logins\n- Token persists across app restarts and survives logout\n\nWeb apps:\n- Token automatically handled via httpOnly cookie (cookies mode)\n- No manual handling required"
|
|
853
|
+
},
|
|
854
|
+
"user": {
|
|
855
|
+
"$ref": "#/components/schemas/AuthResponseUser",
|
|
856
|
+
"description": "User information Standardized across all authentication methods\n\nNOTE: Only present when authentication is complete (no pending challenges)"
|
|
857
|
+
},
|
|
858
|
+
"challengeName": {
|
|
859
|
+
"$ref": "#/components/schemas/AuthChallenge",
|
|
860
|
+
"description": "Challenge that must be completed before authentication is granted\n\nWhen present, the user must complete this challenge using the challenge completion endpoint before they can access the system.\n\nTokens (accessToken, refreshToken) will NOT be present when a challenge exists."
|
|
861
|
+
},
|
|
862
|
+
"session": {
|
|
863
|
+
"type": "string",
|
|
864
|
+
"description": "Temporary session identifier for challenge completion (UUID v4)\n\nThis is NOT a JWT token - it's a temporary identifier that must be submitted when completing the challenge. It expires after a short time (typically 15 minutes) or after successful challenge completion."
|
|
865
|
+
},
|
|
866
|
+
"challengeParameters": {
|
|
867
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E",
|
|
868
|
+
"description": "Challenge-specific parameters\n\nContains information needed to complete the challenge, such as:\n- Masked email/phone for delivery confirmation\n- Challenge type details\n- Instructions for the user\n\nNOTE: Only present when challengeName is set"
|
|
869
|
+
},
|
|
870
|
+
"sub": {
|
|
871
|
+
"type": "string",
|
|
872
|
+
"description": "User's unique identifier (UUID v4) Present in both successful auth and challenge responses Helps the client track which user is authenticating",
|
|
873
|
+
"examples": [
|
|
874
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
875
|
+
]
|
|
876
|
+
}
|
|
877
|
+
},
|
|
878
|
+
"additionalProperties": false,
|
|
879
|
+
"description": "Unified Authentication Response DTO\n\nUsed for ALL authentication operations:\n- Email/password login\n- User signup\n- Social authentication (Google, Apple, Facebook)\n- Token refresh\n- Challenge completions\n\nThis provides a consistent interface regardless of authentication method, improving developer experience and code maintainability.\n\nWhen challenges are present, tokens will not be issued until all challenges are completed. This ensures proper verification and security enforcement.\n\nNo validators needed - this is generated internally by the library."
|
|
880
|
+
},
|
|
881
|
+
"AuthResponseUser": {
|
|
882
|
+
"type": "object",
|
|
883
|
+
"properties": {
|
|
884
|
+
"sub": {
|
|
885
|
+
"type": "string",
|
|
886
|
+
"description": "User's unique identifier (UUID v4) External identifier safe to expose in JWTs and APIs"
|
|
887
|
+
},
|
|
888
|
+
"email": {
|
|
889
|
+
"type": "string",
|
|
890
|
+
"description": "User's email address"
|
|
891
|
+
},
|
|
892
|
+
"firstName": {
|
|
893
|
+
"type": [
|
|
894
|
+
"string",
|
|
895
|
+
"null"
|
|
896
|
+
],
|
|
897
|
+
"description": "User's first name (optional)"
|
|
898
|
+
},
|
|
899
|
+
"lastName": {
|
|
900
|
+
"type": [
|
|
901
|
+
"string",
|
|
902
|
+
"null"
|
|
903
|
+
],
|
|
904
|
+
"description": "User's last name (optional)"
|
|
905
|
+
},
|
|
906
|
+
"phone": {
|
|
907
|
+
"type": "string",
|
|
908
|
+
"description": "User's phone number (optional) E.164 format"
|
|
909
|
+
},
|
|
910
|
+
"isEmailVerified": {
|
|
911
|
+
"type": "boolean",
|
|
912
|
+
"description": "Email verification status"
|
|
913
|
+
},
|
|
914
|
+
"isPhoneVerified": {
|
|
915
|
+
"type": "boolean",
|
|
916
|
+
"description": "Phone verification status"
|
|
917
|
+
},
|
|
918
|
+
"socialProviders": {
|
|
919
|
+
"type": "array",
|
|
920
|
+
"items": {
|
|
921
|
+
"type": "string"
|
|
922
|
+
},
|
|
923
|
+
"description": "List of linked social providers"
|
|
924
|
+
},
|
|
925
|
+
"hasPasswordHash": {
|
|
926
|
+
"type": "boolean",
|
|
927
|
+
"description": "Whether this user has a password set Used to determine if user can use password-based authentication or is a pure social signup (no password, only social auth)"
|
|
928
|
+
}
|
|
929
|
+
},
|
|
930
|
+
"required": [
|
|
931
|
+
"sub",
|
|
932
|
+
"email",
|
|
933
|
+
"isEmailVerified"
|
|
934
|
+
],
|
|
935
|
+
"additionalProperties": false,
|
|
936
|
+
"description": "User information in authentication responses\n\nMinimal user object returned in AuthResponseDTO. Contains only essential fields needed for client applications."
|
|
937
|
+
},
|
|
938
|
+
"BaseChallengeResponse": {
|
|
939
|
+
"type": "object",
|
|
940
|
+
"properties": {
|
|
941
|
+
"session": {
|
|
942
|
+
"type": "string",
|
|
943
|
+
"description": "Challenge session token"
|
|
944
|
+
}
|
|
945
|
+
},
|
|
946
|
+
"required": [
|
|
947
|
+
"session"
|
|
948
|
+
],
|
|
949
|
+
"additionalProperties": false,
|
|
950
|
+
"description": "Base interface for all challenge responses"
|
|
951
|
+
},
|
|
952
|
+
"CanSetPasswordDTO": {
|
|
953
|
+
"type": "object",
|
|
954
|
+
"properties": {
|
|
955
|
+
"sub": {
|
|
956
|
+
"type": "string",
|
|
957
|
+
"description": "User identifier (UUID v4)\n\nValidation:\n- Must be valid UUID v4 format\n\nSanitization:\n- Trimmed and lowercased"
|
|
958
|
+
}
|
|
959
|
+
},
|
|
960
|
+
"required": [
|
|
961
|
+
"sub"
|
|
962
|
+
],
|
|
963
|
+
"additionalProperties": false,
|
|
964
|
+
"description": "DTO for checking if user can set password\n\nSecurity:\n- User sub validated as UUID v4"
|
|
965
|
+
},
|
|
966
|
+
"CanSetPasswordResponseDTO": {
|
|
967
|
+
"type": "object",
|
|
968
|
+
"properties": {
|
|
969
|
+
"canSetPassword": {
|
|
970
|
+
"type": "boolean",
|
|
971
|
+
"description": "Whether user can set password"
|
|
972
|
+
}
|
|
973
|
+
},
|
|
974
|
+
"required": [
|
|
975
|
+
"canSetPassword"
|
|
976
|
+
],
|
|
977
|
+
"additionalProperties": false,
|
|
978
|
+
"description": "Response DTO for canSetPassword"
|
|
979
|
+
},
|
|
980
|
+
"ChallengeResponseData": {
|
|
981
|
+
"anyOf": [
|
|
982
|
+
{
|
|
983
|
+
"$ref": "#/components/schemas/VerifyEmailResponse"
|
|
984
|
+
},
|
|
985
|
+
{
|
|
986
|
+
"$ref": "#/components/schemas/CollectPhoneResponse"
|
|
987
|
+
},
|
|
988
|
+
{
|
|
989
|
+
"$ref": "#/components/schemas/VerifyPhoneResponse"
|
|
990
|
+
},
|
|
991
|
+
{
|
|
992
|
+
"$ref": "#/components/schemas/VerifyMFACodeResponse"
|
|
993
|
+
},
|
|
994
|
+
{
|
|
995
|
+
"$ref": "#/components/schemas/VerifyMFAPasskeyResponse"
|
|
996
|
+
},
|
|
997
|
+
{
|
|
998
|
+
"$ref": "#/components/schemas/ForceChangePasswordResponse"
|
|
999
|
+
},
|
|
1000
|
+
{
|
|
1001
|
+
"$ref": "#/components/schemas/MFASetupResponse"
|
|
1002
|
+
}
|
|
1003
|
+
],
|
|
1004
|
+
"description": "Discriminated union of all challenge response types\n\nUse this type for the unified respondToChallenge() API. TypeScript will narrow the type based on the 'type' discriminator."
|
|
1005
|
+
},
|
|
1006
|
+
"VerifyEmailResponse": {
|
|
1007
|
+
"type": "object",
|
|
1008
|
+
"properties": {
|
|
1009
|
+
"session": {
|
|
1010
|
+
"type": "string",
|
|
1011
|
+
"description": "Challenge session token"
|
|
1012
|
+
},
|
|
1013
|
+
"type": {
|
|
1014
|
+
"type": "string",
|
|
1015
|
+
"const": "VERIFY_EMAIL"
|
|
1016
|
+
},
|
|
1017
|
+
"code": {
|
|
1018
|
+
"type": "string",
|
|
1019
|
+
"description": "6-digit verification code sent to email"
|
|
1020
|
+
}
|
|
1021
|
+
},
|
|
1022
|
+
"required": [
|
|
1023
|
+
"code",
|
|
1024
|
+
"session",
|
|
1025
|
+
"type"
|
|
1026
|
+
],
|
|
1027
|
+
"additionalProperties": false,
|
|
1028
|
+
"description": "Response for email verification challenge"
|
|
1029
|
+
},
|
|
1030
|
+
"CollectPhoneResponse": {
|
|
1031
|
+
"type": "object",
|
|
1032
|
+
"properties": {
|
|
1033
|
+
"session": {
|
|
1034
|
+
"type": "string",
|
|
1035
|
+
"description": "Challenge session token"
|
|
1036
|
+
},
|
|
1037
|
+
"type": {
|
|
1038
|
+
"type": "string",
|
|
1039
|
+
"const": "VERIFY_PHONE"
|
|
1040
|
+
},
|
|
1041
|
+
"phone": {
|
|
1042
|
+
"type": "string",
|
|
1043
|
+
"description": "Phone number in E.164 format"
|
|
1044
|
+
}
|
|
1045
|
+
},
|
|
1046
|
+
"required": [
|
|
1047
|
+
"phone",
|
|
1048
|
+
"session",
|
|
1049
|
+
"type"
|
|
1050
|
+
],
|
|
1051
|
+
"additionalProperties": false,
|
|
1052
|
+
"description": "Response for collecting phone number (first step)"
|
|
1053
|
+
},
|
|
1054
|
+
"VerifyPhoneResponse": {
|
|
1055
|
+
"type": "object",
|
|
1056
|
+
"properties": {
|
|
1057
|
+
"session": {
|
|
1058
|
+
"type": "string",
|
|
1059
|
+
"description": "Challenge session token"
|
|
1060
|
+
},
|
|
1061
|
+
"type": {
|
|
1062
|
+
"type": "string",
|
|
1063
|
+
"const": "VERIFY_PHONE"
|
|
1064
|
+
},
|
|
1065
|
+
"code": {
|
|
1066
|
+
"type": "string",
|
|
1067
|
+
"description": "6-digit verification code sent to phone"
|
|
1068
|
+
}
|
|
1069
|
+
},
|
|
1070
|
+
"required": [
|
|
1071
|
+
"code",
|
|
1072
|
+
"session",
|
|
1073
|
+
"type"
|
|
1074
|
+
],
|
|
1075
|
+
"additionalProperties": false,
|
|
1076
|
+
"description": "Response for verifying phone with code (second step)"
|
|
1077
|
+
},
|
|
1078
|
+
"VerifyMFACodeResponse": {
|
|
1079
|
+
"type": "object",
|
|
1080
|
+
"properties": {
|
|
1081
|
+
"session": {
|
|
1082
|
+
"type": "string",
|
|
1083
|
+
"description": "Challenge session token"
|
|
1084
|
+
},
|
|
1085
|
+
"type": {
|
|
1086
|
+
"type": "string",
|
|
1087
|
+
"const": "MFA_REQUIRED"
|
|
1088
|
+
},
|
|
1089
|
+
"method": {
|
|
1090
|
+
"type": "string",
|
|
1091
|
+
"enum": [
|
|
1092
|
+
"sms",
|
|
1093
|
+
"totp",
|
|
1094
|
+
"backup"
|
|
1095
|
+
],
|
|
1096
|
+
"description": "MFA method being used"
|
|
1097
|
+
},
|
|
1098
|
+
"code": {
|
|
1099
|
+
"type": "string",
|
|
1100
|
+
"description": "Verification code"
|
|
1101
|
+
}
|
|
1102
|
+
},
|
|
1103
|
+
"required": [
|
|
1104
|
+
"code",
|
|
1105
|
+
"method",
|
|
1106
|
+
"session",
|
|
1107
|
+
"type"
|
|
1108
|
+
],
|
|
1109
|
+
"additionalProperties": false,
|
|
1110
|
+
"description": "Response for MFA verification with code (SMS/TOTP/Backup)"
|
|
1111
|
+
},
|
|
1112
|
+
"VerifyMFAPasskeyResponse": {
|
|
1113
|
+
"type": "object",
|
|
1114
|
+
"properties": {
|
|
1115
|
+
"session": {
|
|
1116
|
+
"type": "string",
|
|
1117
|
+
"description": "Challenge session token"
|
|
1118
|
+
},
|
|
1119
|
+
"type": {
|
|
1120
|
+
"type": "string",
|
|
1121
|
+
"const": "MFA_REQUIRED"
|
|
1122
|
+
},
|
|
1123
|
+
"method": {
|
|
1124
|
+
"type": "string",
|
|
1125
|
+
"const": "passkey",
|
|
1126
|
+
"description": "Passkey method"
|
|
1127
|
+
},
|
|
1128
|
+
"credential": {
|
|
1129
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E",
|
|
1130
|
+
"description": "WebAuthn credential from navigator.credentials.get()"
|
|
1131
|
+
}
|
|
1132
|
+
},
|
|
1133
|
+
"required": [
|
|
1134
|
+
"credential",
|
|
1135
|
+
"method",
|
|
1136
|
+
"session",
|
|
1137
|
+
"type"
|
|
1138
|
+
],
|
|
1139
|
+
"additionalProperties": false,
|
|
1140
|
+
"description": "Response for MFA verification with passkey"
|
|
1141
|
+
},
|
|
1142
|
+
"ForceChangePasswordResponse": {
|
|
1143
|
+
"type": "object",
|
|
1144
|
+
"properties": {
|
|
1145
|
+
"session": {
|
|
1146
|
+
"type": "string",
|
|
1147
|
+
"description": "Challenge session token"
|
|
1148
|
+
},
|
|
1149
|
+
"type": {
|
|
1150
|
+
"type": "string",
|
|
1151
|
+
"const": "FORCE_CHANGE_PASSWORD"
|
|
1152
|
+
},
|
|
1153
|
+
"newPassword": {
|
|
1154
|
+
"type": "string",
|
|
1155
|
+
"description": "New password meeting security requirements"
|
|
1156
|
+
}
|
|
1157
|
+
},
|
|
1158
|
+
"required": [
|
|
1159
|
+
"newPassword",
|
|
1160
|
+
"session",
|
|
1161
|
+
"type"
|
|
1162
|
+
],
|
|
1163
|
+
"additionalProperties": false,
|
|
1164
|
+
"description": "Response for forced password change challenge"
|
|
1165
|
+
},
|
|
1166
|
+
"MFASetupResponse": {
|
|
1167
|
+
"type": "object",
|
|
1168
|
+
"properties": {
|
|
1169
|
+
"session": {
|
|
1170
|
+
"type": "string",
|
|
1171
|
+
"description": "Challenge session token"
|
|
1172
|
+
},
|
|
1173
|
+
"type": {
|
|
1174
|
+
"type": "string",
|
|
1175
|
+
"const": "MFA_SETUP_REQUIRED"
|
|
1176
|
+
},
|
|
1177
|
+
"method": {
|
|
1178
|
+
"type": "string",
|
|
1179
|
+
"enum": [
|
|
1180
|
+
"sms",
|
|
1181
|
+
"email",
|
|
1182
|
+
"totp",
|
|
1183
|
+
"passkey"
|
|
1184
|
+
],
|
|
1185
|
+
"description": "MFA method being set up"
|
|
1186
|
+
},
|
|
1187
|
+
"setupData": {
|
|
1188
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E",
|
|
1189
|
+
"description": "Method-specific setup data\n- SMS: { phone: string, code: string }\n- TOTP: { code: string }\n- Passkey: { credential: Record<string, unknown> }"
|
|
1190
|
+
}
|
|
1191
|
+
},
|
|
1192
|
+
"required": [
|
|
1193
|
+
"method",
|
|
1194
|
+
"session",
|
|
1195
|
+
"setupData",
|
|
1196
|
+
"type"
|
|
1197
|
+
],
|
|
1198
|
+
"additionalProperties": false,
|
|
1199
|
+
"description": "Response for MFA setup during challenge"
|
|
1200
|
+
},
|
|
1201
|
+
"ChallengeResponseRequestDTO": {
|
|
1202
|
+
"type": "object",
|
|
1203
|
+
"properties": {
|
|
1204
|
+
"session": {
|
|
1205
|
+
"type": "string",
|
|
1206
|
+
"description": "Temporary session from initial auth response (UUID v4)\n\nValidation:\n- Must be a valid UUID v4 format\n- Generated using randomUUID() in challenge service\n\nSanitization:\n- Trimmed\n- Lowercased for consistency",
|
|
1207
|
+
"examples": [
|
|
1208
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
1209
|
+
]
|
|
1210
|
+
},
|
|
1211
|
+
"challengeName": {
|
|
1212
|
+
"$ref": "#/components/schemas/AuthChallenge",
|
|
1213
|
+
"description": "The challenge being responded to\n\nValidation:\n- Must be a valid AuthChallenge enum value"
|
|
1214
|
+
},
|
|
1215
|
+
"challengeResponses": {
|
|
1216
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E",
|
|
1217
|
+
"description": "Challenge-specific responses\n\nValidation:\n- Must be an object\n- Structure validated in service layer based on challenge type"
|
|
1218
|
+
}
|
|
1219
|
+
},
|
|
1220
|
+
"required": [
|
|
1221
|
+
"session",
|
|
1222
|
+
"challengeName",
|
|
1223
|
+
"challengeResponses"
|
|
1224
|
+
],
|
|
1225
|
+
"additionalProperties": false,
|
|
1226
|
+
"description": "Challenge Completion Request DTO\n\nUsed to submit a response to an authentication challenge.\n\nNote: This is a legacy DTO. The codebase now uses RespondChallengeDTO for the unified API. This DTO is kept for backwards compatibility.\n\nSecurity:\n- Session token validated as UUID v4 format\n- Challenge name validated against enum\n- Challenge responses validated as object"
|
|
1227
|
+
},
|
|
1228
|
+
"ChallengeType": {
|
|
1229
|
+
"type": "string",
|
|
1230
|
+
"enum": [
|
|
1231
|
+
"VERIFY_EMAIL",
|
|
1232
|
+
"VERIFY_PHONE",
|
|
1233
|
+
"MFA_REQUIRED",
|
|
1234
|
+
"FORCE_CHANGE_PASSWORD",
|
|
1235
|
+
"MFA_SETUP_REQUIRED"
|
|
1236
|
+
],
|
|
1237
|
+
"description": "Challenge type enum for validation"
|
|
1238
|
+
},
|
|
1239
|
+
"ChangePasswordDTO": {
|
|
1240
|
+
"type": "object",
|
|
1241
|
+
"properties": {
|
|
1242
|
+
"oldPassword": {
|
|
1243
|
+
"type": "string",
|
|
1244
|
+
"description": "Current password\n\nValidation:\n- Must be a string\n\nNote: NOT trimmed (passwords can have leading/trailing spaces)"
|
|
1245
|
+
},
|
|
1246
|
+
"newPassword": {
|
|
1247
|
+
"type": "string",
|
|
1248
|
+
"description": "New password\n\nValidation:\n- Must be a string\n- Min 8 characters (security requirement)\n- Max 128 characters (prevents DoS via bcrypt)\n\nNote: NOT trimmed (passwords can have leading/trailing spaces)\n\nAdditional checks in service layer:\n- Password history (prevent reuse of recent passwords)\n- Password strength (if configured)\n- Not same as old password"
|
|
1249
|
+
}
|
|
1250
|
+
},
|
|
1251
|
+
"required": [
|
|
1252
|
+
"oldPassword",
|
|
1253
|
+
"newPassword"
|
|
1254
|
+
],
|
|
1255
|
+
"additionalProperties": false
|
|
1256
|
+
},
|
|
1257
|
+
"ChangePasswordResponseDTO": {
|
|
1258
|
+
"type": "object",
|
|
1259
|
+
"properties": {
|
|
1260
|
+
"success": {
|
|
1261
|
+
"type": "boolean",
|
|
1262
|
+
"description": "Success indicator Always true on successful password change",
|
|
1263
|
+
"examples": [
|
|
1264
|
+
true
|
|
1265
|
+
]
|
|
1266
|
+
}
|
|
1267
|
+
},
|
|
1268
|
+
"required": [
|
|
1269
|
+
"success"
|
|
1270
|
+
],
|
|
1271
|
+
"additionalProperties": false,
|
|
1272
|
+
"description": "Response DTO for change password"
|
|
1273
|
+
},
|
|
1274
|
+
"ConfirmAdminResetPasswordDTO": {
|
|
1275
|
+
"type": "object",
|
|
1276
|
+
"properties": {
|
|
1277
|
+
"sub": {
|
|
1278
|
+
"type": "string",
|
|
1279
|
+
"description": "User sub (UUID)\n\nValidation:\n- Must be a valid UUID v4\n\nSanitization:\n- Trimmed\n- Lowercased for consistency",
|
|
1280
|
+
"examples": [
|
|
1281
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
1282
|
+
]
|
|
1283
|
+
},
|
|
1284
|
+
"code": {
|
|
1285
|
+
"type": "string",
|
|
1286
|
+
"description": "Verification code from email/SMS (6-10 digits)\n\nValidation:\n- Must be string\n- Length 6-10 characters\n- Required\n\nSanitization:\n- Trimmed\n\nWHY: Short code for manual entry, subject to attempt tracking",
|
|
1287
|
+
"examples": [
|
|
1288
|
+
"123456"
|
|
1289
|
+
]
|
|
1290
|
+
},
|
|
1291
|
+
"newPassword": {
|
|
1292
|
+
"type": "string",
|
|
1293
|
+
"description": "New password\n\nValidation:\n- Must be string\n- Min 8 characters (security requirement)\n- Max 128 characters (prevents DoS)\n\nNote: NOT trimmed (passwords can have leading/trailing spaces) Additional checks in service layer:\n- Password strength (if configured)\n- Password history (prevent reuse)",
|
|
1294
|
+
"examples": [
|
|
1295
|
+
"NewSecurePassword123!"
|
|
1296
|
+
]
|
|
1297
|
+
}
|
|
1298
|
+
},
|
|
1299
|
+
"required": [
|
|
1300
|
+
"sub",
|
|
1301
|
+
"code",
|
|
1302
|
+
"newPassword"
|
|
1303
|
+
],
|
|
1304
|
+
"additionalProperties": false,
|
|
1305
|
+
"description": "Confirm Admin Reset Password DTO\n\nUser completes admin-initiated password reset with a verification code.\n\nNOTE:\n- Link support is optional, but links carry the same verification `code` as a query parameter (e.g., `...?code=123456`) to keep consumer apps consistent (code-only).\n\nSecurity:\n- Code is required\n- Attempt tracking enforced (max attempts configured in password reset service)\n- Always revokes all sessions on completion\n- Always sets mustChangePassword flag"
|
|
1306
|
+
},
|
|
1307
|
+
"ConfirmAdminResetPasswordResponseDTO": {
|
|
1308
|
+
"type": "object",
|
|
1309
|
+
"properties": {
|
|
1310
|
+
"success": {
|
|
1311
|
+
"type": "boolean",
|
|
1312
|
+
"description": "Success indicator Always true on successful reset"
|
|
1313
|
+
}
|
|
1314
|
+
},
|
|
1315
|
+
"required": [
|
|
1316
|
+
"success"
|
|
1317
|
+
],
|
|
1318
|
+
"additionalProperties": false,
|
|
1319
|
+
"description": "Confirm Admin Reset Password Response DTO\n\nResponse DTO for successful admin password reset completion."
|
|
1320
|
+
},
|
|
1321
|
+
"ConfirmForgotPasswordDTO": {
|
|
1322
|
+
"type": "object",
|
|
1323
|
+
"properties": {
|
|
1324
|
+
"identifier": {
|
|
1325
|
+
"type": "string",
|
|
1326
|
+
"description": "User identifier used to locate the account.\n\nSanitization:\n- Trimmed\n- Lowercased when email format detected (contains '@')"
|
|
1327
|
+
},
|
|
1328
|
+
"code": {
|
|
1329
|
+
"type": "string",
|
|
1330
|
+
"description": "Verification code delivered via email/SMS.\n\nValidation:\n- Numeric string\n- Exact length 6 (default). If a deployment changes length, the service layer can also validate against config for backward compatibility."
|
|
1331
|
+
},
|
|
1332
|
+
"newPassword": {
|
|
1333
|
+
"type": "string",
|
|
1334
|
+
"description": "New password to set on the account.\n\nValidation:\n- 8-128 characters (baseline)\n- NOT trimmed (passwords may intentionally contain leading/trailing spaces)"
|
|
1335
|
+
}
|
|
1336
|
+
},
|
|
1337
|
+
"required": [
|
|
1338
|
+
"identifier",
|
|
1339
|
+
"code",
|
|
1340
|
+
"newPassword"
|
|
1341
|
+
],
|
|
1342
|
+
"additionalProperties": false,
|
|
1343
|
+
"description": "Confirm Forgot Password DTO\n\nConfirms a password reset request by validating the verification code and setting a new password.\n\nSecurity:\n- Code format validated (numeric string + fixed length).\n- Password policy is enforced in the service layer."
|
|
1344
|
+
},
|
|
1345
|
+
"ConfirmForgotPasswordResponseDTO": {
|
|
1346
|
+
"type": "object",
|
|
1347
|
+
"properties": {
|
|
1348
|
+
"success": {
|
|
1349
|
+
"type": "boolean",
|
|
1350
|
+
"description": "True when reset was confirmed and password updated."
|
|
1351
|
+
},
|
|
1352
|
+
"mustChangePassword": {
|
|
1353
|
+
"type": "boolean",
|
|
1354
|
+
"description": "Whether user must change password on next sign-in.\n\nFor forgot-password flows this should typically be false (password is just set)."
|
|
1355
|
+
}
|
|
1356
|
+
},
|
|
1357
|
+
"required": [
|
|
1358
|
+
"success",
|
|
1359
|
+
"mustChangePassword"
|
|
1360
|
+
],
|
|
1361
|
+
"additionalProperties": false,
|
|
1362
|
+
"description": "Confirm Forgot Password Response DTO\n\nResponse for a confirmed password reset."
|
|
1363
|
+
},
|
|
1364
|
+
"DateFilterDTO": {
|
|
1365
|
+
"type": "object",
|
|
1366
|
+
"properties": {
|
|
1367
|
+
"operator": {
|
|
1368
|
+
"type": "string",
|
|
1369
|
+
"enum": [
|
|
1370
|
+
"gt",
|
|
1371
|
+
"gte",
|
|
1372
|
+
"lt",
|
|
1373
|
+
"lte",
|
|
1374
|
+
"eq"
|
|
1375
|
+
],
|
|
1376
|
+
"description": "Comparison operator\n\n- gt: greater than\n- gte: greater than or equal\n- lt: less than\n- lte: less than or equal\n- eq: equal"
|
|
1377
|
+
},
|
|
1378
|
+
"value": {
|
|
1379
|
+
"type": "string",
|
|
1380
|
+
"format": "date-time",
|
|
1381
|
+
"description": "Date value to compare against"
|
|
1382
|
+
}
|
|
1383
|
+
},
|
|
1384
|
+
"required": [
|
|
1385
|
+
"operator",
|
|
1386
|
+
"value"
|
|
1387
|
+
],
|
|
1388
|
+
"additionalProperties": false,
|
|
1389
|
+
"description": "Date filter with operator support\n\nSupports gt (greater than), gte (greater than or equal), lt (less than), lte (less than or equal), eq (equal) operators for date comparisons."
|
|
1390
|
+
},
|
|
1391
|
+
"DeleteUserDTO": {
|
|
1392
|
+
"type": "object",
|
|
1393
|
+
"properties": {
|
|
1394
|
+
"sub": {
|
|
1395
|
+
"type": "string",
|
|
1396
|
+
"description": "User UUID (sub) to delete\n\nMust be valid UUID format"
|
|
1397
|
+
}
|
|
1398
|
+
},
|
|
1399
|
+
"required": [
|
|
1400
|
+
"sub"
|
|
1401
|
+
],
|
|
1402
|
+
"additionalProperties": false,
|
|
1403
|
+
"description": "DTO for administrative user deletion\n\nPermanently deletes user and ALL associated data:\n- Sessions, verification tokens, MFA devices, trusted devices\n- Social accounts, login attempts, challenge sessions, audit logs\n\nWarning: IRREVERSIBLE - All user data permanently removed from database."
|
|
1404
|
+
},
|
|
1405
|
+
"DeleteUserResponseDTO": {
|
|
1406
|
+
"type": "object",
|
|
1407
|
+
"properties": {
|
|
1408
|
+
"success": {
|
|
1409
|
+
"type": "boolean",
|
|
1410
|
+
"description": "Deletion success flag"
|
|
1411
|
+
},
|
|
1412
|
+
"deletedUserId": {
|
|
1413
|
+
"type": "string",
|
|
1414
|
+
"description": "Deleted user's UUID"
|
|
1415
|
+
},
|
|
1416
|
+
"deletedRecords": {
|
|
1417
|
+
"type": "object",
|
|
1418
|
+
"properties": {
|
|
1419
|
+
"sessions": {
|
|
1420
|
+
"type": "number"
|
|
1421
|
+
},
|
|
1422
|
+
"verificationTokens": {
|
|
1423
|
+
"type": "number"
|
|
1424
|
+
},
|
|
1425
|
+
"mfaDevices": {
|
|
1426
|
+
"type": "number"
|
|
1427
|
+
},
|
|
1428
|
+
"trustedDevices": {
|
|
1429
|
+
"type": "number"
|
|
1430
|
+
},
|
|
1431
|
+
"socialAccounts": {
|
|
1432
|
+
"type": "number"
|
|
1433
|
+
},
|
|
1434
|
+
"loginAttempts": {
|
|
1435
|
+
"type": "number"
|
|
1436
|
+
},
|
|
1437
|
+
"challengeSessions": {
|
|
1438
|
+
"type": "number"
|
|
1439
|
+
},
|
|
1440
|
+
"auditLogs": {
|
|
1441
|
+
"type": "number"
|
|
1442
|
+
}
|
|
1443
|
+
},
|
|
1444
|
+
"required": [
|
|
1445
|
+
"sessions",
|
|
1446
|
+
"verificationTokens",
|
|
1447
|
+
"mfaDevices",
|
|
1448
|
+
"trustedDevices",
|
|
1449
|
+
"socialAccounts",
|
|
1450
|
+
"loginAttempts",
|
|
1451
|
+
"challengeSessions",
|
|
1452
|
+
"auditLogs"
|
|
1453
|
+
],
|
|
1454
|
+
"additionalProperties": false,
|
|
1455
|
+
"description": "Count of cascade-deleted records by table"
|
|
1456
|
+
}
|
|
1457
|
+
},
|
|
1458
|
+
"required": [
|
|
1459
|
+
"success",
|
|
1460
|
+
"deletedUserId",
|
|
1461
|
+
"deletedRecords"
|
|
1462
|
+
],
|
|
1463
|
+
"additionalProperties": false,
|
|
1464
|
+
"description": "Response DTO for administrative user deletion\n\nConfirms deletion and provides counts of cascade-deleted records."
|
|
1465
|
+
},
|
|
1466
|
+
"DisableUserDTO": {
|
|
1467
|
+
"type": "object",
|
|
1468
|
+
"properties": {
|
|
1469
|
+
"sub": {
|
|
1470
|
+
"type": "string",
|
|
1471
|
+
"description": "User UUID (sub) to disable\n\nMust be valid UUID format"
|
|
1472
|
+
},
|
|
1473
|
+
"reason": {
|
|
1474
|
+
"type": "string",
|
|
1475
|
+
"description": "Optional reason for locking account\n\nRecorded in lockReason field and audit trail. Max 500 characters."
|
|
1476
|
+
}
|
|
1477
|
+
},
|
|
1478
|
+
"required": [
|
|
1479
|
+
"sub"
|
|
1480
|
+
],
|
|
1481
|
+
"additionalProperties": false,
|
|
1482
|
+
"description": "DTO for administrative permanent account locking\n\nLocks user account permanently (lockedUntil=NULL) and revokes all active sessions. Uses existing rate-limit lock fields (isLocked, lockReason, lockedAt, lockedUntil).\n\nPermanent vs Temporary locks:\n- Rate limiting: lockedUntil = future date (temporary auto-unlock)\n- Admin disableUser: lockedUntil = NULL (permanent manual lock)"
|
|
1483
|
+
},
|
|
1484
|
+
"DisableUserResponseDTO": {
|
|
1485
|
+
"type": "object",
|
|
1486
|
+
"properties": {
|
|
1487
|
+
"success": {
|
|
1488
|
+
"type": "boolean",
|
|
1489
|
+
"description": "Lock success flag"
|
|
1490
|
+
},
|
|
1491
|
+
"user": {
|
|
1492
|
+
"$ref": "#/components/schemas/UserResponseDto",
|
|
1493
|
+
"description": "Sanitized user object with updated lock status"
|
|
1494
|
+
},
|
|
1495
|
+
"revokedSessions": {
|
|
1496
|
+
"type": "number",
|
|
1497
|
+
"description": "Number of sessions revoked (forced logout)"
|
|
1498
|
+
}
|
|
1499
|
+
},
|
|
1500
|
+
"required": [
|
|
1501
|
+
"success",
|
|
1502
|
+
"user",
|
|
1503
|
+
"revokedSessions"
|
|
1504
|
+
],
|
|
1505
|
+
"additionalProperties": false,
|
|
1506
|
+
"description": "Response DTO for administrative account locking"
|
|
1507
|
+
},
|
|
1508
|
+
"EnableUserDTO": {
|
|
1509
|
+
"type": "object",
|
|
1510
|
+
"properties": {
|
|
1511
|
+
"sub": {
|
|
1512
|
+
"type": "string",
|
|
1513
|
+
"description": "User UUID (sub) to enable\n\nMust be valid UUID format"
|
|
1514
|
+
}
|
|
1515
|
+
},
|
|
1516
|
+
"required": [
|
|
1517
|
+
"sub"
|
|
1518
|
+
],
|
|
1519
|
+
"additionalProperties": false,
|
|
1520
|
+
"description": "DTO for administrative account unlocking\n\nUnlocks a previously locked user account by clearing lock fields. This reverses the effect of disableUser() or rate-limit lockouts."
|
|
1521
|
+
},
|
|
1522
|
+
"EnableUserResponseDTO": {
|
|
1523
|
+
"type": "object",
|
|
1524
|
+
"properties": {
|
|
1525
|
+
"success": {
|
|
1526
|
+
"type": "boolean",
|
|
1527
|
+
"description": "Unlock success flag"
|
|
1528
|
+
},
|
|
1529
|
+
"user": {
|
|
1530
|
+
"$ref": "#/components/schemas/UserResponseDto",
|
|
1531
|
+
"description": "Sanitized user object with updated lock status"
|
|
1532
|
+
}
|
|
1533
|
+
},
|
|
1534
|
+
"required": [
|
|
1535
|
+
"success",
|
|
1536
|
+
"user"
|
|
1537
|
+
],
|
|
1538
|
+
"additionalProperties": false,
|
|
1539
|
+
"description": "Response DTO for administrative account unlocking"
|
|
1540
|
+
},
|
|
1541
|
+
"ForgotPasswordDTO": {
|
|
1542
|
+
"type": "object",
|
|
1543
|
+
"properties": {
|
|
1544
|
+
"identifier": {
|
|
1545
|
+
"type": "string",
|
|
1546
|
+
"description": "User identifier used to locate the account.\n\nAccepts email, username, or phone depending on application login policy.\n\nSanitization:\n- Trimmed\n- Lowercased when email format detected (contains '@')"
|
|
1547
|
+
},
|
|
1548
|
+
"baseUrl": {
|
|
1549
|
+
"type": "string",
|
|
1550
|
+
"description": "Base URL for building reset link\n\nValidation:\n- Must be valid URL with http:// or https://\n- Supports localhost URLs (e.g., http://localhost:4200)\n- Max 2048 characters\n- Optional\n\nSanitization:\n- Trimmed\n\nWHY: Allows consumer apps to build custom reset UI (e.g., myapp.com/reset-password?token=xxx) Like email verification and admin reset, supports both code AND link delivery",
|
|
1551
|
+
"examples": [
|
|
1552
|
+
"https://myapp.com/reset-password",
|
|
1553
|
+
"http://localhost:4200"
|
|
1554
|
+
]
|
|
1555
|
+
}
|
|
1556
|
+
},
|
|
1557
|
+
"required": [
|
|
1558
|
+
"identifier"
|
|
1559
|
+
],
|
|
1560
|
+
"additionalProperties": false,
|
|
1561
|
+
"description": "Forgot Password DTO\n\nRequest a password reset code for a user account.\n\nSecurity:\n- This endpoint should not reveal whether an account exists.\n- Identifier is sanitized (trimmed, email lowercased when detected)."
|
|
1562
|
+
},
|
|
1563
|
+
"ForgotPasswordResponseDTO": {
|
|
1564
|
+
"type": "object",
|
|
1565
|
+
"properties": {
|
|
1566
|
+
"success": {
|
|
1567
|
+
"type": "boolean",
|
|
1568
|
+
"description": "Always true when request accepted (regardless of account existence)."
|
|
1569
|
+
},
|
|
1570
|
+
"destination": {
|
|
1571
|
+
"type": "string",
|
|
1572
|
+
"description": "Masked delivery destination (email or phone) when available.\n\nExamples:\n- `j***@example.com`\n- `+1***1234`"
|
|
1573
|
+
},
|
|
1574
|
+
"deliveryMedium": {
|
|
1575
|
+
"type": "string",
|
|
1576
|
+
"enum": [
|
|
1577
|
+
"email",
|
|
1578
|
+
"sms"
|
|
1579
|
+
],
|
|
1580
|
+
"description": "Delivery channel used."
|
|
1581
|
+
},
|
|
1582
|
+
"expiresIn": {
|
|
1583
|
+
"type": "number",
|
|
1584
|
+
"description": "Code expiry in seconds."
|
|
1585
|
+
}
|
|
1586
|
+
},
|
|
1587
|
+
"required": [
|
|
1588
|
+
"success"
|
|
1589
|
+
],
|
|
1590
|
+
"additionalProperties": false,
|
|
1591
|
+
"description": "Forgot Password Response DTO\n\nResponse for a password reset request.\n\nSecurity:\n- `success` should be true even when the identifier does not map to any user, to prevent account enumeration."
|
|
1592
|
+
},
|
|
1593
|
+
"GetAvailableMethodsDTO": {
|
|
1594
|
+
"type": "object",
|
|
1595
|
+
"properties": {
|
|
1596
|
+
"sub": {
|
|
1597
|
+
"type": "string",
|
|
1598
|
+
"description": "User's unique identifier (UUID v4)\n\nValidation:\n- Must be a valid UUID v4 format\n- Matches DB constraint: char(36) or uuid\n\nSanitization:\n- Trimmed\n- Lowercased for consistency",
|
|
1599
|
+
"examples": [
|
|
1600
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
1601
|
+
]
|
|
1602
|
+
}
|
|
1603
|
+
},
|
|
1604
|
+
"required": [
|
|
1605
|
+
"sub"
|
|
1606
|
+
],
|
|
1607
|
+
"additionalProperties": false,
|
|
1608
|
+
"description": "DTO for getting available MFA methods"
|
|
1609
|
+
},
|
|
1610
|
+
"GetAvailableMethodsResponseDTO": {
|
|
1611
|
+
"type": "object",
|
|
1612
|
+
"properties": {
|
|
1613
|
+
"availableMethods": {
|
|
1614
|
+
"type": "array",
|
|
1615
|
+
"items": {
|
|
1616
|
+
"type": "string"
|
|
1617
|
+
},
|
|
1618
|
+
"description": "Array of available method names",
|
|
1619
|
+
"examples": [
|
|
1620
|
+
[
|
|
1621
|
+
"totp",
|
|
1622
|
+
"sms",
|
|
1623
|
+
"passkey",
|
|
1624
|
+
"email"
|
|
1625
|
+
]
|
|
1626
|
+
]
|
|
1627
|
+
}
|
|
1628
|
+
},
|
|
1629
|
+
"required": [
|
|
1630
|
+
"availableMethods"
|
|
1631
|
+
],
|
|
1632
|
+
"additionalProperties": false,
|
|
1633
|
+
"description": "Response DTO for available MFA methods"
|
|
1634
|
+
},
|
|
1635
|
+
"GetChallengeDataDTO": {
|
|
1636
|
+
"type": "object",
|
|
1637
|
+
"properties": {
|
|
1638
|
+
"session": {
|
|
1639
|
+
"type": "string",
|
|
1640
|
+
"description": "Challenge session token (UUID v4)\n\nValidation:\n- Must be a valid UUID v4 format\n- Generated using randomUUID() in challenge service\n- Matches DB constraint: varchar(255) but UUID format enforced\n\nSanitization:\n- Trimmed\n- Lowercased for consistency",
|
|
1641
|
+
"examples": [
|
|
1642
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
1643
|
+
]
|
|
1644
|
+
},
|
|
1645
|
+
"method": {
|
|
1646
|
+
"$ref": "#/components/schemas/MFAChallengeMethod",
|
|
1647
|
+
"description": "MFA method requiring challenge data\n\nValidation:\n- Must be 'passkey' (WebAuthn options), 'sms' (sends code), or 'email' (sends code)"
|
|
1648
|
+
}
|
|
1649
|
+
},
|
|
1650
|
+
"required": [
|
|
1651
|
+
"session",
|
|
1652
|
+
"method"
|
|
1653
|
+
],
|
|
1654
|
+
"additionalProperties": false,
|
|
1655
|
+
"description": "DTO for getting MFA challenge data"
|
|
1656
|
+
},
|
|
1657
|
+
"MFAChallengeMethod": {
|
|
1658
|
+
"type": "string",
|
|
1659
|
+
"enum": [
|
|
1660
|
+
"passkey",
|
|
1661
|
+
"sms",
|
|
1662
|
+
"email"
|
|
1663
|
+
],
|
|
1664
|
+
"description": "MFA method enum for challenge data Supports passkey (WebAuthn options), SMS (sends code), and Email (sends code)"
|
|
1665
|
+
},
|
|
1666
|
+
"GetChallengeDataResponseDTO": {
|
|
1667
|
+
"type": "object",
|
|
1668
|
+
"properties": {
|
|
1669
|
+
"challengeData": {
|
|
1670
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E",
|
|
1671
|
+
"description": "Provider-specific challenge data\n\nType varies by method:\n- Passkey: WebAuthn public key options object Structure: { publicKey: { challenge: string, allowCredentials: [...], ... } }\n- SMS: Masked phone number string (e.g., '***-***-1234')\n- Email: Masked email address string (e.g., 'u***r@example.com')\n\nNote: Type is `Record<string, unknown>` which accommodates both object and string types. Frontend should check `typeof challengeData === 'string'` to determine if it's SMS/Email (string) or Passkey (object)."
|
|
1672
|
+
}
|
|
1673
|
+
},
|
|
1674
|
+
"required": [
|
|
1675
|
+
"challengeData"
|
|
1676
|
+
],
|
|
1677
|
+
"additionalProperties": false,
|
|
1678
|
+
"description": "Response DTO for challenge data"
|
|
1679
|
+
},
|
|
1680
|
+
"GetClientInfoResponseDTO": {
|
|
1681
|
+
"type": "object",
|
|
1682
|
+
"properties": {
|
|
1683
|
+
"ipAddress": {
|
|
1684
|
+
"type": "string",
|
|
1685
|
+
"description": "Client IP address\n\nExtracted from X-Forwarded-For, CF-Connecting-IP, etc. Automatically handles proxies and load balancers. Returns 'unknown' if called outside request context."
|
|
1686
|
+
},
|
|
1687
|
+
"userAgent": {
|
|
1688
|
+
"type": "string",
|
|
1689
|
+
"description": "User agent string from the request\n\nReturns 'unknown' if called outside request context."
|
|
1690
|
+
},
|
|
1691
|
+
"deviceToken": {
|
|
1692
|
+
"type": "string",
|
|
1693
|
+
"description": "Device token for trusted device feature\n\nExtracted from cookie (nauth_device_token) or header (X-Device-Token). Optional - only present if device token exists."
|
|
1694
|
+
},
|
|
1695
|
+
"deviceName": {
|
|
1696
|
+
"type": "string",
|
|
1697
|
+
"description": "Optional device name (if provided by client)"
|
|
1698
|
+
},
|
|
1699
|
+
"deviceType": {
|
|
1700
|
+
"type": "string",
|
|
1701
|
+
"enum": [
|
|
1702
|
+
"mobile",
|
|
1703
|
+
"desktop",
|
|
1704
|
+
"tablet"
|
|
1705
|
+
],
|
|
1706
|
+
"description": "Optional device type (if provided by client)"
|
|
1707
|
+
},
|
|
1708
|
+
"ipCountry": {
|
|
1709
|
+
"type": "string",
|
|
1710
|
+
"description": "Optional IP country (from geolocation, if available)"
|
|
1711
|
+
},
|
|
1712
|
+
"ipCity": {
|
|
1713
|
+
"type": "string",
|
|
1714
|
+
"description": "Optional IP city (from geolocation, if available)"
|
|
1715
|
+
},
|
|
1716
|
+
"ipLatitude": {
|
|
1717
|
+
"type": "number",
|
|
1718
|
+
"description": "Optional IP latitude (from geolocation, if available) Used for impossible travel detection"
|
|
1719
|
+
},
|
|
1720
|
+
"ipLongitude": {
|
|
1721
|
+
"type": "number",
|
|
1722
|
+
"description": "Optional IP longitude (from geolocation, if available) Used for impossible travel detection"
|
|
1723
|
+
},
|
|
1724
|
+
"platform": {
|
|
1725
|
+
"type": "string",
|
|
1726
|
+
"description": "Platform extracted from user agent\n\nExamples: \"iOS\", \"Android\", \"Windows\", \"macOS\""
|
|
1727
|
+
},
|
|
1728
|
+
"browser": {
|
|
1729
|
+
"type": "string",
|
|
1730
|
+
"description": "Browser extracted from user agent\n\nExamples: \"Chrome\", \"Safari\", \"Firefox\""
|
|
1731
|
+
},
|
|
1732
|
+
"sessionId": {
|
|
1733
|
+
"type": "number",
|
|
1734
|
+
"description": "Current session ID (if available from authenticated request)\n\nExtracted from JWT token payload after authentication."
|
|
1735
|
+
},
|
|
1736
|
+
"userId": {
|
|
1737
|
+
"type": "number",
|
|
1738
|
+
"description": "Current user ID (if available from authenticated request)\n\nExtracted from JWT token payload (sub claim) after authentication. Used to identify who performed an action (e.g., for audit trails)."
|
|
1739
|
+
},
|
|
1740
|
+
"sub": {
|
|
1741
|
+
"type": "string",
|
|
1742
|
+
"description": "Current user's sub (UUID, if available from authenticated request). Prefer this over userId for performedBy in audit and mfaExemptGrantedBy."
|
|
1743
|
+
}
|
|
1744
|
+
},
|
|
1745
|
+
"required": [
|
|
1746
|
+
"ipAddress",
|
|
1747
|
+
"userAgent"
|
|
1748
|
+
],
|
|
1749
|
+
"additionalProperties": false,
|
|
1750
|
+
"description": "Response DTO for client information"
|
|
1751
|
+
},
|
|
1752
|
+
"GetDeviceTokenResponseDTO": {
|
|
1753
|
+
"type": "object",
|
|
1754
|
+
"properties": {
|
|
1755
|
+
"deviceToken": {
|
|
1756
|
+
"type": "string",
|
|
1757
|
+
"description": "Device token for trusted device feature\n\nExtracted from cookie (nauth_device_token) or header (X-Device-Token). Optional - undefined if not present."
|
|
1758
|
+
}
|
|
1759
|
+
},
|
|
1760
|
+
"additionalProperties": false,
|
|
1761
|
+
"description": "Response DTO for device token"
|
|
1762
|
+
},
|
|
1763
|
+
"GetIpAddressResponseDTO": {
|
|
1764
|
+
"type": "object",
|
|
1765
|
+
"properties": {
|
|
1766
|
+
"ipAddress": {
|
|
1767
|
+
"type": "string",
|
|
1768
|
+
"description": "Client IP address\n\nExtracted from X-Forwarded-For, CF-Connecting-IP, etc. Returns 'unknown' if called outside request context."
|
|
1769
|
+
}
|
|
1770
|
+
},
|
|
1771
|
+
"required": [
|
|
1772
|
+
"ipAddress"
|
|
1773
|
+
],
|
|
1774
|
+
"additionalProperties": false,
|
|
1775
|
+
"description": "Response DTO for IP address"
|
|
1776
|
+
},
|
|
1777
|
+
"GetLinkedAccountsDTO": {
|
|
1778
|
+
"type": "object",
|
|
1779
|
+
"additionalProperties": false,
|
|
1780
|
+
"description": "DTO for getting linked social accounts\n\nSecurity:\n- User ID validated as UUID v4"
|
|
1781
|
+
},
|
|
1782
|
+
"GetLinkedAccountsResponseDTO": {
|
|
1783
|
+
"type": "object",
|
|
1784
|
+
"properties": {
|
|
1785
|
+
"accounts": {
|
|
1786
|
+
"type": "array",
|
|
1787
|
+
"items": {
|
|
1788
|
+
"type": "object",
|
|
1789
|
+
"properties": {
|
|
1790
|
+
"provider": {
|
|
1791
|
+
"type": "string"
|
|
1792
|
+
},
|
|
1793
|
+
"providerEmail": {
|
|
1794
|
+
"type": "string"
|
|
1795
|
+
},
|
|
1796
|
+
"linkedAt": {
|
|
1797
|
+
"type": "string",
|
|
1798
|
+
"format": "date-time"
|
|
1799
|
+
},
|
|
1800
|
+
"lastUsedAt": {
|
|
1801
|
+
"type": "string",
|
|
1802
|
+
"format": "date-time"
|
|
1803
|
+
}
|
|
1804
|
+
},
|
|
1805
|
+
"required": [
|
|
1806
|
+
"provider",
|
|
1807
|
+
"linkedAt"
|
|
1808
|
+
],
|
|
1809
|
+
"additionalProperties": false
|
|
1810
|
+
},
|
|
1811
|
+
"description": "Array of linked social accounts"
|
|
1812
|
+
}
|
|
1813
|
+
},
|
|
1814
|
+
"required": [
|
|
1815
|
+
"accounts"
|
|
1816
|
+
],
|
|
1817
|
+
"additionalProperties": false,
|
|
1818
|
+
"description": "Response DTO for getLinkedAccounts"
|
|
1819
|
+
},
|
|
1820
|
+
"GetMFAStatusResponseDTO": {
|
|
1821
|
+
"type": "object",
|
|
1822
|
+
"properties": {
|
|
1823
|
+
"enabled": {
|
|
1824
|
+
"type": "boolean",
|
|
1825
|
+
"description": "Whether MFA is enabled for the user"
|
|
1826
|
+
},
|
|
1827
|
+
"required": {
|
|
1828
|
+
"type": "boolean",
|
|
1829
|
+
"description": "Whether MFA is required (enabled and has configured devices)"
|
|
1830
|
+
},
|
|
1831
|
+
"configuredMethods": {
|
|
1832
|
+
"type": "array",
|
|
1833
|
+
"items": {
|
|
1834
|
+
"$ref": "#/components/schemas/MFADeviceMethod"
|
|
1835
|
+
},
|
|
1836
|
+
"description": "Array of configured MFA device methods"
|
|
1837
|
+
},
|
|
1838
|
+
"availableMethods": {
|
|
1839
|
+
"type": "array",
|
|
1840
|
+
"items": {
|
|
1841
|
+
"type": "string"
|
|
1842
|
+
},
|
|
1843
|
+
"description": "Array of available MFA methods that can be set up"
|
|
1844
|
+
},
|
|
1845
|
+
"hasBackupCodes": {
|
|
1846
|
+
"type": "boolean",
|
|
1847
|
+
"description": "Whether user has backup codes"
|
|
1848
|
+
},
|
|
1849
|
+
"preferredMethod": {
|
|
1850
|
+
"$ref": "#/components/schemas/MFADeviceMethod",
|
|
1851
|
+
"description": "Preferred MFA method (if set)"
|
|
1852
|
+
},
|
|
1853
|
+
"mfaExempt": {
|
|
1854
|
+
"type": "boolean",
|
|
1855
|
+
"description": "Whether user is exempt from MFA requirements"
|
|
1856
|
+
},
|
|
1857
|
+
"mfaExemptReason": {
|
|
1858
|
+
"type": [
|
|
1859
|
+
"string",
|
|
1860
|
+
"null"
|
|
1861
|
+
],
|
|
1862
|
+
"description": "Reason for MFA exemption (if exempt)"
|
|
1863
|
+
},
|
|
1864
|
+
"mfaExemptGrantedAt": {
|
|
1865
|
+
"anyOf": [
|
|
1866
|
+
{
|
|
1867
|
+
"type": "string",
|
|
1868
|
+
"format": "date-time"
|
|
1869
|
+
},
|
|
1870
|
+
{
|
|
1871
|
+
"type": "null"
|
|
1872
|
+
}
|
|
1873
|
+
],
|
|
1874
|
+
"description": "Date when MFA exemption was granted (if exempt)"
|
|
1875
|
+
}
|
|
1876
|
+
},
|
|
1877
|
+
"required": [
|
|
1878
|
+
"enabled",
|
|
1879
|
+
"required",
|
|
1880
|
+
"configuredMethods",
|
|
1881
|
+
"availableMethods",
|
|
1882
|
+
"hasBackupCodes",
|
|
1883
|
+
"mfaExempt",
|
|
1884
|
+
"mfaExemptReason",
|
|
1885
|
+
"mfaExemptGrantedAt"
|
|
1886
|
+
],
|
|
1887
|
+
"additionalProperties": false,
|
|
1888
|
+
"description": "Response DTO for MFA status\n\nReturned by MFAService.getMfaStatus() (user self-service) and MFAService.adminGetMfaStatus() (admin operation)."
|
|
1889
|
+
},
|
|
1890
|
+
"GetSessionIdResponseDTO": {
|
|
1891
|
+
"type": "object",
|
|
1892
|
+
"properties": {
|
|
1893
|
+
"sessionId": {
|
|
1894
|
+
"type": "number",
|
|
1895
|
+
"description": "Current session ID (if available from authenticated request)\n\nExtracted from JWT token payload after authentication. Optional - undefined if not available."
|
|
1896
|
+
}
|
|
1897
|
+
},
|
|
1898
|
+
"additionalProperties": false,
|
|
1899
|
+
"description": "Response DTO for session ID"
|
|
1900
|
+
},
|
|
1901
|
+
"GetSetupDataDTO": {
|
|
1902
|
+
"type": "object",
|
|
1903
|
+
"properties": {
|
|
1904
|
+
"session": {
|
|
1905
|
+
"type": "string",
|
|
1906
|
+
"description": "Challenge session token (UUID v4)\n\nValidation:\n- Must be a valid UUID v4 format\n- Generated using randomUUID() in challenge service\n- Matches DB constraint: varchar(255) but UUID format enforced\n\nSanitization:\n- Trimmed\n- Lowercased for consistency",
|
|
1907
|
+
"examples": [
|
|
1908
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
1909
|
+
]
|
|
1910
|
+
},
|
|
1911
|
+
"method": {
|
|
1912
|
+
"$ref": "#/components/schemas/MFAMethod",
|
|
1913
|
+
"description": "MFA method to set up\n\nValidation:\n- Must be one of: sms, email, totp, passkey"
|
|
1914
|
+
},
|
|
1915
|
+
"setupData": {
|
|
1916
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E",
|
|
1917
|
+
"description": "Optional provider-specific setup data\n\nValidation:\n- Must be an object if provided\n- Structure validated by MFA provider services"
|
|
1918
|
+
}
|
|
1919
|
+
},
|
|
1920
|
+
"required": [
|
|
1921
|
+
"session",
|
|
1922
|
+
"method"
|
|
1923
|
+
],
|
|
1924
|
+
"additionalProperties": false,
|
|
1925
|
+
"description": "DTO for getting MFA setup data"
|
|
1926
|
+
},
|
|
1927
|
+
"MFAMethod": {
|
|
1928
|
+
"type": "string",
|
|
1929
|
+
"enum": [
|
|
1930
|
+
"totp",
|
|
1931
|
+
"sms",
|
|
1932
|
+
"email",
|
|
1933
|
+
"passkey",
|
|
1934
|
+
"backup"
|
|
1935
|
+
],
|
|
1936
|
+
"description": "All supported MFA methods\n\nUse this enum instead of string literals throughout the codebase."
|
|
1937
|
+
},
|
|
1938
|
+
"GetSetupDataResponseDTO": {
|
|
1939
|
+
"type": "object",
|
|
1940
|
+
"properties": {
|
|
1941
|
+
"setupData": {
|
|
1942
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E",
|
|
1943
|
+
"description": "Provider-specific setup data\n\nStructure varies by method:\n- TOTP: { secret: string, qrCode: string, manualEntryKey: string }\n- SMS: { maskedPhone: string }\n- Email: { maskedEmail: string }\n- Passkey: WebAuthn registration options"
|
|
1944
|
+
}
|
|
1945
|
+
},
|
|
1946
|
+
"required": [
|
|
1947
|
+
"setupData"
|
|
1948
|
+
],
|
|
1949
|
+
"additionalProperties": false,
|
|
1950
|
+
"description": "Response DTO for setup data"
|
|
1951
|
+
},
|
|
1952
|
+
"GetUserAgentResponseDTO": {
|
|
1953
|
+
"type": "object",
|
|
1954
|
+
"properties": {
|
|
1955
|
+
"userAgent": {
|
|
1956
|
+
"type": "string",
|
|
1957
|
+
"description": "User agent string from the request\n\nReturns 'unknown' if called outside request context."
|
|
1958
|
+
}
|
|
1959
|
+
},
|
|
1960
|
+
"required": [
|
|
1961
|
+
"userAgent"
|
|
1962
|
+
],
|
|
1963
|
+
"additionalProperties": false,
|
|
1964
|
+
"description": "Response DTO for user agent"
|
|
1965
|
+
},
|
|
1966
|
+
"GetUserAuthHistoryDTO": {
|
|
1967
|
+
"type": "object",
|
|
1968
|
+
"properties": {
|
|
1969
|
+
"page": {
|
|
1970
|
+
"type": "number",
|
|
1971
|
+
"description": "Page number (1-indexed)",
|
|
1972
|
+
"default": 1
|
|
1973
|
+
},
|
|
1974
|
+
"limit": {
|
|
1975
|
+
"type": "number",
|
|
1976
|
+
"description": "Number of records per page",
|
|
1977
|
+
"default": 50
|
|
1978
|
+
},
|
|
1979
|
+
"startDate": {
|
|
1980
|
+
"type": "string",
|
|
1981
|
+
"format": "date-time",
|
|
1982
|
+
"description": "Filter events from this date onwards"
|
|
1983
|
+
},
|
|
1984
|
+
"endDate": {
|
|
1985
|
+
"type": "string",
|
|
1986
|
+
"format": "date-time",
|
|
1987
|
+
"description": "Filter events up to this date"
|
|
1988
|
+
},
|
|
1989
|
+
"eventTypes": {
|
|
1990
|
+
"type": "array",
|
|
1991
|
+
"items": {
|
|
1992
|
+
"$ref": "#/components/schemas/AuthAuditEventType"
|
|
1993
|
+
},
|
|
1994
|
+
"description": "Filter by specific event types\n\nIf provided, only events matching these types will be returned."
|
|
1995
|
+
},
|
|
1996
|
+
"eventStatus": {
|
|
1997
|
+
"type": "array",
|
|
1998
|
+
"items": {
|
|
1999
|
+
"$ref": "#/components/schemas/AuthAuditEventStatus"
|
|
2000
|
+
},
|
|
2001
|
+
"description": "Filter by event status\n\nIf provided, only events matching these statuses will be returned."
|
|
2002
|
+
}
|
|
2003
|
+
},
|
|
2004
|
+
"additionalProperties": false,
|
|
2005
|
+
"description": "Request DTO for getting user authentication history (user self-service)\n\nUser self-service DTO - no userSub field. Service gets user from authenticated context."
|
|
2006
|
+
},
|
|
2007
|
+
"GetUserAuthHistoryResponseDTO": {
|
|
2008
|
+
"type": "object",
|
|
2009
|
+
"properties": {
|
|
2010
|
+
"data": {
|
|
2011
|
+
"type": "array",
|
|
2012
|
+
"items": {
|
|
2013
|
+
"$ref": "#/components/schemas/IAuthAudit"
|
|
2014
|
+
},
|
|
2015
|
+
"description": "Array of audit records"
|
|
2016
|
+
},
|
|
2017
|
+
"total": {
|
|
2018
|
+
"type": "number",
|
|
2019
|
+
"description": "Total number of records matching the query"
|
|
2020
|
+
},
|
|
2021
|
+
"page": {
|
|
2022
|
+
"type": "number",
|
|
2023
|
+
"description": "Current page number"
|
|
2024
|
+
},
|
|
2025
|
+
"limit": {
|
|
2026
|
+
"type": "number",
|
|
2027
|
+
"description": "Number of records per page"
|
|
2028
|
+
},
|
|
2029
|
+
"totalPages": {
|
|
2030
|
+
"type": "number",
|
|
2031
|
+
"description": "Total number of pages"
|
|
2032
|
+
}
|
|
2033
|
+
},
|
|
2034
|
+
"required": [
|
|
2035
|
+
"data",
|
|
2036
|
+
"total",
|
|
2037
|
+
"page",
|
|
2038
|
+
"limit",
|
|
2039
|
+
"totalPages"
|
|
2040
|
+
],
|
|
2041
|
+
"additionalProperties": false,
|
|
2042
|
+
"description": "Response DTO for paginated user authentication history"
|
|
2043
|
+
},
|
|
2044
|
+
"IAuthAudit": {
|
|
2045
|
+
"type": "object",
|
|
2046
|
+
"properties": {
|
|
2047
|
+
"id": {
|
|
2048
|
+
"type": "number"
|
|
2049
|
+
},
|
|
2050
|
+
"userId": {
|
|
2051
|
+
"type": "number"
|
|
2052
|
+
},
|
|
2053
|
+
"eventType": {
|
|
2054
|
+
"type": "string"
|
|
2055
|
+
},
|
|
2056
|
+
"eventStatus": {
|
|
2057
|
+
"type": "string",
|
|
2058
|
+
"enum": [
|
|
2059
|
+
"SUCCESS",
|
|
2060
|
+
"FAILURE",
|
|
2061
|
+
"INFO",
|
|
2062
|
+
"SUSPICIOUS"
|
|
2063
|
+
]
|
|
2064
|
+
},
|
|
2065
|
+
"riskFactor": {
|
|
2066
|
+
"type": [
|
|
2067
|
+
"number",
|
|
2068
|
+
"null"
|
|
2069
|
+
]
|
|
2070
|
+
},
|
|
2071
|
+
"riskFactors": {
|
|
2072
|
+
"anyOf": [
|
|
2073
|
+
{
|
|
2074
|
+
"type": "array",
|
|
2075
|
+
"items": {
|
|
2076
|
+
"type": "string"
|
|
2077
|
+
}
|
|
2078
|
+
},
|
|
2079
|
+
{
|
|
2080
|
+
"type": "null"
|
|
2081
|
+
}
|
|
2082
|
+
]
|
|
2083
|
+
},
|
|
2084
|
+
"adaptiveMfaTriggered": {
|
|
2085
|
+
"type": [
|
|
2086
|
+
"boolean",
|
|
2087
|
+
"null"
|
|
2088
|
+
]
|
|
2089
|
+
},
|
|
2090
|
+
"ipAddress": {
|
|
2091
|
+
"type": [
|
|
2092
|
+
"string",
|
|
2093
|
+
"null"
|
|
2094
|
+
]
|
|
2095
|
+
},
|
|
2096
|
+
"ipCountry": {
|
|
2097
|
+
"type": [
|
|
2098
|
+
"string",
|
|
2099
|
+
"null"
|
|
2100
|
+
]
|
|
2101
|
+
},
|
|
2102
|
+
"ipCity": {
|
|
2103
|
+
"type": [
|
|
2104
|
+
"string",
|
|
2105
|
+
"null"
|
|
2106
|
+
]
|
|
2107
|
+
},
|
|
2108
|
+
"userAgent": {
|
|
2109
|
+
"type": [
|
|
2110
|
+
"string",
|
|
2111
|
+
"null"
|
|
2112
|
+
]
|
|
2113
|
+
},
|
|
2114
|
+
"platform": {
|
|
2115
|
+
"type": [
|
|
2116
|
+
"string",
|
|
2117
|
+
"null"
|
|
2118
|
+
]
|
|
2119
|
+
},
|
|
2120
|
+
"browser": {
|
|
2121
|
+
"type": [
|
|
2122
|
+
"string",
|
|
2123
|
+
"null"
|
|
2124
|
+
]
|
|
2125
|
+
},
|
|
2126
|
+
"deviceId": {
|
|
2127
|
+
"type": [
|
|
2128
|
+
"string",
|
|
2129
|
+
"null"
|
|
2130
|
+
]
|
|
2131
|
+
},
|
|
2132
|
+
"deviceName": {
|
|
2133
|
+
"type": [
|
|
2134
|
+
"string",
|
|
2135
|
+
"null"
|
|
2136
|
+
]
|
|
2137
|
+
},
|
|
2138
|
+
"deviceType": {
|
|
2139
|
+
"type": [
|
|
2140
|
+
"string",
|
|
2141
|
+
"null"
|
|
2142
|
+
]
|
|
2143
|
+
},
|
|
2144
|
+
"sessionId": {
|
|
2145
|
+
"type": [
|
|
2146
|
+
"number",
|
|
2147
|
+
"null"
|
|
2148
|
+
]
|
|
2149
|
+
},
|
|
2150
|
+
"challengeSessionId": {
|
|
2151
|
+
"type": [
|
|
2152
|
+
"number",
|
|
2153
|
+
"null"
|
|
2154
|
+
]
|
|
2155
|
+
},
|
|
2156
|
+
"authMethod": {
|
|
2157
|
+
"type": [
|
|
2158
|
+
"string",
|
|
2159
|
+
"null"
|
|
2160
|
+
]
|
|
2161
|
+
},
|
|
2162
|
+
"performedBy": {
|
|
2163
|
+
"type": [
|
|
2164
|
+
"string",
|
|
2165
|
+
"null"
|
|
2166
|
+
]
|
|
2167
|
+
},
|
|
2168
|
+
"reason": {
|
|
2169
|
+
"type": [
|
|
2170
|
+
"string",
|
|
2171
|
+
"null"
|
|
2172
|
+
]
|
|
2173
|
+
},
|
|
2174
|
+
"description": {
|
|
2175
|
+
"type": [
|
|
2176
|
+
"string",
|
|
2177
|
+
"null"
|
|
2178
|
+
]
|
|
2179
|
+
},
|
|
2180
|
+
"metadata": {
|
|
2181
|
+
"anyOf": [
|
|
2182
|
+
{
|
|
2183
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E"
|
|
2184
|
+
},
|
|
2185
|
+
{
|
|
2186
|
+
"type": "null"
|
|
2187
|
+
}
|
|
2188
|
+
]
|
|
2189
|
+
},
|
|
2190
|
+
"createdAt": {
|
|
2191
|
+
"type": "string",
|
|
2192
|
+
"format": "date-time"
|
|
2193
|
+
}
|
|
2194
|
+
},
|
|
2195
|
+
"required": [
|
|
2196
|
+
"id",
|
|
2197
|
+
"userId",
|
|
2198
|
+
"eventType",
|
|
2199
|
+
"eventStatus",
|
|
2200
|
+
"createdAt"
|
|
2201
|
+
],
|
|
2202
|
+
"additionalProperties": false,
|
|
2203
|
+
"description": "Authentication Audit Entity Interface\n\nAudit trail record for authentication and security events"
|
|
2204
|
+
},
|
|
2205
|
+
"GetUserByEmailDTO": {
|
|
2206
|
+
"type": "object",
|
|
2207
|
+
"properties": {
|
|
2208
|
+
"email": {
|
|
2209
|
+
"type": "string",
|
|
2210
|
+
"description": "Email address to search for\n\nValidation:\n- Must be a valid email format\n- Max 255 characters (matches DB constraint)\n\nSanitization:\n- Trimmed\n- Lowercased for consistency",
|
|
2211
|
+
"examples": [
|
|
2212
|
+
"user@example.com"
|
|
2213
|
+
]
|
|
2214
|
+
},
|
|
2215
|
+
"requireEmailVerified": {
|
|
2216
|
+
"type": "boolean",
|
|
2217
|
+
"description": "Only return user if email is verified\n\nValidation:\n- Must be a boolean if present\n- Default: false",
|
|
2218
|
+
"examples": [
|
|
2219
|
+
true
|
|
2220
|
+
]
|
|
2221
|
+
}
|
|
2222
|
+
},
|
|
2223
|
+
"required": [
|
|
2224
|
+
"email"
|
|
2225
|
+
],
|
|
2226
|
+
"additionalProperties": false,
|
|
2227
|
+
"description": "Request DTO for getting user by email"
|
|
2228
|
+
},
|
|
2229
|
+
"GetUserByIdDTO": {
|
|
2230
|
+
"type": "object",
|
|
2231
|
+
"properties": {
|
|
2232
|
+
"sub": {
|
|
2233
|
+
"type": "string",
|
|
2234
|
+
"description": "User's unique identifier (UUID v4)\n\nValidation:\n- Must be a valid UUID v4 format\n- Matches DB constraint: char(36) or uuid\n\nSanitization:\n- Trimmed\n- Lowercased for consistency",
|
|
2235
|
+
"examples": [
|
|
2236
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
2237
|
+
]
|
|
2238
|
+
}
|
|
2239
|
+
},
|
|
2240
|
+
"required": [
|
|
2241
|
+
"sub"
|
|
2242
|
+
],
|
|
2243
|
+
"additionalProperties": false,
|
|
2244
|
+
"description": "Request DTO for getting user by ID"
|
|
2245
|
+
},
|
|
2246
|
+
"GetUserDevicesDTO": {
|
|
2247
|
+
"type": "object",
|
|
2248
|
+
"additionalProperties": false,
|
|
2249
|
+
"description": "DTO for getting user MFA devices\n\nUser self-service DTO - no sub field. Service gets user from authenticated context."
|
|
2250
|
+
},
|
|
2251
|
+
"GetUserDevicesResponseDTO": {
|
|
2252
|
+
"type": "object",
|
|
2253
|
+
"properties": {
|
|
2254
|
+
"devices": {
|
|
2255
|
+
"type": "array",
|
|
2256
|
+
"items": {
|
|
2257
|
+
"$ref": "#/components/schemas/IMFADevice"
|
|
2258
|
+
},
|
|
2259
|
+
"description": "Array of user's MFA devices"
|
|
2260
|
+
}
|
|
2261
|
+
},
|
|
2262
|
+
"required": [
|
|
2263
|
+
"devices"
|
|
2264
|
+
],
|
|
2265
|
+
"additionalProperties": false,
|
|
2266
|
+
"description": "Response DTO for user MFA devices"
|
|
2267
|
+
},
|
|
2268
|
+
"IMFADevice": {
|
|
2269
|
+
"type": "object",
|
|
2270
|
+
"properties": {
|
|
2271
|
+
"id": {
|
|
2272
|
+
"type": "number"
|
|
2273
|
+
},
|
|
2274
|
+
"userId": {
|
|
2275
|
+
"type": "number"
|
|
2276
|
+
},
|
|
2277
|
+
"type": {
|
|
2278
|
+
"$ref": "#/components/schemas/MFADeviceMethod"
|
|
2279
|
+
},
|
|
2280
|
+
"name": {
|
|
2281
|
+
"type": "string"
|
|
2282
|
+
},
|
|
2283
|
+
"secret": {
|
|
2284
|
+
"type": [
|
|
2285
|
+
"string",
|
|
2286
|
+
"null"
|
|
2287
|
+
]
|
|
2288
|
+
},
|
|
2289
|
+
"credentialId": {
|
|
2290
|
+
"type": [
|
|
2291
|
+
"string",
|
|
2292
|
+
"null"
|
|
2293
|
+
]
|
|
2294
|
+
},
|
|
2295
|
+
"publicKey": {
|
|
2296
|
+
"type": [
|
|
2297
|
+
"string",
|
|
2298
|
+
"null"
|
|
2299
|
+
]
|
|
2300
|
+
},
|
|
2301
|
+
"counter": {
|
|
2302
|
+
"type": [
|
|
2303
|
+
"number",
|
|
2304
|
+
"null"
|
|
2305
|
+
]
|
|
2306
|
+
},
|
|
2307
|
+
"transports": {
|
|
2308
|
+
"anyOf": [
|
|
2309
|
+
{
|
|
2310
|
+
"type": "array",
|
|
2311
|
+
"items": {
|
|
2312
|
+
"type": "string"
|
|
2313
|
+
}
|
|
2314
|
+
},
|
|
2315
|
+
{
|
|
2316
|
+
"type": "null"
|
|
2317
|
+
}
|
|
2318
|
+
]
|
|
2319
|
+
},
|
|
2320
|
+
"phoneNumber": {
|
|
2321
|
+
"type": [
|
|
2322
|
+
"string",
|
|
2323
|
+
"null"
|
|
2324
|
+
]
|
|
2325
|
+
},
|
|
2326
|
+
"email": {
|
|
2327
|
+
"type": [
|
|
2328
|
+
"string",
|
|
2329
|
+
"null"
|
|
2330
|
+
]
|
|
2331
|
+
},
|
|
2332
|
+
"isPrimary": {
|
|
2333
|
+
"type": "boolean"
|
|
2334
|
+
},
|
|
2335
|
+
"isActive": {
|
|
2336
|
+
"type": "boolean"
|
|
2337
|
+
},
|
|
2338
|
+
"lastUsedAt": {
|
|
2339
|
+
"anyOf": [
|
|
2340
|
+
{
|
|
2341
|
+
"type": "string",
|
|
2342
|
+
"format": "date-time"
|
|
2343
|
+
},
|
|
2344
|
+
{
|
|
2345
|
+
"type": "null"
|
|
2346
|
+
}
|
|
2347
|
+
]
|
|
2348
|
+
},
|
|
2349
|
+
"createdAt": {
|
|
2350
|
+
"type": "string",
|
|
2351
|
+
"format": "date-time"
|
|
2352
|
+
}
|
|
2353
|
+
},
|
|
2354
|
+
"required": [
|
|
2355
|
+
"id",
|
|
2356
|
+
"userId",
|
|
2357
|
+
"type",
|
|
2358
|
+
"name",
|
|
2359
|
+
"secret",
|
|
2360
|
+
"credentialId",
|
|
2361
|
+
"publicKey",
|
|
2362
|
+
"counter",
|
|
2363
|
+
"transports",
|
|
2364
|
+
"isActive",
|
|
2365
|
+
"lastUsedAt",
|
|
2366
|
+
"createdAt"
|
|
2367
|
+
],
|
|
2368
|
+
"additionalProperties": false
|
|
2369
|
+
},
|
|
2370
|
+
"GetUserSessionsDTO": {
|
|
2371
|
+
"type": "object",
|
|
2372
|
+
"properties": {
|
|
2373
|
+
"sub": {
|
|
2374
|
+
"type": "string",
|
|
2375
|
+
"description": "User sub (UUID)"
|
|
2376
|
+
}
|
|
2377
|
+
},
|
|
2378
|
+
"required": [
|
|
2379
|
+
"sub"
|
|
2380
|
+
],
|
|
2381
|
+
"additionalProperties": false,
|
|
2382
|
+
"description": "DTO for getting user sessions"
|
|
2383
|
+
},
|
|
2384
|
+
"GetUserSessionsResponseDTO": {
|
|
2385
|
+
"type": "object",
|
|
2386
|
+
"properties": {
|
|
2387
|
+
"sessions": {
|
|
2388
|
+
"type": "array",
|
|
2389
|
+
"items": {
|
|
2390
|
+
"$ref": "#/components/schemas/UserSessionInfo"
|
|
2391
|
+
},
|
|
2392
|
+
"description": "Array of user sessions"
|
|
2393
|
+
}
|
|
2394
|
+
},
|
|
2395
|
+
"required": [
|
|
2396
|
+
"sessions"
|
|
2397
|
+
],
|
|
2398
|
+
"additionalProperties": false,
|
|
2399
|
+
"description": "Response DTO for getting user sessions"
|
|
2400
|
+
},
|
|
2401
|
+
"UserSessionInfo": {
|
|
2402
|
+
"type": "object",
|
|
2403
|
+
"properties": {
|
|
2404
|
+
"sessionId": {
|
|
2405
|
+
"type": "string",
|
|
2406
|
+
"description": "Session ID"
|
|
2407
|
+
},
|
|
2408
|
+
"deviceId": {
|
|
2409
|
+
"type": [
|
|
2410
|
+
"string",
|
|
2411
|
+
"null"
|
|
2412
|
+
],
|
|
2413
|
+
"description": "Device ID"
|
|
2414
|
+
},
|
|
2415
|
+
"deviceName": {
|
|
2416
|
+
"type": [
|
|
2417
|
+
"string",
|
|
2418
|
+
"null"
|
|
2419
|
+
],
|
|
2420
|
+
"description": "Device name"
|
|
2421
|
+
},
|
|
2422
|
+
"deviceType": {
|
|
2423
|
+
"type": [
|
|
2424
|
+
"string",
|
|
2425
|
+
"null"
|
|
2426
|
+
],
|
|
2427
|
+
"description": "Device type"
|
|
2428
|
+
},
|
|
2429
|
+
"platform": {
|
|
2430
|
+
"type": [
|
|
2431
|
+
"string",
|
|
2432
|
+
"null"
|
|
2433
|
+
],
|
|
2434
|
+
"description": "Platform"
|
|
2435
|
+
},
|
|
2436
|
+
"browser": {
|
|
2437
|
+
"type": [
|
|
2438
|
+
"string",
|
|
2439
|
+
"null"
|
|
2440
|
+
],
|
|
2441
|
+
"description": "Browser"
|
|
2442
|
+
},
|
|
2443
|
+
"ipAddress": {
|
|
2444
|
+
"type": [
|
|
2445
|
+
"string",
|
|
2446
|
+
"null"
|
|
2447
|
+
],
|
|
2448
|
+
"description": "IP address"
|
|
2449
|
+
},
|
|
2450
|
+
"ipCountry": {
|
|
2451
|
+
"type": [
|
|
2452
|
+
"string",
|
|
2453
|
+
"null"
|
|
2454
|
+
],
|
|
2455
|
+
"description": "IP country"
|
|
2456
|
+
},
|
|
2457
|
+
"ipCity": {
|
|
2458
|
+
"type": [
|
|
2459
|
+
"string",
|
|
2460
|
+
"null"
|
|
2461
|
+
],
|
|
2462
|
+
"description": "IP city"
|
|
2463
|
+
},
|
|
2464
|
+
"lastActivityAt": {
|
|
2465
|
+
"type": "string",
|
|
2466
|
+
"format": "date-time",
|
|
2467
|
+
"description": "Last activity timestamp"
|
|
2468
|
+
},
|
|
2469
|
+
"createdAt": {
|
|
2470
|
+
"type": "string",
|
|
2471
|
+
"format": "date-time",
|
|
2472
|
+
"description": "Session creation timestamp"
|
|
2473
|
+
},
|
|
2474
|
+
"expiresAt": {
|
|
2475
|
+
"type": "string",
|
|
2476
|
+
"format": "date-time",
|
|
2477
|
+
"description": "Session expiration timestamp"
|
|
2478
|
+
},
|
|
2479
|
+
"isRemembered": {
|
|
2480
|
+
"type": "boolean",
|
|
2481
|
+
"description": "Whether session is remembered"
|
|
2482
|
+
},
|
|
2483
|
+
"isCurrent": {
|
|
2484
|
+
"type": "boolean",
|
|
2485
|
+
"description": "Whether this is the current session"
|
|
2486
|
+
},
|
|
2487
|
+
"authMethod": {
|
|
2488
|
+
"type": [
|
|
2489
|
+
"string",
|
|
2490
|
+
"null"
|
|
2491
|
+
],
|
|
2492
|
+
"description": "Authentication method used for this session Examples: 'password', 'social', 'admin', 'admin-social' For social logins, check authProvider for the specific OAuth provider"
|
|
2493
|
+
},
|
|
2494
|
+
"authProvider": {
|
|
2495
|
+
"type": [
|
|
2496
|
+
"string",
|
|
2497
|
+
"null"
|
|
2498
|
+
],
|
|
2499
|
+
"description": "OAuth provider name (only present for social logins) Examples: 'google', 'facebook', 'github', 'apple'"
|
|
2500
|
+
}
|
|
2501
|
+
},
|
|
2502
|
+
"required": [
|
|
2503
|
+
"sessionId",
|
|
2504
|
+
"deviceId",
|
|
2505
|
+
"deviceName",
|
|
2506
|
+
"deviceType",
|
|
2507
|
+
"platform",
|
|
2508
|
+
"browser",
|
|
2509
|
+
"ipAddress",
|
|
2510
|
+
"ipCountry",
|
|
2511
|
+
"ipCity",
|
|
2512
|
+
"lastActivityAt",
|
|
2513
|
+
"createdAt",
|
|
2514
|
+
"expiresAt",
|
|
2515
|
+
"isRemembered",
|
|
2516
|
+
"isCurrent",
|
|
2517
|
+
"authMethod",
|
|
2518
|
+
"authProvider"
|
|
2519
|
+
],
|
|
2520
|
+
"additionalProperties": false,
|
|
2521
|
+
"description": "Session information in user sessions response"
|
|
2522
|
+
},
|
|
2523
|
+
"GetUsersDTO": {
|
|
2524
|
+
"type": "object",
|
|
2525
|
+
"properties": {
|
|
2526
|
+
"page": {
|
|
2527
|
+
"type": "number",
|
|
2528
|
+
"description": "Page number (1-indexed)\n\nDefault: 1"
|
|
2529
|
+
},
|
|
2530
|
+
"limit": {
|
|
2531
|
+
"type": "number",
|
|
2532
|
+
"description": "Number of records per page\n\nDefault: 10, Max: 100"
|
|
2533
|
+
},
|
|
2534
|
+
"email": {
|
|
2535
|
+
"type": "string",
|
|
2536
|
+
"description": "Filter by email address (partial match)\n\nSupports partial matching using LIKE query. Example: \"john\" will match \"john@example.com\", \"johnny@test.com\", etc."
|
|
2537
|
+
},
|
|
2538
|
+
"phone": {
|
|
2539
|
+
"type": "string",
|
|
2540
|
+
"description": "Filter by phone number (partial match)\n\nSupports partial matching using LIKE query. Example: \"+1\" will match \"+14155552671\", \"+12025551234\", etc."
|
|
2541
|
+
},
|
|
2542
|
+
"isEmailVerified": {
|
|
2543
|
+
"type": "boolean",
|
|
2544
|
+
"description": "Filter by email verification status"
|
|
2545
|
+
},
|
|
2546
|
+
"isPhoneVerified": {
|
|
2547
|
+
"type": "boolean",
|
|
2548
|
+
"description": "Filter by phone verification status"
|
|
2549
|
+
},
|
|
2550
|
+
"hasSocialAuth": {
|
|
2551
|
+
"type": "boolean",
|
|
2552
|
+
"description": "Filter by social auth presence"
|
|
2553
|
+
},
|
|
2554
|
+
"isLocked": {
|
|
2555
|
+
"type": "boolean",
|
|
2556
|
+
"description": "Filter by account lock status"
|
|
2557
|
+
},
|
|
2558
|
+
"mfaEnabled": {
|
|
2559
|
+
"type": "boolean",
|
|
2560
|
+
"description": "Filter by MFA enabled status"
|
|
2561
|
+
},
|
|
2562
|
+
"createdAt": {
|
|
2563
|
+
"$ref": "#/components/schemas/DateFilterDTO",
|
|
2564
|
+
"description": "Filter by account creation date\n\nSupports operators: gt, gte, lt, lte, eq"
|
|
2565
|
+
},
|
|
2566
|
+
"updatedAt": {
|
|
2567
|
+
"$ref": "#/components/schemas/DateFilterDTO",
|
|
2568
|
+
"description": "Filter by last update date\n\nSupports operators: gt, gte, lt, lte, eq"
|
|
2569
|
+
},
|
|
2570
|
+
"sortBy": {
|
|
2571
|
+
"type": "string",
|
|
2572
|
+
"enum": [
|
|
2573
|
+
"email",
|
|
2574
|
+
"createdAt",
|
|
2575
|
+
"updatedAt",
|
|
2576
|
+
"username",
|
|
2577
|
+
"phone"
|
|
2578
|
+
],
|
|
2579
|
+
"description": "Field to sort by\n\nDefault: createdAt"
|
|
2580
|
+
},
|
|
2581
|
+
"sortOrder": {
|
|
2582
|
+
"type": "string",
|
|
2583
|
+
"enum": [
|
|
2584
|
+
"ASC",
|
|
2585
|
+
"DESC"
|
|
2586
|
+
],
|
|
2587
|
+
"description": "Sort order\n\nDefault: DESC"
|
|
2588
|
+
}
|
|
2589
|
+
},
|
|
2590
|
+
"additionalProperties": false,
|
|
2591
|
+
"description": "DTO for paginated user listing with advanced filtering\n\nSupports pagination, boolean filters, exact match filters, date filters with operators, and flexible sorting."
|
|
2592
|
+
},
|
|
2593
|
+
"GetUsersResponseDTO": {
|
|
2594
|
+
"type": "object",
|
|
2595
|
+
"properties": {
|
|
2596
|
+
"users": {
|
|
2597
|
+
"type": "array",
|
|
2598
|
+
"items": {
|
|
2599
|
+
"$ref": "#/components/schemas/UserResponseDto"
|
|
2600
|
+
},
|
|
2601
|
+
"description": "Array of sanitized user objects"
|
|
2602
|
+
},
|
|
2603
|
+
"pagination": {
|
|
2604
|
+
"type": "object",
|
|
2605
|
+
"properties": {
|
|
2606
|
+
"page": {
|
|
2607
|
+
"type": "number"
|
|
2608
|
+
},
|
|
2609
|
+
"limit": {
|
|
2610
|
+
"type": "number"
|
|
2611
|
+
},
|
|
2612
|
+
"total": {
|
|
2613
|
+
"type": "number"
|
|
2614
|
+
},
|
|
2615
|
+
"totalPages": {
|
|
2616
|
+
"type": "number"
|
|
2617
|
+
}
|
|
2618
|
+
},
|
|
2619
|
+
"required": [
|
|
2620
|
+
"page",
|
|
2621
|
+
"limit",
|
|
2622
|
+
"total",
|
|
2623
|
+
"totalPages"
|
|
2624
|
+
],
|
|
2625
|
+
"additionalProperties": false,
|
|
2626
|
+
"description": "Pagination metadata"
|
|
2627
|
+
}
|
|
2628
|
+
},
|
|
2629
|
+
"required": [
|
|
2630
|
+
"users",
|
|
2631
|
+
"pagination"
|
|
2632
|
+
],
|
|
2633
|
+
"additionalProperties": false,
|
|
2634
|
+
"description": "Response DTO for paginated user listing"
|
|
2635
|
+
},
|
|
2636
|
+
"HandleCallbackDTO": {
|
|
2637
|
+
"type": "object",
|
|
2638
|
+
"properties": {
|
|
2639
|
+
"code": {
|
|
2640
|
+
"type": "string",
|
|
2641
|
+
"description": "Authorization code from OAuth callback\n\nValidation:\n- Must be non-empty string\n- Max 2000 characters\n\nSanitization:\n- Trimmed"
|
|
2642
|
+
},
|
|
2643
|
+
"state": {
|
|
2644
|
+
"type": "string",
|
|
2645
|
+
"description": "State parameter from OAuth callback (for CSRF validation)\n\nValidation:\n- Must be non-empty string\n- Max 500 characters\n\nSanitization:\n- Trimmed"
|
|
2646
|
+
}
|
|
2647
|
+
},
|
|
2648
|
+
"required": [
|
|
2649
|
+
"code",
|
|
2650
|
+
"state"
|
|
2651
|
+
],
|
|
2652
|
+
"additionalProperties": false,
|
|
2653
|
+
"description": "DTO for handling OAuth callback\n\nUsed when processing OAuth callback from social providers after user authorization.\n\nSecurity:\n- Code validated for length\n- State validated for CSRF protection"
|
|
2654
|
+
},
|
|
2655
|
+
"HasProviderDTO": {
|
|
2656
|
+
"type": "object",
|
|
2657
|
+
"properties": {
|
|
2658
|
+
"methodName": {
|
|
2659
|
+
"type": "string",
|
|
2660
|
+
"description": "Provider method name\n\nValidation:\n- Must be one of: totp, sms, email, passkey\n- Max 50 characters\n\nSanitization:\n- Trimmed and lowercased",
|
|
2661
|
+
"examples": [
|
|
2662
|
+
"totp"
|
|
2663
|
+
]
|
|
2664
|
+
}
|
|
2665
|
+
},
|
|
2666
|
+
"required": [
|
|
2667
|
+
"methodName"
|
|
2668
|
+
],
|
|
2669
|
+
"additionalProperties": false,
|
|
2670
|
+
"description": "DTO for checking if MFA provider is registered"
|
|
2671
|
+
},
|
|
2672
|
+
"HasProviderResponseDTO": {
|
|
2673
|
+
"type": "object",
|
|
2674
|
+
"properties": {
|
|
2675
|
+
"hasProvider": {
|
|
2676
|
+
"type": "boolean",
|
|
2677
|
+
"description": "Whether provider is registered"
|
|
2678
|
+
}
|
|
2679
|
+
},
|
|
2680
|
+
"required": [
|
|
2681
|
+
"hasProvider"
|
|
2682
|
+
],
|
|
2683
|
+
"additionalProperties": false,
|
|
2684
|
+
"description": "Response DTO for has provider check"
|
|
2685
|
+
},
|
|
2686
|
+
"IsTrustedDeviceResponseDTO": {
|
|
2687
|
+
"type": "object",
|
|
2688
|
+
"properties": {
|
|
2689
|
+
"trusted": {
|
|
2690
|
+
"type": "boolean",
|
|
2691
|
+
"description": "Whether the current device is trusted\n\nTrue if the device has a valid trusted device token and trust has not expired. False if no device token exists, device token is invalid, or trust has expired.",
|
|
2692
|
+
"examples": [
|
|
2693
|
+
true
|
|
2694
|
+
]
|
|
2695
|
+
}
|
|
2696
|
+
},
|
|
2697
|
+
"required": [
|
|
2698
|
+
"trusted"
|
|
2699
|
+
],
|
|
2700
|
+
"additionalProperties": false,
|
|
2701
|
+
"description": "Response DTO for checking trusted device status"
|
|
2702
|
+
},
|
|
2703
|
+
"JwtPayload": {
|
|
2704
|
+
"type": "object",
|
|
2705
|
+
"properties": {
|
|
2706
|
+
"sub": {
|
|
2707
|
+
"type": "string",
|
|
2708
|
+
"description": "User ID (subject)"
|
|
2709
|
+
},
|
|
2710
|
+
"email": {
|
|
2711
|
+
"type": "string",
|
|
2712
|
+
"description": "User email"
|
|
2713
|
+
},
|
|
2714
|
+
"type": {
|
|
2715
|
+
"type": "string",
|
|
2716
|
+
"enum": [
|
|
2717
|
+
"access",
|
|
2718
|
+
"refresh"
|
|
2719
|
+
],
|
|
2720
|
+
"description": "Token type - always 'access' for access tokens"
|
|
2721
|
+
},
|
|
2722
|
+
"sessionId": {
|
|
2723
|
+
"type": "string",
|
|
2724
|
+
"description": "Session ID"
|
|
2725
|
+
},
|
|
2726
|
+
"tokenFamily": {
|
|
2727
|
+
"type": "string",
|
|
2728
|
+
"description": "Token family ID (for rotation detection)"
|
|
2729
|
+
},
|
|
2730
|
+
"iat": {
|
|
2731
|
+
"type": "number",
|
|
2732
|
+
"description": "Issued at timestamp (Unix epoch)"
|
|
2733
|
+
},
|
|
2734
|
+
"exp": {
|
|
2735
|
+
"type": "number",
|
|
2736
|
+
"description": "Expiration timestamp (Unix epoch)"
|
|
2737
|
+
},
|
|
2738
|
+
"iss": {
|
|
2739
|
+
"type": "string",
|
|
2740
|
+
"description": "Issuer"
|
|
2741
|
+
},
|
|
2742
|
+
"aud": {
|
|
2743
|
+
"anyOf": [
|
|
2744
|
+
{
|
|
2745
|
+
"type": "string"
|
|
2746
|
+
},
|
|
2747
|
+
{
|
|
2748
|
+
"type": "array",
|
|
2749
|
+
"items": {
|
|
2750
|
+
"type": "string"
|
|
2751
|
+
}
|
|
2752
|
+
}
|
|
2753
|
+
],
|
|
2754
|
+
"description": "Audience"
|
|
2755
|
+
},
|
|
2756
|
+
"deviceId": {
|
|
2757
|
+
"type": "string",
|
|
2758
|
+
"description": "Device ID"
|
|
2759
|
+
}
|
|
2760
|
+
},
|
|
2761
|
+
"required": [
|
|
2762
|
+
"sub",
|
|
2763
|
+
"email",
|
|
2764
|
+
"type",
|
|
2765
|
+
"sessionId",
|
|
2766
|
+
"iat",
|
|
2767
|
+
"exp"
|
|
2768
|
+
],
|
|
2769
|
+
"additionalProperties": false,
|
|
2770
|
+
"description": "JWT Payload structure for validated tokens\n\nContains all claims present in a valid access token."
|
|
2771
|
+
},
|
|
2772
|
+
"LinkSocialAccountDTO": {
|
|
2773
|
+
"type": "object",
|
|
2774
|
+
"properties": {
|
|
2775
|
+
"provider": {
|
|
2776
|
+
"type": "string",
|
|
2777
|
+
"description": "Social provider name (e.g., 'google', 'apple', 'facebook')\n\nValidation:\n- Must be non-empty string\n- Max 50 characters\n\nSanitization:\n- Trimmed and lowercased"
|
|
2778
|
+
},
|
|
2779
|
+
"code": {
|
|
2780
|
+
"type": "string",
|
|
2781
|
+
"description": "Authorization code from OAuth callback\n\nValidation:\n- Must be non-empty string\n- Max 1000 characters\n\nSanitization:\n- Trimmed"
|
|
2782
|
+
},
|
|
2783
|
+
"state": {
|
|
2784
|
+
"type": "string",
|
|
2785
|
+
"description": "State parameter from OAuth callback (for CSRF validation)\n\nValidation:\n- Must be non-empty string\n- Max 500 characters\n\nSanitization:\n- Trimmed"
|
|
2786
|
+
}
|
|
2787
|
+
},
|
|
2788
|
+
"required": [
|
|
2789
|
+
"provider",
|
|
2790
|
+
"code",
|
|
2791
|
+
"state"
|
|
2792
|
+
],
|
|
2793
|
+
"additionalProperties": false,
|
|
2794
|
+
"description": "DTO for linking social account\n\nSecurity:\n- User ID validated as UUID v4\n- Provider name validated\n- Code and state validated for length"
|
|
2795
|
+
},
|
|
2796
|
+
"LinkSocialAccountResponseDTO": {
|
|
2797
|
+
"type": "object",
|
|
2798
|
+
"properties": {
|
|
2799
|
+
"message": {
|
|
2800
|
+
"type": "string",
|
|
2801
|
+
"description": "Success message"
|
|
2802
|
+
},
|
|
2803
|
+
"provider": {
|
|
2804
|
+
"type": "string",
|
|
2805
|
+
"description": "Provider name"
|
|
2806
|
+
}
|
|
2807
|
+
},
|
|
2808
|
+
"required": [
|
|
2809
|
+
"message",
|
|
2810
|
+
"provider"
|
|
2811
|
+
],
|
|
2812
|
+
"additionalProperties": false,
|
|
2813
|
+
"description": "Response DTO for linkSocialAccount"
|
|
2814
|
+
},
|
|
2815
|
+
"ListProvidersResponseDTO": {
|
|
2816
|
+
"type": "object",
|
|
2817
|
+
"properties": {
|
|
2818
|
+
"providers": {
|
|
2819
|
+
"type": "array",
|
|
2820
|
+
"items": {
|
|
2821
|
+
"type": "string"
|
|
2822
|
+
},
|
|
2823
|
+
"description": "Array of registered provider method names",
|
|
2824
|
+
"examples": [
|
|
2825
|
+
[
|
|
2826
|
+
"totp",
|
|
2827
|
+
"sms",
|
|
2828
|
+
"passkey"
|
|
2829
|
+
]
|
|
2830
|
+
]
|
|
2831
|
+
}
|
|
2832
|
+
},
|
|
2833
|
+
"required": [
|
|
2834
|
+
"providers"
|
|
2835
|
+
],
|
|
2836
|
+
"additionalProperties": false,
|
|
2837
|
+
"description": "Response DTO for listing providers"
|
|
2838
|
+
},
|
|
2839
|
+
"LoginDTO": {
|
|
2840
|
+
"type": "object",
|
|
2841
|
+
"properties": {
|
|
2842
|
+
"identifier": {
|
|
2843
|
+
"type": "string",
|
|
2844
|
+
"description": "Login identifier (email, username, or phone)\n\nValidation:\n- At least 1 character\n- Max 255 characters (prevents attacks)\n\nSanitization:\n- Trimmed\n- Lowercased if it looks like email"
|
|
2845
|
+
},
|
|
2846
|
+
"password": {
|
|
2847
|
+
"type": "string",
|
|
2848
|
+
"description": "User password\n\nValidation:\n- At least 1 character (lenient for login)\n- Max 128 characters (prevents DoS)\n\nNote: NOT trimmed (passwords can have spaces)"
|
|
2849
|
+
},
|
|
2850
|
+
"deviceName": {
|
|
2851
|
+
"type": "string",
|
|
2852
|
+
"description": "Optional device name for session identification\n\nValidation:\n- Max 255 characters (matches DB constraint: varchar(255))\n\nSanitization:\n- Trimmed"
|
|
2853
|
+
},
|
|
2854
|
+
"deviceType": {
|
|
2855
|
+
"type": "string",
|
|
2856
|
+
"enum": [
|
|
2857
|
+
"mobile",
|
|
2858
|
+
"desktop",
|
|
2859
|
+
"tablet"
|
|
2860
|
+
],
|
|
2861
|
+
"description": "Optional device type\n\nValidation:\n- Must be one of: mobile, desktop, tablet\n- Max 50 characters (matches DB constraint: varchar(50))\n\nSanitization:\n- Trimmed and lowercased"
|
|
2862
|
+
},
|
|
2863
|
+
"recaptchaToken": {
|
|
2864
|
+
"type": "string",
|
|
2865
|
+
"description": "Optional reCAPTCHA token\n\nRequired when server has reCAPTCHA enabled and enforces validation for the current token delivery mode (typically 'cookies' for web).\n\nValidation:\n- Must be a string\n- Token is single-use and expires after 2 minutes\n- Token must be generated for correct action (e.g., 'login')\n\nSecurity:\n- Token validation happens server-side only\n- Invalid/expired tokens result in RECAPTCHA_VALIDATION_FAILED error\n- Low scores (v3) result in RECAPTCHA_SCORE_TOO_LOW error"
|
|
2866
|
+
}
|
|
2867
|
+
},
|
|
2868
|
+
"required": [
|
|
2869
|
+
"identifier",
|
|
2870
|
+
"password"
|
|
2871
|
+
],
|
|
2872
|
+
"additionalProperties": false,
|
|
2873
|
+
"description": "DTO for user login with security-focused validation\n\nSecurity:\n- Identifier validated (email, username, or phone)\n- Password length enforced\n- Input sanitization applied\n- DeviceId validated if provided"
|
|
2874
|
+
},
|
|
2875
|
+
"LogoutAllDTO": {
|
|
2876
|
+
"type": "object",
|
|
2877
|
+
"properties": {
|
|
2878
|
+
"forgetDevices": {
|
|
2879
|
+
"type": "boolean",
|
|
2880
|
+
"description": "Whether to also forget/revoke all trusted devices\n\nIf true, all trusted devices for this user will be revoked, requiring MFA on next login from any device.\n\nDefault: false (devices remain trusted)",
|
|
2881
|
+
"examples": [
|
|
2882
|
+
false
|
|
2883
|
+
]
|
|
2884
|
+
}
|
|
2885
|
+
},
|
|
2886
|
+
"additionalProperties": false,
|
|
2887
|
+
"description": "Request DTO for logout all sessions"
|
|
2888
|
+
},
|
|
2889
|
+
"LogoutAllResponseDTO": {
|
|
2890
|
+
"type": "object",
|
|
2891
|
+
"properties": {
|
|
2892
|
+
"revokedCount": {
|
|
2893
|
+
"type": "number",
|
|
2894
|
+
"description": "Number of sessions revoked",
|
|
2895
|
+
"examples": [
|
|
2896
|
+
5
|
|
2897
|
+
]
|
|
2898
|
+
}
|
|
2899
|
+
},
|
|
2900
|
+
"required": [
|
|
2901
|
+
"revokedCount"
|
|
2902
|
+
],
|
|
2903
|
+
"additionalProperties": false,
|
|
2904
|
+
"description": "Response DTO for logout all sessions"
|
|
2905
|
+
},
|
|
2906
|
+
"LogoutDTO": {
|
|
2907
|
+
"type": "object",
|
|
2908
|
+
"properties": {
|
|
2909
|
+
"forgetMe": {
|
|
2910
|
+
"type": "boolean",
|
|
2911
|
+
"description": "If true, also removes trusted device\n\nValidation:\n- Must be a boolean if present\n- Default: false",
|
|
2912
|
+
"examples": [
|
|
2913
|
+
false
|
|
2914
|
+
]
|
|
2915
|
+
}
|
|
2916
|
+
},
|
|
2917
|
+
"additionalProperties": false,
|
|
2918
|
+
"description": "Request DTO for logout"
|
|
2919
|
+
},
|
|
2920
|
+
"LogoutResponseDTO": {
|
|
2921
|
+
"type": "object",
|
|
2922
|
+
"properties": {
|
|
2923
|
+
"success": {
|
|
2924
|
+
"type": "boolean",
|
|
2925
|
+
"description": "Success indicator Always true on successful logout",
|
|
2926
|
+
"examples": [
|
|
2927
|
+
true
|
|
2928
|
+
]
|
|
2929
|
+
}
|
|
2930
|
+
},
|
|
2931
|
+
"required": [
|
|
2932
|
+
"success"
|
|
2933
|
+
],
|
|
2934
|
+
"additionalProperties": false,
|
|
2935
|
+
"description": "Response DTO for logout"
|
|
2936
|
+
},
|
|
2937
|
+
"LogoutSessionDTO": {
|
|
2938
|
+
"type": "object",
|
|
2939
|
+
"properties": {
|
|
2940
|
+
"sessionId": {
|
|
2941
|
+
"type": "string",
|
|
2942
|
+
"description": "Session ID to revoke"
|
|
2943
|
+
}
|
|
2944
|
+
},
|
|
2945
|
+
"required": [
|
|
2946
|
+
"sessionId"
|
|
2947
|
+
],
|
|
2948
|
+
"additionalProperties": false,
|
|
2949
|
+
"description": "DTO for logging out a specific session"
|
|
2950
|
+
},
|
|
2951
|
+
"LogoutSessionResponseDTO": {
|
|
2952
|
+
"type": "object",
|
|
2953
|
+
"properties": {
|
|
2954
|
+
"success": {
|
|
2955
|
+
"type": "boolean",
|
|
2956
|
+
"description": "Whether the session was successfully revoked"
|
|
2957
|
+
},
|
|
2958
|
+
"wasCurrentSession": {
|
|
2959
|
+
"type": "boolean",
|
|
2960
|
+
"description": "Whether the revoked session was the current session"
|
|
2961
|
+
}
|
|
2962
|
+
},
|
|
2963
|
+
"required": [
|
|
2964
|
+
"success",
|
|
2965
|
+
"wasCurrentSession"
|
|
2966
|
+
],
|
|
2967
|
+
"additionalProperties": false,
|
|
2968
|
+
"description": "Response DTO for logging out a specific session"
|
|
2969
|
+
},
|
|
2970
|
+
"MFAMethodType": {
|
|
2971
|
+
"type": "string",
|
|
2972
|
+
"enum": [
|
|
2973
|
+
"sms",
|
|
2974
|
+
"email",
|
|
2975
|
+
"totp",
|
|
2976
|
+
"passkey",
|
|
2977
|
+
"backup"
|
|
2978
|
+
],
|
|
2979
|
+
"description": "MFA method enum for validation"
|
|
2980
|
+
},
|
|
2981
|
+
"RefreshTokenDTO": {
|
|
2982
|
+
"type": "object",
|
|
2983
|
+
"properties": {
|
|
2984
|
+
"refreshToken": {
|
|
2985
|
+
"type": "string",
|
|
2986
|
+
"description": "JWT refresh token\n\nOptional to support cookies mode where token is read from cookie. If provided, must be a valid string with min 10 characters.\n\nValidation:\n- Optional (allows cookies mode with empty body)\n- If provided, must be a string\n- If provided, min 10 characters (minimum valid JWT length)\n- If provided, max 2048 characters (prevents DoS, typical JWT is 200-500 chars)\n\nNote: Token format and signature validated in service layer Note: Controller fills this from cookies if empty in cookies mode"
|
|
2987
|
+
}
|
|
2988
|
+
},
|
|
2989
|
+
"additionalProperties": false,
|
|
2990
|
+
"description": "Refresh Token DTO\n\nUsed for refreshing access tokens with a valid refresh token.\n\nSupports both JSON and cookies token delivery modes:\n- JSON mode: refreshToken must be provided in request body\n- Cookies mode: refreshToken is optional in body (read from cookie by controller)\n\nSecurity:\n- Token length validated (prevents DoS)\n- JWT tokens can be long, but we validate input length\n- Token is validated in service layer for format and signature"
|
|
2991
|
+
},
|
|
2992
|
+
"RemoveDevicesDTO": {
|
|
2993
|
+
"type": "object",
|
|
2994
|
+
"properties": {
|
|
2995
|
+
"methodType": {
|
|
2996
|
+
"type": "string",
|
|
2997
|
+
"description": "MFA method type to remove\n\nValidation:\n- Must be one of: totp, sms, email, passkey\n- Max 50 characters\n\nSanitization:\n- Trimmed and lowercased",
|
|
2998
|
+
"examples": [
|
|
2999
|
+
"totp"
|
|
3000
|
+
]
|
|
3001
|
+
}
|
|
3002
|
+
},
|
|
3003
|
+
"required": [
|
|
3004
|
+
"methodType"
|
|
3005
|
+
],
|
|
3006
|
+
"additionalProperties": false,
|
|
3007
|
+
"description": "DTO for removing MFA devices\n\nUser self-service DTO - no userSub field. Service gets user from authenticated context."
|
|
3008
|
+
},
|
|
3009
|
+
"RemoveDevicesResponseDTO": {
|
|
3010
|
+
"type": "object",
|
|
3011
|
+
"properties": {
|
|
3012
|
+
"deletedCount": {
|
|
3013
|
+
"type": "number",
|
|
3014
|
+
"description": "Number of devices deleted"
|
|
3015
|
+
},
|
|
3016
|
+
"mfaDisabled": {
|
|
3017
|
+
"type": "boolean",
|
|
3018
|
+
"description": "Whether MFA was disabled (if this was the last device)"
|
|
3019
|
+
}
|
|
3020
|
+
},
|
|
3021
|
+
"required": [
|
|
3022
|
+
"deletedCount",
|
|
3023
|
+
"mfaDisabled"
|
|
3024
|
+
],
|
|
3025
|
+
"additionalProperties": false,
|
|
3026
|
+
"description": "Response DTO for removing devices"
|
|
3027
|
+
},
|
|
3028
|
+
"ResendCodeDTO": {
|
|
3029
|
+
"type": "object",
|
|
3030
|
+
"properties": {
|
|
3031
|
+
"session": {
|
|
3032
|
+
"type": "string",
|
|
3033
|
+
"description": "Challenge session token (UUID v4)\n\nValidation:\n- Must be a valid UUID v4 format\n- Generated using randomUUID() in challenge service\n- Matches DB constraint: varchar(255) but UUID format enforced\n\nSanitization:\n- Trimmed\n- Lowercased for consistency",
|
|
3034
|
+
"examples": [
|
|
3035
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
3036
|
+
]
|
|
3037
|
+
}
|
|
3038
|
+
},
|
|
3039
|
+
"required": [
|
|
3040
|
+
"session"
|
|
3041
|
+
],
|
|
3042
|
+
"additionalProperties": false,
|
|
3043
|
+
"description": "DTO for resending verification code"
|
|
3044
|
+
},
|
|
3045
|
+
"ResendCodeResponseDTO": {
|
|
3046
|
+
"type": "object",
|
|
3047
|
+
"properties": {
|
|
3048
|
+
"destination": {
|
|
3049
|
+
"type": "string",
|
|
3050
|
+
"description": "Masked destination where code was sent\n\nFormat:\n- Email: \"u***r@example.com\"\n- Phone: \"+1***5678\"",
|
|
3051
|
+
"examples": [
|
|
3052
|
+
"u***r@example.com"
|
|
3053
|
+
]
|
|
3054
|
+
}
|
|
3055
|
+
},
|
|
3056
|
+
"required": [
|
|
3057
|
+
"destination"
|
|
3058
|
+
],
|
|
3059
|
+
"additionalProperties": false,
|
|
3060
|
+
"description": "Response DTO for resend code"
|
|
3061
|
+
},
|
|
3062
|
+
"ResendVerificationEmailDTO": {
|
|
3063
|
+
"type": "object",
|
|
3064
|
+
"properties": {
|
|
3065
|
+
"sub": {
|
|
3066
|
+
"type": "string",
|
|
3067
|
+
"description": "User identifier (UUID v4) - optional if email provided\n\nValidation:\n- Must be valid UUID v4 format if provided\n- Required if email is not provided\n\nSanitization:\n- Trimmed and lowercased"
|
|
3068
|
+
},
|
|
3069
|
+
"email": {
|
|
3070
|
+
"type": "string",
|
|
3071
|
+
"description": "User's email address - optional if sub provided\n\nValidation:\n- Valid email format if provided\n- Max 255 characters (DB limit)\n- Required if sub is not provided\n\nSanitization:\n- Trimmed and lowercased"
|
|
3072
|
+
},
|
|
3073
|
+
"baseUrl": {
|
|
3074
|
+
"type": "string",
|
|
3075
|
+
"description": "Base URL for verification link (optional)\n\nValidation:\n- Must be valid URL format (http:// or https://)\n- Max 2048 characters\n- Optional field\n\nSanitization:\n- Trimmed"
|
|
3076
|
+
},
|
|
3077
|
+
"challengeSessionId": {
|
|
3078
|
+
"type": "number",
|
|
3079
|
+
"description": "Challenge session ID (internal use) Optional - used internally to link verification to specific challenge session. Provides security by ensuring codes are only valid for the session they were created for.\n\nValidation:\n- Must be a positive integer if provided\n- Optional (for backward compatibility and direct verification flows)"
|
|
3080
|
+
}
|
|
3081
|
+
},
|
|
3082
|
+
"additionalProperties": false,
|
|
3083
|
+
"description": "DTO for requesting a verification email resend\n\nSupports both overload patterns: 1. Resend by user sub (string) 2. Resend by email address (object with email property)\n\nSecurity:\n- Either sub or email must be provided (conditional validation)\n- Rate limiting applied in service layer\n- Input sanitization prevents abuse"
|
|
3084
|
+
},
|
|
3085
|
+
"ResendVerificationEmailResponseDTO": {
|
|
3086
|
+
"type": "object",
|
|
3087
|
+
"properties": {
|
|
3088
|
+
"tokenId": {
|
|
3089
|
+
"type": "number",
|
|
3090
|
+
"description": "Verification token ID (internal integer)"
|
|
3091
|
+
}
|
|
3092
|
+
},
|
|
3093
|
+
"required": [
|
|
3094
|
+
"tokenId"
|
|
3095
|
+
],
|
|
3096
|
+
"additionalProperties": false,
|
|
3097
|
+
"description": "Response DTO for resendVerificationEmail"
|
|
3098
|
+
},
|
|
3099
|
+
"ResendVerificationSMSDTO": {
|
|
3100
|
+
"type": "object",
|
|
3101
|
+
"properties": {
|
|
3102
|
+
"sub": {
|
|
3103
|
+
"type": "string",
|
|
3104
|
+
"description": "User identifier (UUID v4) - optional if phone provided\n\nValidation:\n- Must be valid UUID v4 format if provided\n- Required if phone is not provided\n\nSanitization:\n- Trimmed and lowercased"
|
|
3105
|
+
},
|
|
3106
|
+
"phone": {
|
|
3107
|
+
"type": "string",
|
|
3108
|
+
"description": "User's phone number - optional if sub provided\n\nValidation:\n- Must match E.164 format if provided\n- Max 20 characters (DB limit)\n- Required if sub is not provided\n\nSanitization:\n- Whitespace removed"
|
|
3109
|
+
}
|
|
3110
|
+
},
|
|
3111
|
+
"additionalProperties": false,
|
|
3112
|
+
"description": "DTO for resending verification SMS\n\nSupports both sub and phone-based resend\n\nSecurity:\n- Either sub or phone must be provided (conditional validation)\n- Rate limiting applied in service layer\n- Input sanitization prevents abuse"
|
|
3113
|
+
},
|
|
3114
|
+
"ResendVerificationSMSResponseDTO": {
|
|
3115
|
+
"type": "object",
|
|
3116
|
+
"properties": {
|
|
3117
|
+
"tokenId": {
|
|
3118
|
+
"type": "number",
|
|
3119
|
+
"description": "Verification token ID (internal integer)"
|
|
3120
|
+
}
|
|
3121
|
+
},
|
|
3122
|
+
"required": [
|
|
3123
|
+
"tokenId"
|
|
3124
|
+
],
|
|
3125
|
+
"additionalProperties": false,
|
|
3126
|
+
"description": "Response DTO for resendVerificationSMS"
|
|
3127
|
+
},
|
|
3128
|
+
"ResetPasswordDTO": {
|
|
3129
|
+
"type": "object",
|
|
3130
|
+
"properties": {
|
|
3131
|
+
"token": {
|
|
3132
|
+
"type": "string",
|
|
3133
|
+
"description": "Password reset token from email\n\nValidation:\n- Must be a string\n- Min 1 character (prevents empty strings)\n- Max 255 characters (matches DB constraint: varchar(255))\n\nSanitization:\n- Trimmed\n\nNote: Token format and validity validated in service layer"
|
|
3134
|
+
},
|
|
3135
|
+
"newPassword": {
|
|
3136
|
+
"type": "string",
|
|
3137
|
+
"description": "New password\n\nValidation:\n- Must be a string\n- Min 8 characters (security requirement)\n- Max 128 characters (prevents DoS via bcrypt)\n\nNote: NOT trimmed (passwords can have leading/trailing spaces) Additional checks in service layer:\n- Password strength (if configured)\n- Password history (prevent reuse)"
|
|
3138
|
+
}
|
|
3139
|
+
},
|
|
3140
|
+
"required": [
|
|
3141
|
+
"token",
|
|
3142
|
+
"newPassword"
|
|
3143
|
+
],
|
|
3144
|
+
"additionalProperties": false,
|
|
3145
|
+
"description": "Reset Password DTO\n\nUsed to reset password with a valid reset token.\n\nSecurity:\n- Token length validated (matches DB constraint: varchar(255))\n- Password strength enforced (8-128 chars)\n- Token format validated in service layer"
|
|
3146
|
+
},
|
|
3147
|
+
"ResetPasswordRequestDTO": {
|
|
3148
|
+
"type": "object",
|
|
3149
|
+
"properties": {
|
|
3150
|
+
"identifier": {
|
|
3151
|
+
"type": "string",
|
|
3152
|
+
"description": "User identifier (email or phone)\n\nValidation:\n- Must be a string\n- Min 1 character\n- Max 255 characters (matches DB constraint for email)\n\nSanitization:\n- Trimmed\n- Lowercased if email format detected"
|
|
3153
|
+
}
|
|
3154
|
+
},
|
|
3155
|
+
"required": [
|
|
3156
|
+
"identifier"
|
|
3157
|
+
],
|
|
3158
|
+
"additionalProperties": false,
|
|
3159
|
+
"description": "Reset Password Request DTO\n\nUsed to request a password reset token via email or phone.\n\nSecurity:\n- Identifier validated (email or phone)\n- Input sanitization applied"
|
|
3160
|
+
},
|
|
3161
|
+
"RespondChallengeDTO": {
|
|
3162
|
+
"type": "object",
|
|
3163
|
+
"properties": {
|
|
3164
|
+
"session": {
|
|
3165
|
+
"type": "string",
|
|
3166
|
+
"description": "Challenge session token (UUID v4) Always required\n\nValidation:\n- Must be a valid UUID v4 format\n- Generated using randomUUID() in challenge service\n- Matches DB constraint: varchar(255) but UUID format enforced\n\nSanitization:\n- Trimmed\n- Lowercased for consistency",
|
|
3167
|
+
"examples": [
|
|
3168
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
3169
|
+
]
|
|
3170
|
+
},
|
|
3171
|
+
"type": {
|
|
3172
|
+
"$ref": "#/components/schemas/ChallengeType",
|
|
3173
|
+
"description": "Challenge type being responded to Always required"
|
|
3174
|
+
},
|
|
3175
|
+
"code": {
|
|
3176
|
+
"type": "string",
|
|
3177
|
+
"description": "Verification code Required for:\n- VERIFY_EMAIL\n- VERIFY_PHONE (when verifying code)\n- MFA_REQUIRED (for SMS/Email/TOTP/Backup methods)\n\nValidation:\n- Must be a string\n- Length 4-10 characters (covers all code types)\n- Alphanumeric only\n\nNote: NOT trimmed (codes should be exact)"
|
|
3178
|
+
},
|
|
3179
|
+
"phone": {
|
|
3180
|
+
"type": "string",
|
|
3181
|
+
"description": "Phone number in E.164 format Required for VERIFY_PHONE when collecting phone number (first step)\n\nValidation:\n- Must be a string\n- Must match E.164 format: +[country code][number]\n- Example: +14155552671\n- Max 20 characters (matches DB limit)\n\nSanitization:\n- Trimmed\n- Only digits and leading + allowed"
|
|
3182
|
+
},
|
|
3183
|
+
"newPassword": {
|
|
3184
|
+
"type": "string",
|
|
3185
|
+
"description": "New password Required for FORCE_CHANGE_PASSWORD challenge\n\nValidation:\n- Must be a string\n- Min 8 characters (security requirement)\n- Max 128 characters (prevents DoS via bcrypt)\n\nNote: NOT trimmed (passwords can have leading/trailing spaces)"
|
|
3186
|
+
},
|
|
3187
|
+
"method": {
|
|
3188
|
+
"$ref": "#/components/schemas/MFAMethodType",
|
|
3189
|
+
"description": "MFA method being used or set up Required for:\n- MFA_REQUIRED challenge (method being used for verification)\n- MFA_SETUP_REQUIRED challenge (method being set up)\n\nValidation:\n- Must be one of: sms, email, totp, passkey, backup"
|
|
3190
|
+
},
|
|
3191
|
+
"credential": {
|
|
3192
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E",
|
|
3193
|
+
"description": "Passkey credential Required for MFA_REQUIRED when method is 'passkey'\n\nValidation:\n- Must be an object\n- Contains WebAuthn credential from navigator.credentials.get()"
|
|
3194
|
+
},
|
|
3195
|
+
"setupData": {
|
|
3196
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E",
|
|
3197
|
+
"description": "MFA setup data (method-specific) Required for MFA_SETUP_REQUIRED challenge\n\nExpected structure by method:\n- SMS: { phone: string, code: string }\n- Email: { code: string }\n- TOTP: { code: string }\n- Passkey: { credential: Record<string, unknown> }\n\nValidation:\n- Must be an object\n- Structure validated by MFA provider services"
|
|
3198
|
+
}
|
|
3199
|
+
},
|
|
3200
|
+
"required": [
|
|
3201
|
+
"session",
|
|
3202
|
+
"type"
|
|
3203
|
+
],
|
|
3204
|
+
"additionalProperties": false,
|
|
3205
|
+
"description": "Unified DTO for responding to authentication challenges\n\nUses conditional validation (@ValidateIf) to validate fields based on challenge type. This ensures proper validation while maintaining a single endpoint for all challenge types.\n\nSecurity:\n- All strings have max length constraints matching DB limits\n- Phone numbers validated against E.164 format (prevents SQL injection)\n- Verification codes validated for length (4-10 chars)\n- Passwords validated for strength requirements\n- Session tokens validated as UUID v4 format (prevents injection)"
|
|
3206
|
+
},
|
|
3207
|
+
"SendVerificationEmailDTO": {
|
|
3208
|
+
"type": "object",
|
|
3209
|
+
"properties": {
|
|
3210
|
+
"sub": {
|
|
3211
|
+
"type": "string",
|
|
3212
|
+
"description": "User identifier (UUID v4)\n\nValidation:\n- Must be valid UUID v4 format\n\nSanitization:\n- Trimmed and lowercased"
|
|
3213
|
+
},
|
|
3214
|
+
"baseUrl": {
|
|
3215
|
+
"type": "string",
|
|
3216
|
+
"description": "Base URL for verification link (optional)\n\nValidation:\n- Must be valid URL format (http:// or https://)\n- Supports localhost URLs (e.g., http://localhost:4200)\n- Max 2048 characters (typical URL length limit)\n- Optional field\n\nSanitization:\n- Trimmed"
|
|
3217
|
+
},
|
|
3218
|
+
"skipAlreadyVerifiedCheck": {
|
|
3219
|
+
"type": "boolean",
|
|
3220
|
+
"description": "Skip the \"already verified\" check Used for MFA contexts where codes are needed even if email is verified\n\nValidation:\n- Must be boolean\n- Optional (defaults to false)"
|
|
3221
|
+
},
|
|
3222
|
+
"challengeSessionId": {
|
|
3223
|
+
"type": "number",
|
|
3224
|
+
"description": "Challenge session ID to link this verification token to Optional - for linking verification tokens to specific challenge sessions. Provides security by preventing old tokens from being used with new sessions.\n\nValidation:\n- Must be a positive integer\n- Optional (for backward compatibility and non-challenge flows like password reset)"
|
|
3225
|
+
}
|
|
3226
|
+
},
|
|
3227
|
+
"required": [
|
|
3228
|
+
"sub"
|
|
3229
|
+
],
|
|
3230
|
+
"additionalProperties": false,
|
|
3231
|
+
"description": "DTO for sending a verification email\n\nSecurity:\n- User sub validated as UUID v4\n- BaseURL validated as max length\n- Skip flag is boolean (prevents injection)"
|
|
3232
|
+
},
|
|
3233
|
+
"SendVerificationEmailResponseDTO": {
|
|
3234
|
+
"type": "object",
|
|
3235
|
+
"properties": {
|
|
3236
|
+
"tokenId": {
|
|
3237
|
+
"type": "number",
|
|
3238
|
+
"description": "Verification token ID (internal integer)"
|
|
3239
|
+
}
|
|
3240
|
+
},
|
|
3241
|
+
"required": [
|
|
3242
|
+
"tokenId"
|
|
3243
|
+
],
|
|
3244
|
+
"additionalProperties": false,
|
|
3245
|
+
"description": "Response DTO for sendVerificationEmail"
|
|
3246
|
+
},
|
|
3247
|
+
"SendVerificationSMSDTO": {
|
|
3248
|
+
"type": "object",
|
|
3249
|
+
"properties": {
|
|
3250
|
+
"sub": {
|
|
3251
|
+
"type": "string",
|
|
3252
|
+
"description": "User identifier (UUID v4)\n\nValidation:\n- Must be valid UUID v4 format\n\nSanitization:\n- Trimmed and lowercased"
|
|
3253
|
+
},
|
|
3254
|
+
"skipAlreadyVerifiedCheck": {
|
|
3255
|
+
"type": "boolean",
|
|
3256
|
+
"description": "Skip the \"already verified\" check Used for MFA contexts where codes are needed even if phone is verified\n\nValidation:\n- Must be boolean\n- Optional (defaults to true)"
|
|
3257
|
+
},
|
|
3258
|
+
"challengeSessionId": {
|
|
3259
|
+
"type": "number",
|
|
3260
|
+
"description": "Challenge session ID to link this verification token to Optional - for linking verification tokens to specific challenge sessions. Provides security by preventing old tokens from being used with new sessions.\n\nValidation:\n- Must be a positive integer\n- Optional (for backward compatibility and non-challenge flows)"
|
|
3261
|
+
}
|
|
3262
|
+
},
|
|
3263
|
+
"required": [
|
|
3264
|
+
"sub"
|
|
3265
|
+
],
|
|
3266
|
+
"additionalProperties": false,
|
|
3267
|
+
"description": "DTO for sending verification SMS\n\nSecurity:\n- User sub validated as UUID v4\n- Skip flag is boolean (prevents injection)"
|
|
3268
|
+
},
|
|
3269
|
+
"SendVerificationSMSResponseDTO": {
|
|
3270
|
+
"type": "object",
|
|
3271
|
+
"properties": {
|
|
3272
|
+
"tokenId": {
|
|
3273
|
+
"type": "number",
|
|
3274
|
+
"description": "Verification token ID (internal integer)"
|
|
3275
|
+
}
|
|
3276
|
+
},
|
|
3277
|
+
"required": [
|
|
3278
|
+
"tokenId"
|
|
3279
|
+
],
|
|
3280
|
+
"additionalProperties": false,
|
|
3281
|
+
"description": "Response DTO for sendVerificationSMS"
|
|
3282
|
+
},
|
|
3283
|
+
"SetMFAExemptionDTO": {
|
|
3284
|
+
"type": "object",
|
|
3285
|
+
"properties": {
|
|
3286
|
+
"sub": {
|
|
3287
|
+
"type": "string",
|
|
3288
|
+
"description": "User's unique identifier (UUID v4)\n\nValidation:\n- Must be a valid UUID v4 format\n- Matches DB constraint: char(36) or uuid\n\nSanitization:\n- Trimmed\n- Lowercased for consistency",
|
|
3289
|
+
"examples": [
|
|
3290
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
3291
|
+
]
|
|
3292
|
+
},
|
|
3293
|
+
"exempt": {
|
|
3294
|
+
"type": "boolean",
|
|
3295
|
+
"description": "Whether to grant exemption (true) or revoke exemption (false)"
|
|
3296
|
+
},
|
|
3297
|
+
"reason": {
|
|
3298
|
+
"type": [
|
|
3299
|
+
"string",
|
|
3300
|
+
"null"
|
|
3301
|
+
],
|
|
3302
|
+
"description": "Optional reason for the exemption status change\n\nValidation:\n- Max 500 characters\n\nSanitization:\n- Trimmed"
|
|
3303
|
+
},
|
|
3304
|
+
"grantedBy": {
|
|
3305
|
+
"type": [
|
|
3306
|
+
"string",
|
|
3307
|
+
"null"
|
|
3308
|
+
],
|
|
3309
|
+
"description": "Optional identifier of the admin performing this action. Typically the admin's sub (UUID) when set from authenticated context. Used for mfaExemptGrantedBy on the user and for audit performedBy.\n\nValidation:\n- Max 255 characters\n\nSanitization:\n- Trimmed"
|
|
3310
|
+
}
|
|
3311
|
+
},
|
|
3312
|
+
"required": [
|
|
3313
|
+
"sub",
|
|
3314
|
+
"exempt"
|
|
3315
|
+
],
|
|
3316
|
+
"additionalProperties": false,
|
|
3317
|
+
"description": "DTO for setting MFA exemption\n\nSECURITY: This DTO targets an arbitrary user; it must only be accepted by admin-protected APIs."
|
|
3318
|
+
},
|
|
3319
|
+
"SetMFAExemptionResponseDTO": {
|
|
3320
|
+
"type": "object",
|
|
3321
|
+
"properties": {
|
|
3322
|
+
"mfaExempt": {
|
|
3323
|
+
"type": "boolean",
|
|
3324
|
+
"description": "Whether user is exempt from MFA requirements"
|
|
3325
|
+
},
|
|
3326
|
+
"mfaExemptReason": {
|
|
3327
|
+
"type": [
|
|
3328
|
+
"string",
|
|
3329
|
+
"null"
|
|
3330
|
+
],
|
|
3331
|
+
"description": "Reason for MFA exemption (if exempt)"
|
|
3332
|
+
},
|
|
3333
|
+
"mfaExemptGrantedAt": {
|
|
3334
|
+
"anyOf": [
|
|
3335
|
+
{
|
|
3336
|
+
"type": "string",
|
|
3337
|
+
"format": "date-time"
|
|
3338
|
+
},
|
|
3339
|
+
{
|
|
3340
|
+
"type": "null"
|
|
3341
|
+
}
|
|
3342
|
+
],
|
|
3343
|
+
"description": "Date when MFA exemption was granted (if exempt)"
|
|
3344
|
+
}
|
|
3345
|
+
},
|
|
3346
|
+
"required": [
|
|
3347
|
+
"mfaExempt",
|
|
3348
|
+
"mfaExemptReason",
|
|
3349
|
+
"mfaExemptGrantedAt"
|
|
3350
|
+
],
|
|
3351
|
+
"additionalProperties": false,
|
|
3352
|
+
"description": "Response DTO for setting MFA exemption"
|
|
3353
|
+
},
|
|
3354
|
+
"SetMustChangePasswordDTO": {
|
|
3355
|
+
"type": "object",
|
|
3356
|
+
"properties": {
|
|
3357
|
+
"sub": {
|
|
3358
|
+
"type": "string",
|
|
3359
|
+
"description": "User's unique identifier (UUID v4)\n\nValidation:\n- Must be a valid UUID v4 format\n- Matches DB constraint: char(36) or uuid\n\nSanitization:\n- Trimmed\n- Lowercased for consistency",
|
|
3360
|
+
"examples": [
|
|
3361
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
3362
|
+
]
|
|
3363
|
+
}
|
|
3364
|
+
},
|
|
3365
|
+
"required": [
|
|
3366
|
+
"sub"
|
|
3367
|
+
],
|
|
3368
|
+
"additionalProperties": false,
|
|
3369
|
+
"description": "Request DTO for setting must change password flag"
|
|
3370
|
+
},
|
|
3371
|
+
"SetMustChangePasswordResponseDTO": {
|
|
3372
|
+
"type": "object",
|
|
3373
|
+
"properties": {
|
|
3374
|
+
"success": {
|
|
3375
|
+
"type": "boolean",
|
|
3376
|
+
"description": "Success indicator Always true on successful flag set",
|
|
3377
|
+
"examples": [
|
|
3378
|
+
true
|
|
3379
|
+
]
|
|
3380
|
+
}
|
|
3381
|
+
},
|
|
3382
|
+
"required": [
|
|
3383
|
+
"success"
|
|
3384
|
+
],
|
|
3385
|
+
"additionalProperties": false,
|
|
3386
|
+
"description": "Response DTO for set must change password"
|
|
3387
|
+
},
|
|
3388
|
+
"SetPasswordForSocialUserDTO": {
|
|
3389
|
+
"type": "object",
|
|
3390
|
+
"properties": {
|
|
3391
|
+
"sub": {
|
|
3392
|
+
"type": "string",
|
|
3393
|
+
"description": "User identifier (UUID v4)\n\nValidation:\n- Must be valid UUID v4 format\n\nSanitization:\n- Trimmed and lowercased"
|
|
3394
|
+
},
|
|
3395
|
+
"password": {
|
|
3396
|
+
"type": "string",
|
|
3397
|
+
"description": "New password\n\nValidation:\n- Must be non-empty string\n- Min 1 character (actual validation in AuthService)\n- Max 128 characters (matches DB constraint)\n\nSanitization:\n- Not trimmed (passwords may have leading/trailing spaces intentionally)"
|
|
3398
|
+
}
|
|
3399
|
+
},
|
|
3400
|
+
"required": [
|
|
3401
|
+
"sub",
|
|
3402
|
+
"password"
|
|
3403
|
+
],
|
|
3404
|
+
"additionalProperties": false,
|
|
3405
|
+
"description": "DTO for setting password for social-only user\n\nSecurity:\n- User sub validated as UUID v4\n- Password validated for strength (delegated to AuthService)"
|
|
3406
|
+
},
|
|
3407
|
+
"SetPasswordForSocialUserResponseDTO": {
|
|
3408
|
+
"type": "object",
|
|
3409
|
+
"properties": {
|
|
3410
|
+
"message": {
|
|
3411
|
+
"type": "string",
|
|
3412
|
+
"description": "Success message"
|
|
3413
|
+
}
|
|
3414
|
+
},
|
|
3415
|
+
"required": [
|
|
3416
|
+
"message"
|
|
3417
|
+
],
|
|
3418
|
+
"additionalProperties": false,
|
|
3419
|
+
"description": "Response DTO for setPasswordForSocialUser"
|
|
3420
|
+
},
|
|
3421
|
+
"SetPreferredMethodDTO": {
|
|
3422
|
+
"type": "object",
|
|
3423
|
+
"properties": {
|
|
3424
|
+
"methodType": {
|
|
3425
|
+
"type": "string",
|
|
3426
|
+
"description": "MFA method type to set as preferred\n\nValidation:\n- Must be one of: totp, sms, email, passkey\n- Max 50 characters\n\nSanitization:\n- Trimmed and lowercased",
|
|
3427
|
+
"examples": [
|
|
3428
|
+
"totp"
|
|
3429
|
+
]
|
|
3430
|
+
}
|
|
3431
|
+
},
|
|
3432
|
+
"required": [
|
|
3433
|
+
"methodType"
|
|
3434
|
+
],
|
|
3435
|
+
"additionalProperties": false,
|
|
3436
|
+
"description": "DTO for setting preferred MFA method\n\nUser self-service DTO - no userSub field. Service gets user from authenticated context."
|
|
3437
|
+
},
|
|
3438
|
+
"SetPreferredMethodResponseDTO": {
|
|
3439
|
+
"type": "object",
|
|
3440
|
+
"properties": {
|
|
3441
|
+
"message": {
|
|
3442
|
+
"type": "string",
|
|
3443
|
+
"description": "Success message"
|
|
3444
|
+
}
|
|
3445
|
+
},
|
|
3446
|
+
"required": [
|
|
3447
|
+
"message"
|
|
3448
|
+
],
|
|
3449
|
+
"additionalProperties": false,
|
|
3450
|
+
"description": "Response DTO for setting preferred method"
|
|
3451
|
+
},
|
|
3452
|
+
"SetupMFADTO": {
|
|
3453
|
+
"type": "object",
|
|
3454
|
+
"properties": {
|
|
3455
|
+
"methodName": {
|
|
3456
|
+
"type": "string",
|
|
3457
|
+
"description": "MFA method name\n\nValidation:\n- Must be one of: totp, sms, email, passkey\n- Max 50 characters\n\nSanitization:\n- Trimmed and lowercased",
|
|
3458
|
+
"examples": [
|
|
3459
|
+
"totp"
|
|
3460
|
+
]
|
|
3461
|
+
},
|
|
3462
|
+
"setupData": {
|
|
3463
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E",
|
|
3464
|
+
"description": "Optional provider-specific setup data\n\nValidation:\n- Must be an object if provided\n- Structure validated by MFA provider services"
|
|
3465
|
+
}
|
|
3466
|
+
},
|
|
3467
|
+
"required": [
|
|
3468
|
+
"methodName"
|
|
3469
|
+
],
|
|
3470
|
+
"additionalProperties": false,
|
|
3471
|
+
"description": "DTO for setting up MFA device\n\nUser self-service DTO - no sub field. Service gets user from authenticated context."
|
|
3472
|
+
},
|
|
3473
|
+
"SetupMFAResponseDTO": {
|
|
3474
|
+
"type": "object",
|
|
3475
|
+
"properties": {
|
|
3476
|
+
"setupData": {
|
|
3477
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E",
|
|
3478
|
+
"description": "Provider-specific setup response\n\nStructure varies by method:\n- TOTP: { secret, qrCode, manualEntryKey }\n- SMS: { maskedPhone }\n- Passkey: WebAuthn registration options"
|
|
3479
|
+
}
|
|
3480
|
+
},
|
|
3481
|
+
"required": [
|
|
3482
|
+
"setupData"
|
|
3483
|
+
],
|
|
3484
|
+
"additionalProperties": false,
|
|
3485
|
+
"description": "Response DTO for MFA setup"
|
|
3486
|
+
},
|
|
3487
|
+
"SignupDTO": {
|
|
3488
|
+
"type": "object",
|
|
3489
|
+
"properties": {
|
|
3490
|
+
"email": {
|
|
3491
|
+
"type": "string",
|
|
3492
|
+
"description": "User email address\n\nValidation:\n- Valid email format (RFC 5322)\n- Max 255 characters (matches DB limit)\n\nSanitization:\n- Trimmed and lowercased"
|
|
3493
|
+
},
|
|
3494
|
+
"password": {
|
|
3495
|
+
"type": "string",
|
|
3496
|
+
"description": "User password\n\nValidation:\n- Min 8 characters\n- Max 128 characters (prevents DoS via bcrypt)\n- Additional policy checks in service layer\n\nNote: NOT trimmed (passwords can have leading/trailing spaces)"
|
|
3497
|
+
},
|
|
3498
|
+
"username": {
|
|
3499
|
+
"type": "string",
|
|
3500
|
+
"description": "Optional username\n\nValidation:\n- 3-50 characters\n- Alphanumeric, underscores, and hyphens only\n- Max 255 characters (DB limit)\n\nSanitization:\n- Trimmed\n- Case preserved (username can be case-sensitive per config)"
|
|
3501
|
+
},
|
|
3502
|
+
"firstName": {
|
|
3503
|
+
"type": "string",
|
|
3504
|
+
"description": "Optional first name\n\nValidation:\n- 1-100 characters\n- Max 100 characters (DB limit)\n\nSanitization:\n- Trimmed\n- Title case preserved"
|
|
3505
|
+
},
|
|
3506
|
+
"lastName": {
|
|
3507
|
+
"type": "string",
|
|
3508
|
+
"description": "Optional last name\n\nValidation:\n- 1-100 characters\n- Max 100 characters (DB limit)\n\nSanitization:\n- Trimmed\n- Title case preserved"
|
|
3509
|
+
},
|
|
3510
|
+
"phone": {
|
|
3511
|
+
"type": "string",
|
|
3512
|
+
"description": "Optional phone number\n\nValidation:\n- E.164 format (international standard)\n- MUST start with + (required for security)\n- Max 20 characters (DB limit)\n- Example: +14155552671, +61444567890\n\nSanitization:\n- Whitespace removed\n- Only digits and leading + preserved\n\nSecurity:\n- Strict E.164 validation prevents SQL injection\n- Max length prevents oversized inputs\n\nNote: Using regex for E.164 format as IsPhoneNumber requires specific country codes and doesn't support international E.164 format validation directly"
|
|
3513
|
+
},
|
|
3514
|
+
"metadata": {
|
|
3515
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E",
|
|
3516
|
+
"description": "Optional metadata (custom fields)\n\nSecurity:\n- Validated in service layer if used\n- Max depth/size limits should be enforced"
|
|
3517
|
+
},
|
|
3518
|
+
"recaptchaToken": {
|
|
3519
|
+
"type": "string",
|
|
3520
|
+
"description": "Optional reCAPTCHA token\n\nRequired when server has reCAPTCHA enabled and enforces validation for the current token delivery mode (typically 'cookies' for web).\n\nValidation:\n- Must be a string\n- Token is single-use and expires after 2 minutes\n- Token must be generated for correct action (e.g., 'signup')\n\nSecurity:\n- Token validation happens server-side only\n- Invalid/expired tokens result in RECAPTCHA_VALIDATION_FAILED error\n- Low scores (v3) result in RECAPTCHA_SCORE_TOO_LOW error"
|
|
3521
|
+
}
|
|
3522
|
+
},
|
|
3523
|
+
"required": [
|
|
3524
|
+
"email",
|
|
3525
|
+
"password"
|
|
3526
|
+
],
|
|
3527
|
+
"additionalProperties": false,
|
|
3528
|
+
"description": "DTO for user signup with comprehensive validation\n\nSecurity:\n- All fields validated against DB constraints\n- Input sanitization applied automatically\n- Password strength enforced (8-128 chars)\n- Email/username uniqueness checked in service layer"
|
|
3529
|
+
},
|
|
3530
|
+
"SocialCallbackFormDTO": {
|
|
3531
|
+
"type": "object",
|
|
3532
|
+
"properties": {
|
|
3533
|
+
"code": {
|
|
3534
|
+
"type": "string",
|
|
3535
|
+
"description": "OAuth authorization code from provider\n\nValidation:\n- Optional field\n- Max 2000 characters\n\nSanitization:\n- Trimmed"
|
|
3536
|
+
},
|
|
3537
|
+
"state": {
|
|
3538
|
+
"type": "string",
|
|
3539
|
+
"description": "OAuth state parameter for CSRF protection\n\nValidation:\n- Optional field\n- Max 500 characters\n\nSanitization:\n- Trimmed"
|
|
3540
|
+
},
|
|
3541
|
+
"error": {
|
|
3542
|
+
"type": "string",
|
|
3543
|
+
"description": "Provider error code (if user cancels or error occurs)\n\nValidation:\n- Optional field\n- Max 2000 characters\n\nSanitization:\n- Trimmed"
|
|
3544
|
+
},
|
|
3545
|
+
"error_description": {
|
|
3546
|
+
"type": "string",
|
|
3547
|
+
"description": "Provider error description\n\nValidation:\n- Optional field\n- Max 4000 characters\n\nSanitization:\n- Trimmed"
|
|
3548
|
+
},
|
|
3549
|
+
"scope": {
|
|
3550
|
+
"type": "string",
|
|
3551
|
+
"description": "Provider callback extras (for validation compatibility)\n\nIncluded for parity with GET callback DTO to avoid strict validation issues.\n\nValidation:\n- Optional field\n- Max 4000 characters\n\nSanitization:\n- Trimmed"
|
|
3552
|
+
},
|
|
3553
|
+
"authuser": {
|
|
3554
|
+
"type": "string",
|
|
3555
|
+
"description": "Provider-specific parameter\n\nValidation:\n- Optional field\n- Max 50 characters\n\nSanitization:\n- Trimmed"
|
|
3556
|
+
},
|
|
3557
|
+
"hd": {
|
|
3558
|
+
"type": "string",
|
|
3559
|
+
"description": "Provider-specific parameter\n\nValidation:\n- Optional field\n- Max 2000 characters\n\nSanitization:\n- Trimmed"
|
|
3560
|
+
},
|
|
3561
|
+
"prompt": {
|
|
3562
|
+
"type": "string",
|
|
3563
|
+
"description": "Provider-specific parameter\n\nValidation:\n- Optional field\n- Max 2000 characters\n\nSanitization:\n- Trimmed"
|
|
3564
|
+
}
|
|
3565
|
+
},
|
|
3566
|
+
"additionalProperties": false,
|
|
3567
|
+
"description": "DTO for Apple form_post OAuth callbacks\n\nApple uses POST form_post response mode instead of query parameters. This DTO handles the form data sent to the callback endpoint."
|
|
3568
|
+
},
|
|
3569
|
+
"SocialCallbackQueryDTO": {
|
|
3570
|
+
"type": "object",
|
|
3571
|
+
"properties": {
|
|
3572
|
+
"code": {
|
|
3573
|
+
"type": "string",
|
|
3574
|
+
"description": "OAuth authorization code from provider\n\nValidation:\n- Optional field\n- Max 2000 characters\n\nSanitization:\n- Trimmed"
|
|
3575
|
+
},
|
|
3576
|
+
"state": {
|
|
3577
|
+
"type": "string",
|
|
3578
|
+
"description": "OAuth state parameter for CSRF protection\n\nValidation:\n- Optional field\n- Max 500 characters\n\nSanitization:\n- Trimmed"
|
|
3579
|
+
},
|
|
3580
|
+
"error": {
|
|
3581
|
+
"type": "string",
|
|
3582
|
+
"description": "Provider error code (if user cancels or error occurs)\n\nValidation:\n- Optional field\n- Max 2000 characters\n\nSanitization:\n- Trimmed",
|
|
3583
|
+
"examples": [
|
|
3584
|
+
"access_denied"
|
|
3585
|
+
]
|
|
3586
|
+
},
|
|
3587
|
+
"error_description": {
|
|
3588
|
+
"type": "string",
|
|
3589
|
+
"description": "Provider error description\n\nValidation:\n- Optional field\n- Max 4000 characters\n\nSanitization:\n- Trimmed",
|
|
3590
|
+
"examples": [
|
|
3591
|
+
"User cancelled the authentication request"
|
|
3592
|
+
]
|
|
3593
|
+
},
|
|
3594
|
+
"scope": {
|
|
3595
|
+
"type": "string",
|
|
3596
|
+
"description": "Google-specific: OAuth scope parameter\n\nGoogle often includes this in the callback. Explicitly allowed to avoid validation errors when using whitelist + forbidNonWhitelisted validation.\n\nValidation:\n- Optional field\n- Max 4000 characters\n\nSanitization:\n- Trimmed"
|
|
3597
|
+
},
|
|
3598
|
+
"authuser": {
|
|
3599
|
+
"type": "string",
|
|
3600
|
+
"description": "Google-specific: Authenticated user index\n\nValidation:\n- Optional field\n- Max 50 characters\n\nSanitization:\n- Trimmed"
|
|
3601
|
+
},
|
|
3602
|
+
"hd": {
|
|
3603
|
+
"type": "string",
|
|
3604
|
+
"description": "Google-specific: Hosted domain parameter\n\nValidation:\n- Optional field\n- Max 2000 characters\n\nSanitization:\n- Trimmed"
|
|
3605
|
+
},
|
|
3606
|
+
"prompt": {
|
|
3607
|
+
"type": "string",
|
|
3608
|
+
"description": "Google-specific: Prompt parameter\n\nValidation:\n- Optional field\n- Max 2000 characters\n\nSanitization:\n- Trimmed"
|
|
3609
|
+
},
|
|
3610
|
+
"session_state": {
|
|
3611
|
+
"type": "string",
|
|
3612
|
+
"description": "Provider-specific: Session state parameter\n\nSome providers include this for session management.\n\nValidation:\n- Optional field\n- Max 2000 characters\n\nSanitization:\n- Trimmed"
|
|
3613
|
+
},
|
|
3614
|
+
"error_uri": {
|
|
3615
|
+
"type": "string",
|
|
3616
|
+
"description": "Provider-specific: Error URI parameter\n\nSome providers include a URI with more error details.\n\nValidation:\n- Optional field\n- Max 4000 characters\n\nSanitization:\n- Trimmed"
|
|
3617
|
+
}
|
|
3618
|
+
},
|
|
3619
|
+
"additionalProperties": false,
|
|
3620
|
+
"description": "DTO for OAuth callbacks via GET query parameters\n\nUsed by providers that redirect with query params (Google, Facebook). This DTO handles both successful callbacks and error scenarios."
|
|
3621
|
+
},
|
|
3622
|
+
"SocialExchangeDTO": {
|
|
3623
|
+
"type": "object",
|
|
3624
|
+
"properties": {
|
|
3625
|
+
"exchangeToken": {
|
|
3626
|
+
"type": "string",
|
|
3627
|
+
"description": "One-time exchange token from callback redirect URL\n\nValidation:\n- Must be non-empty string\n- Max 500 characters\n\nSanitization:\n- Trimmed"
|
|
3628
|
+
}
|
|
3629
|
+
},
|
|
3630
|
+
"required": [
|
|
3631
|
+
"exchangeToken"
|
|
3632
|
+
],
|
|
3633
|
+
"additionalProperties": false,
|
|
3634
|
+
"description": "DTO for exchanging a social redirect exchange token\n\nUsed in redirect-first social login flow. The backend redirects back to the frontend with an `exchangeToken` in the URL, and the frontend exchanges it for an AuthResponse.\n\nSecurity:\n- Exchange token validated for length\n- One-time use (consumed immediately)\n- Short TTL (default: 60 seconds)"
|
|
3635
|
+
},
|
|
3636
|
+
"StartSocialRedirectQueryDTO": {
|
|
3637
|
+
"type": "object",
|
|
3638
|
+
"properties": {
|
|
3639
|
+
"returnTo": {
|
|
3640
|
+
"type": "string",
|
|
3641
|
+
"description": "Frontend path or absolute URL to redirect to after authentication completes\n\nValidation:\n- Optional field\n- Max 2048 characters\n\nSanitization:\n- Trimmed",
|
|
3642
|
+
"examples": [
|
|
3643
|
+
"/auth/callback",
|
|
3644
|
+
"https://myapp.com/auth/callback"
|
|
3645
|
+
]
|
|
3646
|
+
},
|
|
3647
|
+
"appState": {
|
|
3648
|
+
"type": "string",
|
|
3649
|
+
"description": "Opaque, non-secret state to round-trip back to the frontend\n\nThis value is stored during the OAuth flow and returned to the frontend after authentication completes. Use it to maintain UI state across the redirect.\n\nValidation:\n- Optional field\n- Max 2000 characters\n\nSanitization:\n- Trimmed",
|
|
3650
|
+
"examples": [
|
|
3651
|
+
"12345",
|
|
3652
|
+
"page=dashboard&mode=dark"
|
|
3653
|
+
]
|
|
3654
|
+
},
|
|
3655
|
+
"action": {
|
|
3656
|
+
"type": "string",
|
|
3657
|
+
"enum": [
|
|
3658
|
+
"login",
|
|
3659
|
+
"link"
|
|
3660
|
+
],
|
|
3661
|
+
"description": "Redirect action type\n\n- `login`: Standard social login/signup (default)\n- `link`: Link social account to existing authenticated user\n\nValidation:\n- Optional field\n- Must be either 'login' or 'link'",
|
|
3662
|
+
"examples": [
|
|
3663
|
+
"login",
|
|
3664
|
+
"link"
|
|
3665
|
+
]
|
|
3666
|
+
}
|
|
3667
|
+
},
|
|
3668
|
+
"additionalProperties": false,
|
|
3669
|
+
"description": "DTO for starting the redirect-first social login flow\n\nUsed when initiating a backend-first OAuth redirect flow where the provider redirects back to the backend callback endpoint."
|
|
3670
|
+
},
|
|
3671
|
+
"TokenResponse": {
|
|
3672
|
+
"type": "object",
|
|
3673
|
+
"properties": {
|
|
3674
|
+
"accessToken": {
|
|
3675
|
+
"type": "string",
|
|
3676
|
+
"description": "New JWT access token"
|
|
3677
|
+
},
|
|
3678
|
+
"refreshToken": {
|
|
3679
|
+
"type": "string",
|
|
3680
|
+
"description": "New JWT refresh token"
|
|
3681
|
+
},
|
|
3682
|
+
"accessTokenExpiresAt": {
|
|
3683
|
+
"type": "number",
|
|
3684
|
+
"description": "Access token expiration (Unix timestamp in seconds)"
|
|
3685
|
+
},
|
|
3686
|
+
"refreshTokenExpiresAt": {
|
|
3687
|
+
"type": "number",
|
|
3688
|
+
"description": "Refresh token expiration (Unix timestamp in seconds)"
|
|
3689
|
+
}
|
|
3690
|
+
},
|
|
3691
|
+
"required": [
|
|
3692
|
+
"accessToken",
|
|
3693
|
+
"refreshToken",
|
|
3694
|
+
"accessTokenExpiresAt",
|
|
3695
|
+
"refreshTokenExpiresAt"
|
|
3696
|
+
],
|
|
3697
|
+
"additionalProperties": false,
|
|
3698
|
+
"description": "Token Response DTO\n\nReturned by token refresh operations Contains new access and refresh tokens with expiration times"
|
|
3699
|
+
},
|
|
3700
|
+
"TrustDeviceResponseDTO": {
|
|
3701
|
+
"type": "object",
|
|
3702
|
+
"properties": {
|
|
3703
|
+
"deviceToken": {
|
|
3704
|
+
"type": "string",
|
|
3705
|
+
"description": "Device trust token\n\nNote: Store this token securely on the client device",
|
|
3706
|
+
"examples": [
|
|
3707
|
+
"device-token-uuid-string"
|
|
3708
|
+
]
|
|
3709
|
+
}
|
|
3710
|
+
},
|
|
3711
|
+
"required": [
|
|
3712
|
+
"deviceToken"
|
|
3713
|
+
],
|
|
3714
|
+
"additionalProperties": false,
|
|
3715
|
+
"description": "Response DTO for trust device"
|
|
3716
|
+
},
|
|
3717
|
+
"UnlinkSocialAccountDTO": {
|
|
3718
|
+
"type": "object",
|
|
3719
|
+
"properties": {
|
|
3720
|
+
"provider": {
|
|
3721
|
+
"type": "string",
|
|
3722
|
+
"description": "Social provider name (e.g., 'google', 'apple', 'facebook')\n\nValidation:\n- Must be non-empty string\n- Max 50 characters\n\nSanitization:\n- Trimmed and lowercased"
|
|
3723
|
+
}
|
|
3724
|
+
},
|
|
3725
|
+
"required": [
|
|
3726
|
+
"provider"
|
|
3727
|
+
],
|
|
3728
|
+
"additionalProperties": false,
|
|
3729
|
+
"description": "DTO for unlinking social account\n\nSecurity:\n- User ID validated as UUID v4\n- Provider name validated"
|
|
3730
|
+
},
|
|
3731
|
+
"UnlinkSocialAccountResponseDTO": {
|
|
3732
|
+
"type": "object",
|
|
3733
|
+
"properties": {
|
|
3734
|
+
"message": {
|
|
3735
|
+
"type": "string",
|
|
3736
|
+
"description": "Success message"
|
|
3737
|
+
}
|
|
3738
|
+
},
|
|
3739
|
+
"required": [
|
|
3740
|
+
"message"
|
|
3741
|
+
],
|
|
3742
|
+
"additionalProperties": false,
|
|
3743
|
+
"description": "Response DTO for unlinkSocialAccount"
|
|
3744
|
+
},
|
|
3745
|
+
"UpdateUserAttributesDTO": {
|
|
3746
|
+
"type": "object",
|
|
3747
|
+
"additionalProperties": false,
|
|
3748
|
+
"properties": {
|
|
3749
|
+
"username": {
|
|
3750
|
+
"type": "string",
|
|
3751
|
+
"description": "Optional username update\n\nValidation:\n- 3-50 characters\n- Alphanumeric, underscores, and hyphens only\n- Max 255 characters (DB limit)\n- Uniqueness checked in service layer\n\nSanitization:\n- Trimmed\n- Case preserved (username can be case-sensitive per config)"
|
|
3752
|
+
},
|
|
3753
|
+
"firstName": {
|
|
3754
|
+
"type": "string",
|
|
3755
|
+
"description": "Optional first name update\n\nValidation:\n- 1-100 characters\n- Max 100 characters (DB limit)\n\nSanitization:\n- Trimmed\n- Title case preserved"
|
|
3756
|
+
},
|
|
3757
|
+
"lastName": {
|
|
3758
|
+
"type": "string",
|
|
3759
|
+
"description": "Optional last name update\n\nValidation:\n- 1-100 characters\n- Max 100 characters (DB limit)\n\nSanitization:\n- Trimmed\n- Title case preserved"
|
|
3760
|
+
},
|
|
3761
|
+
"email": {
|
|
3762
|
+
"type": "string",
|
|
3763
|
+
"description": "Optional email address update\n\nValidation:\n- Valid email format (RFC 5322)\n- Max 255 characters (matches DB limit)\n- Uniqueness checked in service layer\n\nSanitization:\n- Trimmed and lowercased"
|
|
3764
|
+
},
|
|
3765
|
+
"phone": {
|
|
3766
|
+
"type": "string",
|
|
3767
|
+
"description": "Optional phone number update\n\nValidation:\n- E.164 format (international standard)\n- MUST start with + (required for security)\n- Max 20 characters (DB limit)\n- Uniqueness checked in service layer\n\nSanitization:\n- Whitespace removed\n- Only digits and leading + preserved\n\nSecurity:\n- Strict E.164 validation prevents SQL injection\n- Max length prevents oversized inputs"
|
|
3768
|
+
},
|
|
3769
|
+
"metadata": {
|
|
3770
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E",
|
|
3771
|
+
"description": "Optional metadata update (custom fields)\n\nBehavior:\n- Existing metadata is merged with new values\n- To delete a metadata key, set it to null\n- To update a value, provide the new value\n- To add a new key, include it in the object\n\nSecurity:\n- Validated in service layer if used\n- Max depth/size limits should be enforced"
|
|
3772
|
+
},
|
|
3773
|
+
"preferredMfaMethod": {
|
|
3774
|
+
"$ref": "#/components/schemas/MFADeviceMethod",
|
|
3775
|
+
"description": "Optional preferred MFA method\n\nSets the user's preferred MFA method for authentication. Must be one of the MFA device methods the user has configured.\n\nValidation:\n- Must be one of: totp, sms, email, passkey\n- Max 50 characters (matches typical method name length)"
|
|
3776
|
+
},
|
|
3777
|
+
"retainVerification": {
|
|
3778
|
+
"type": "boolean",
|
|
3779
|
+
"description": "Optional flag to retain verification status when updating email/phone\n\nWhen true:\n- Email verification status is preserved when email is updated\n- Phone verification status is preserved when phone is updated\n- Useful when verification was done externally or outside nauth-toolkit\n\nWhen false or undefined (default):\n- Email verification is reset to false when email is updated\n- Phone verification is reset to false when phone is updated\n- User must re-verify the new email/phone"
|
|
3780
|
+
}
|
|
3781
|
+
},
|
|
3782
|
+
"description": "Request DTO for updating user attributes (self-service, no sub)"
|
|
3783
|
+
},
|
|
3784
|
+
"UpdateVerifiedStatusRequestDTO": {
|
|
3785
|
+
"type": "object",
|
|
3786
|
+
"properties": {
|
|
3787
|
+
"sub": {
|
|
3788
|
+
"type": "string",
|
|
3789
|
+
"description": "User's unique identifier (UUID v4)\n\nValidation:\n- Must be a valid UUID v4 format\n- Matches DB constraint: char(36) or uuid\n\nSanitization:\n- Trimmed\n- Lowercased for consistency",
|
|
3790
|
+
"examples": [
|
|
3791
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
3792
|
+
]
|
|
3793
|
+
},
|
|
3794
|
+
"isEmailVerified": {
|
|
3795
|
+
"type": "boolean",
|
|
3796
|
+
"description": "Email verification status\n\nValidation:\n- If set to true, user must have an email address\n- If set to false, can be set even if email doesn't exist (default state)\n- Optional - only updates if provided",
|
|
3797
|
+
"examples": [
|
|
3798
|
+
true
|
|
3799
|
+
]
|
|
3800
|
+
},
|
|
3801
|
+
"isPhoneVerified": {
|
|
3802
|
+
"type": "boolean",
|
|
3803
|
+
"description": "Phone verification status\n\nValidation:\n- If set to true, user must have a phone number\n- If set to false, can be set even if phone doesn't exist (default state)\n- Optional - only updates if provided",
|
|
3804
|
+
"examples": [
|
|
3805
|
+
true
|
|
3806
|
+
]
|
|
3807
|
+
}
|
|
3808
|
+
},
|
|
3809
|
+
"required": [
|
|
3810
|
+
"sub"
|
|
3811
|
+
],
|
|
3812
|
+
"additionalProperties": false,
|
|
3813
|
+
"description": "Request DTO for updating verification status"
|
|
3814
|
+
},
|
|
3815
|
+
"UserUpdateDTO": {
|
|
3816
|
+
"type": "object",
|
|
3817
|
+
"properties": {
|
|
3818
|
+
"username": {
|
|
3819
|
+
"type": "string",
|
|
3820
|
+
"description": "Optional username update\n\nValidation:\n- 3-50 characters\n- Alphanumeric, underscores, and hyphens only\n- Max 255 characters (DB limit)\n- Uniqueness checked in service layer\n\nSanitization:\n- Trimmed\n- Case preserved (username can be case-sensitive per config)"
|
|
3821
|
+
},
|
|
3822
|
+
"firstName": {
|
|
3823
|
+
"type": "string",
|
|
3824
|
+
"description": "Optional first name update\n\nValidation:\n- 1-100 characters\n- Max 100 characters (DB limit)\n\nSanitization:\n- Trimmed\n- Title case preserved"
|
|
3825
|
+
},
|
|
3826
|
+
"lastName": {
|
|
3827
|
+
"type": "string",
|
|
3828
|
+
"description": "Optional last name update\n\nValidation:\n- 1-100 characters\n- Max 100 characters (DB limit)\n\nSanitization:\n- Trimmed\n- Title case preserved"
|
|
3829
|
+
},
|
|
3830
|
+
"email": {
|
|
3831
|
+
"type": "string",
|
|
3832
|
+
"description": "Optional email address update\n\nValidation:\n- Valid email format (RFC 5322)\n- Max 255 characters (matches DB limit)\n- Uniqueness checked in service layer\n\nSanitization:\n- Trimmed and lowercased"
|
|
3833
|
+
},
|
|
3834
|
+
"phone": {
|
|
3835
|
+
"type": "string",
|
|
3836
|
+
"description": "Optional phone number update\n\nValidation:\n- E.164 format (international standard)\n- MUST start with + (required for security)\n- Max 20 characters (DB limit)\n- Uniqueness checked in service layer\n\nSanitization:\n- Whitespace removed\n- Only digits and leading + preserved\n\nSecurity:\n- Strict E.164 validation prevents SQL injection\n- Max length prevents oversized inputs"
|
|
3837
|
+
},
|
|
3838
|
+
"metadata": {
|
|
3839
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E",
|
|
3840
|
+
"description": "Optional metadata update (custom fields)\n\nBehavior:\n- Existing metadata is merged with new values\n- To delete a metadata key, set it to null\n- To update a value, provide the new value\n- To add a new key, include it in the object\n\nSecurity:\n- Validated in service layer if used\n- Max depth/size limits should be enforced"
|
|
3841
|
+
},
|
|
3842
|
+
"preferredMfaMethod": {
|
|
3843
|
+
"$ref": "#/components/schemas/MFADeviceMethod",
|
|
3844
|
+
"description": "Optional preferred MFA method\n\nSets the user's preferred MFA method for authentication. Must be one of the MFA device methods the user has configured.\n\nValidation:\n- Must be one of: totp, sms, email, passkey\n- Max 50 characters (matches typical method name length)"
|
|
3845
|
+
},
|
|
3846
|
+
"retainVerification": {
|
|
3847
|
+
"type": "boolean",
|
|
3848
|
+
"description": "Optional flag to retain verification status when updating email/phone\n\nWhen true:\n- Email verification status is preserved when email is updated\n- Phone verification status is preserved when phone is updated\n- Useful when verification was done externally or outside nauth-toolkit\n\nWhen false or undefined (default):\n- Email verification is reset to false when email is updated\n- Phone verification is reset to false when phone is updated\n- User must re-verify the new email/phone"
|
|
3849
|
+
}
|
|
3850
|
+
},
|
|
3851
|
+
"additionalProperties": false,
|
|
3852
|
+
"description": "DTO for updating user attributes\n\nSecurity:\n- All fields validated against DB constraints\n- Input sanitization applied automatically\n- Email uniqueness checked in service layer\n- Phone uniqueness checked in service layer\n- Username uniqueness checked in service layer"
|
|
3853
|
+
},
|
|
3854
|
+
"ValidateAccessTokenDTO": {
|
|
3855
|
+
"type": "object",
|
|
3856
|
+
"properties": {
|
|
3857
|
+
"accessToken": {
|
|
3858
|
+
"type": "string",
|
|
3859
|
+
"description": "JWT access token to validate\n\nValidation:\n- Must be a string\n- Min 10 characters (minimum valid JWT length)\n- Max 2048 characters (prevents DoS, typical JWT is 200-500 chars)\n\nNote: Token format, signature, and expiration validated in service layer",
|
|
3860
|
+
"examples": [
|
|
3861
|
+
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U"
|
|
3862
|
+
]
|
|
3863
|
+
}
|
|
3864
|
+
},
|
|
3865
|
+
"required": [
|
|
3866
|
+
"accessToken"
|
|
3867
|
+
],
|
|
3868
|
+
"additionalProperties": false,
|
|
3869
|
+
"description": "Validate Access Token DTO\n\nUsed for validating JWT access tokens and decoding their payload.\n\nSecurity:\n- Token length validated (prevents DoS)\n- JWT tokens can be long, but we validate input length\n- Token is validated in service layer for format, signature, and expiration"
|
|
3870
|
+
},
|
|
3871
|
+
"ValidateAccessTokenResponseDTO": {
|
|
3872
|
+
"type": "object",
|
|
3873
|
+
"properties": {
|
|
3874
|
+
"valid": {
|
|
3875
|
+
"type": "boolean",
|
|
3876
|
+
"description": "Whether the token is valid\n\nIf true, payload will be present. If false, error and errorType will be present."
|
|
3877
|
+
},
|
|
3878
|
+
"payload": {
|
|
3879
|
+
"$ref": "#/components/schemas/JwtPayload",
|
|
3880
|
+
"description": "Decoded JWT payload (only if valid is true)\n\nContains all token claims including user information and session details."
|
|
3881
|
+
},
|
|
3882
|
+
"error": {
|
|
3883
|
+
"type": "string",
|
|
3884
|
+
"description": "Error message (only if valid is false)\n\nHuman-readable description of why validation failed."
|
|
3885
|
+
},
|
|
3886
|
+
"errorType": {
|
|
3887
|
+
"type": "string",
|
|
3888
|
+
"enum": [
|
|
3889
|
+
"expired",
|
|
3890
|
+
"invalid",
|
|
3891
|
+
"malformed",
|
|
3892
|
+
"blacklisted"
|
|
3893
|
+
],
|
|
3894
|
+
"description": "Error type for specific handling (only if valid is false)\n\nCategorizes the validation error for programmatic handling.\n\n- `expired`: Token has expired (exp claim < current time)\n- `invalid`: Token signature verification failed or invalid format\n- `malformed`: Token structure is invalid (not a proper JWT)\n- `blacklisted`: Token has been revoked or blacklisted"
|
|
3895
|
+
}
|
|
3896
|
+
},
|
|
3897
|
+
"required": [
|
|
3898
|
+
"valid"
|
|
3899
|
+
],
|
|
3900
|
+
"additionalProperties": false,
|
|
3901
|
+
"description": "Validate Access Token Response DTO\n\nResponse DTO for token validation operations."
|
|
3902
|
+
},
|
|
3903
|
+
"VerifyEmailResponseDTO": {
|
|
3904
|
+
"type": "object",
|
|
3905
|
+
"properties": {
|
|
3906
|
+
"message": {
|
|
3907
|
+
"type": "string",
|
|
3908
|
+
"description": "Success message"
|
|
3909
|
+
}
|
|
3910
|
+
},
|
|
3911
|
+
"required": [
|
|
3912
|
+
"message"
|
|
3913
|
+
],
|
|
3914
|
+
"additionalProperties": false,
|
|
3915
|
+
"description": "Response DTO for verifyEmailWithCode and verifyEmailWithToken"
|
|
3916
|
+
},
|
|
3917
|
+
"VerifyEmailWithCodeDTO": {
|
|
3918
|
+
"type": "object",
|
|
3919
|
+
"properties": {
|
|
3920
|
+
"email": {
|
|
3921
|
+
"type": "string",
|
|
3922
|
+
"description": "User's email address Must match the email used during signup\n\nValidation:\n- Valid email format (RFC 5322)\n- Max 255 characters (matches DB column limit)\n- Automatically trimmed and lowercased\n\nSanitization:\n- Removes leading/trailing whitespace\n- Converts to lowercase for case-insensitive matching"
|
|
3923
|
+
},
|
|
3924
|
+
"code": {
|
|
3925
|
+
"type": "string",
|
|
3926
|
+
"description": "6-digit verification code from email\n\nValidation:\n- Must be numeric string (digits only)\n- Exactly 6 characters long\n- Fixed length prevents timing attacks\n\nSanitization:\n- Removes all whitespace (users might copy \"123 456\")\n- Removes non-digit characters"
|
|
3927
|
+
},
|
|
3928
|
+
"challengeSessionId": {
|
|
3929
|
+
"type": "number",
|
|
3930
|
+
"description": "Challenge session ID (internal use) Optional - used internally to link verification to specific challenge session. Provides security by ensuring codes are only valid for the session they were created for.\n\nValidation:\n- Must be a positive integer if provided\n- Optional (for backward compatibility and direct verification flows)"
|
|
3931
|
+
}
|
|
3932
|
+
},
|
|
3933
|
+
"required": [
|
|
3934
|
+
"email",
|
|
3935
|
+
"code"
|
|
3936
|
+
],
|
|
3937
|
+
"additionalProperties": false,
|
|
3938
|
+
"description": "DTO for verifying email with code (6-digit OTP)\n\nSecurity:\n- Email must be valid format and match DB limits\n- Code must be exactly 6 digits (no more, no less)\n- All fields are required (no optional fields to prevent attacks)\n- Input sanitization applied automatically"
|
|
3939
|
+
},
|
|
3940
|
+
"VerifyEmailWithTokenDTO": {
|
|
3941
|
+
"type": "object",
|
|
3942
|
+
"properties": {
|
|
3943
|
+
"token": {
|
|
3944
|
+
"type": "string",
|
|
3945
|
+
"description": "Verification token from email link\n\nValidation:\n- Exactly 64 hexadecimal characters (SHA-256 hash output)\n- Only 0-9 and a-f characters allowed\n- Case-insensitive\n\nSanitization:\n- Removes whitespace\n- Converts to lowercase for consistent hashing"
|
|
3946
|
+
}
|
|
3947
|
+
},
|
|
3948
|
+
"required": [
|
|
3949
|
+
"token"
|
|
3950
|
+
],
|
|
3951
|
+
"additionalProperties": false,
|
|
3952
|
+
"description": "DTO for verifying email with URL token\n\nSecurity:\n- Token must be valid hex format\n- Exact length enforced (64 chars = 32 bytes SHA-256 hash)\n- No SQL injection or XSS possible\n- Input sanitization prevents malformed tokens"
|
|
3953
|
+
},
|
|
3954
|
+
"VerifyMFACodeDTO": {
|
|
3955
|
+
"type": "object",
|
|
3956
|
+
"properties": {
|
|
3957
|
+
"sub": {
|
|
3958
|
+
"type": "string",
|
|
3959
|
+
"description": "User's unique identifier (UUID v4)\n\nValidation:\n- Must be a valid UUID v4 format\n- Matches DB constraint: char(36) or uuid\n\nSanitization:\n- Trimmed\n- Lowercased for consistency",
|
|
3960
|
+
"examples": [
|
|
3961
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
3962
|
+
]
|
|
3963
|
+
},
|
|
3964
|
+
"methodName": {
|
|
3965
|
+
"type": "string",
|
|
3966
|
+
"description": "MFA method name\n\nValidation:\n- Must be one of: totp, sms, email, passkey, backup\n- Max 50 characters\n\nSanitization:\n- Trimmed and lowercased",
|
|
3967
|
+
"examples": [
|
|
3968
|
+
"totp"
|
|
3969
|
+
]
|
|
3970
|
+
},
|
|
3971
|
+
"code": {
|
|
3972
|
+
"anyOf": [
|
|
3973
|
+
{
|
|
3974
|
+
"type": "string"
|
|
3975
|
+
},
|
|
3976
|
+
{
|
|
3977
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E"
|
|
3978
|
+
}
|
|
3979
|
+
],
|
|
3980
|
+
"description": "Verification code or credential (provider-specific)\n\nValidation:\n- Must be a string or object depending on method\n- For TOTP/SMS/Email: string code\n- For Passkey: credential object\n- For Backup: string code"
|
|
3981
|
+
},
|
|
3982
|
+
"deviceId": {
|
|
3983
|
+
"type": "number",
|
|
3984
|
+
"description": "Optional device ID\n\nValidation:\n- Must be a positive integer if provided"
|
|
3985
|
+
}
|
|
3986
|
+
},
|
|
3987
|
+
"required": [
|
|
3988
|
+
"sub",
|
|
3989
|
+
"methodName",
|
|
3990
|
+
"code"
|
|
3991
|
+
],
|
|
3992
|
+
"additionalProperties": false,
|
|
3993
|
+
"description": "DTO for verifying MFA code"
|
|
3994
|
+
},
|
|
3995
|
+
"VerifyMFACodeResponseDTO": {
|
|
3996
|
+
"type": "object",
|
|
3997
|
+
"properties": {
|
|
3998
|
+
"valid": {
|
|
3999
|
+
"type": "boolean",
|
|
4000
|
+
"description": "Whether verification succeeded"
|
|
4001
|
+
}
|
|
4002
|
+
},
|
|
4003
|
+
"required": [
|
|
4004
|
+
"valid"
|
|
4005
|
+
],
|
|
4006
|
+
"additionalProperties": false,
|
|
4007
|
+
"description": "Response DTO for MFA code verification"
|
|
4008
|
+
},
|
|
4009
|
+
"VerifyPhoneResponseDTO": {
|
|
4010
|
+
"type": "object",
|
|
4011
|
+
"properties": {
|
|
4012
|
+
"message": {
|
|
4013
|
+
"type": "string",
|
|
4014
|
+
"description": "Success message"
|
|
4015
|
+
}
|
|
4016
|
+
},
|
|
4017
|
+
"required": [
|
|
4018
|
+
"message"
|
|
4019
|
+
],
|
|
4020
|
+
"additionalProperties": false,
|
|
4021
|
+
"description": "Response DTO for verifyPhoneWithCode and verifyPhoneWithCodeBySub"
|
|
4022
|
+
},
|
|
4023
|
+
"VerifyPhoneWithCodeBySubDTO": {
|
|
4024
|
+
"type": "object",
|
|
4025
|
+
"properties": {
|
|
4026
|
+
"sub": {
|
|
4027
|
+
"type": "string",
|
|
4028
|
+
"description": "User's external identifier (sub/UUID v4)\n\nValidation:\n- Must be a valid UUID v4 format\n- Matches DB constraint: char(36) or uuid\n\nSanitization:\n- Trimmed and lowercased for consistency",
|
|
4029
|
+
"examples": [
|
|
4030
|
+
"a21b654c-2746-4168-acee-c175083a65cd"
|
|
4031
|
+
]
|
|
4032
|
+
},
|
|
4033
|
+
"code": {
|
|
4034
|
+
"type": "string",
|
|
4035
|
+
"description": "6-digit verification code\n\nValidation:\n- Must be a numeric string\n- Exactly 6 digits",
|
|
4036
|
+
"examples": [
|
|
4037
|
+
"123456"
|
|
4038
|
+
]
|
|
4039
|
+
},
|
|
4040
|
+
"challengeSessionId": {
|
|
4041
|
+
"type": "number",
|
|
4042
|
+
"description": "Challenge session ID (internal use) Optional - used internally to link verification to specific challenge session. Provides security by ensuring codes are only valid for the session they were created for.\n\nValidation:\n- Must be a positive integer if provided\n- Optional (for backward compatibility and direct verification flows)"
|
|
4043
|
+
}
|
|
4044
|
+
},
|
|
4045
|
+
"required": [
|
|
4046
|
+
"sub",
|
|
4047
|
+
"code"
|
|
4048
|
+
],
|
|
4049
|
+
"additionalProperties": false,
|
|
4050
|
+
"description": "Verify Phone with Code by User Sub DTO\n\nUsed for phone verification with 6-digit OTP code when allowing duplicate phones. Requires user sub to identify which user's phone to verify.\n\nSecurity:\n- UUID format validated (prevents injection)\n- Code format validated (6 digits)"
|
|
4051
|
+
},
|
|
4052
|
+
"VerifyPhoneWithCodeDTO": {
|
|
4053
|
+
"type": "object",
|
|
4054
|
+
"properties": {
|
|
4055
|
+
"phone": {
|
|
4056
|
+
"type": "string",
|
|
4057
|
+
"description": "User's phone number in E.164 format\n\nValidation:\n- Must be a string\n- Must match E.164 format: +[country code][number]\n- Max 20 characters (matches DB constraint: varchar(20))\n\nSanitization:\n- Trimmed\n- Whitespace removed",
|
|
4058
|
+
"examples": [
|
|
4059
|
+
"+1234567890"
|
|
4060
|
+
]
|
|
4061
|
+
},
|
|
4062
|
+
"code": {
|
|
4063
|
+
"type": "string",
|
|
4064
|
+
"description": "6-digit verification code\n\nValidation:\n- Must be a string\n- Exactly 6 digits (numeric only)\n- No letters, spaces, or special characters\n- Fixed length prevents timing attacks\n\nSanitization:\n- Removes all whitespace (users might copy \"123 456\")\n- Ensures only numeric string",
|
|
4065
|
+
"examples": [
|
|
4066
|
+
"123456"
|
|
4067
|
+
]
|
|
4068
|
+
},
|
|
4069
|
+
"challengeSessionId": {
|
|
4070
|
+
"type": "number",
|
|
4071
|
+
"description": "Challenge session ID (internal use) Optional - used internally to link verification to specific challenge session. Provides security by ensuring codes are only valid for the session they were created for.\n\nValidation:\n- Must be a positive integer if provided\n- Optional (for backward compatibility and direct verification flows)"
|
|
4072
|
+
}
|
|
4073
|
+
},
|
|
4074
|
+
"required": [
|
|
4075
|
+
"phone",
|
|
4076
|
+
"code"
|
|
4077
|
+
],
|
|
4078
|
+
"additionalProperties": false,
|
|
4079
|
+
"description": "Verify Phone with Code DTO\n\nUsed for phone verification with 6-digit OTP code.\n\nSecurity:\n- Phone validated against E.164 format (prevents SQL injection)\n- Code validated for exact 6 digits\n- All fields match DB constraints"
|
|
4080
|
+
},
|
|
4081
|
+
"VerifyTokenDTO": {
|
|
4082
|
+
"type": "object",
|
|
4083
|
+
"properties": {
|
|
4084
|
+
"provider": {
|
|
4085
|
+
"type": "string",
|
|
4086
|
+
"description": "Social provider name\n\nValidation:\n- Must be one of: 'google', 'apple', 'facebook'\n- Max 50 characters\n\nSanitization:\n- Trimmed and lowercased"
|
|
4087
|
+
},
|
|
4088
|
+
"idToken": {
|
|
4089
|
+
"type": "string",
|
|
4090
|
+
"description": "ID token (JWT) from native SDK\n\nRequired for:\n- google (always)\n- apple (always)\n- facebook Limited Login (when accessToken is not provided)\n\nValidation:\n- Required for google/apple\n- Required for facebook only when accessToken is NOT provided\n- Must be non-empty string\n- Max 10000 characters (JWT tokens can be large)\n\nSanitization:\n- Trimmed"
|
|
4091
|
+
},
|
|
4092
|
+
"accessToken": {
|
|
4093
|
+
"type": "string",
|
|
4094
|
+
"description": "Access token (opaque) from native SDK\n\nRequired for:\n- facebook classic login (when idToken is not provided)\n\nOptional for:\n- google (provided alongside idToken)\n\nValidation:\n- Required for facebook only when idToken is NOT provided\n- Must be non-empty string if provided\n- Max 2000 characters\n\nSanitization:\n- Trimmed"
|
|
4095
|
+
},
|
|
4096
|
+
"profileData": {
|
|
4097
|
+
"$ref": "#/components/schemas/Record%3Cstring%2Cunknown%3E",
|
|
4098
|
+
"description": "Optional profile data from native SDK\n\nSome providers (e.g., Apple) only provide user profile data on first sign-in. Clients should capture and send this data for proper user creation.\n\nValidation:\n- Optional\n- Must be a valid object if provided"
|
|
4099
|
+
}
|
|
4100
|
+
},
|
|
4101
|
+
"required": [
|
|
4102
|
+
"provider"
|
|
4103
|
+
],
|
|
4104
|
+
"additionalProperties": false,
|
|
4105
|
+
"description": "DTO for verifying social authentication token from native mobile apps\n\nUsed when mobile apps (iOS, Android) use native SDKs (e.g., Google Sign-In SDK, Sign in with Apple, Facebook SDK) and need to verify tokens on the backend.\n\nSupports provider-aware validation:\n- **google**: requires `idToken`, `accessToken` optional\n- **apple**: requires `idToken`, `accessToken` optional, `profileData` optional\n- **facebook**: - Classic login: requires `accessToken` (when `idToken` not provided) - Limited Login (OIDC): requires `idToken` (JWT, when `accessToken` not provided)\n\nSecurity:\n- Provider allow-list enforced\n- Per-provider required fields validated\n- Token signature verification performed\n- Token must be fresh (not expired)"
|
|
4106
|
+
}
|
|
4107
|
+
}
|
|
4108
|
+
}
|
|
4109
|
+
}
|