@djangocfg/api 2.1.360 → 2.1.361
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/auth-server.cjs +1 -0
- package/dist/auth-server.cjs.map +1 -1
- package/dist/auth-server.mjs +1 -0
- package/dist/auth-server.mjs.map +1 -1
- package/dist/auth.cjs +1 -0
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.mjs +1 -0
- package/dist/auth.mjs.map +1 -1
- package/dist/clients.cjs +1 -0
- package/dist/clients.cjs.map +1 -1
- package/dist/clients.mjs +1 -0
- package/dist/clients.mjs.map +1 -1
- package/dist/hooks.cjs +1 -0
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.mjs +1 -0
- package/dist/hooks.mjs.map +1 -1
- package/dist/index.cjs +1 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +1 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/_api/generated/_cfg_accounts/openapi.json +1811 -0
- package/src/_api/generated/_cfg_centrifugo/openapi.json +132 -0
- package/src/_api/generated/_cfg_totp/openapi.json +927 -0
- package/src/_api/generated/helpers/auth.ts +13 -2
- package/src/_api/generated/openapi.json +2789 -0
|
@@ -0,0 +1,2789 @@
|
|
|
1
|
+
{
|
|
2
|
+
"openapi": "3.1.0",
|
|
3
|
+
"info": {
|
|
4
|
+
"title": "Django CFG API",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"description": "RESTful API with modern architecture"
|
|
7
|
+
},
|
|
8
|
+
"paths": {
|
|
9
|
+
"/cfg/accounts/api-key/": {
|
|
10
|
+
"get": {
|
|
11
|
+
"operationId": "cfg_accounts_api_key_retrieve",
|
|
12
|
+
"description": "Retrieve the current user's API key (masked) and metadata.",
|
|
13
|
+
"summary": "Get API key details",
|
|
14
|
+
"tags": [
|
|
15
|
+
"cfg_accounts_api_key"
|
|
16
|
+
],
|
|
17
|
+
"security": [
|
|
18
|
+
{
|
|
19
|
+
"jwtAuth": []
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"cookieAuth": []
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"responses": {
|
|
26
|
+
"200": {
|
|
27
|
+
"content": {
|
|
28
|
+
"application/json": {
|
|
29
|
+
"schema": {
|
|
30
|
+
"$ref": "#/components/schemas/APIKey"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"description": ""
|
|
35
|
+
},
|
|
36
|
+
"401": {
|
|
37
|
+
"content": {
|
|
38
|
+
"application/json": {
|
|
39
|
+
"schema": {
|
|
40
|
+
"description": "Authentication credentials were not provided."
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"description": ""
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"x-async-capable": false
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"/cfg/accounts/api-key/regenerate/": {
|
|
51
|
+
"post": {
|
|
52
|
+
"operationId": "cfg_accounts_api_key_regenerate_create",
|
|
53
|
+
"description": "Generate a new API key. The full key is returned only once.",
|
|
54
|
+
"summary": "Regenerate API key",
|
|
55
|
+
"tags": [
|
|
56
|
+
"cfg_accounts_api_key"
|
|
57
|
+
],
|
|
58
|
+
"requestBody": {
|
|
59
|
+
"content": {
|
|
60
|
+
"application/json": {
|
|
61
|
+
"schema": {
|
|
62
|
+
"$ref": "#/components/schemas/APIKeyRequest"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"required": true
|
|
67
|
+
},
|
|
68
|
+
"security": [
|
|
69
|
+
{
|
|
70
|
+
"jwtAuth": []
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"cookieAuth": []
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
"responses": {
|
|
77
|
+
"200": {
|
|
78
|
+
"content": {
|
|
79
|
+
"application/json": {
|
|
80
|
+
"schema": {
|
|
81
|
+
"$ref": "#/components/schemas/APIKeyRegenerate"
|
|
82
|
+
},
|
|
83
|
+
"examples": {
|
|
84
|
+
"RegenerateResponse": {
|
|
85
|
+
"value": {
|
|
86
|
+
"key": "d0b45e78-1234-5678-9abc-def012345678",
|
|
87
|
+
"reissued_at": "2024-01-15T10:30:00Z"
|
|
88
|
+
},
|
|
89
|
+
"summary": "Regenerate Response"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
"description": ""
|
|
95
|
+
},
|
|
96
|
+
"401": {
|
|
97
|
+
"content": {
|
|
98
|
+
"application/json": {
|
|
99
|
+
"schema": {
|
|
100
|
+
"description": "Authentication credentials were not provided."
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
"description": ""
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"x-async-capable": false
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
"/cfg/accounts/api-key/test/": {
|
|
111
|
+
"post": {
|
|
112
|
+
"operationId": "cfg_accounts_api_key_test_create",
|
|
113
|
+
"description": "Test whether an API key is valid without consuming it.",
|
|
114
|
+
"summary": "Test API key",
|
|
115
|
+
"tags": [
|
|
116
|
+
"cfg_accounts_api_key"
|
|
117
|
+
],
|
|
118
|
+
"requestBody": {
|
|
119
|
+
"content": {
|
|
120
|
+
"application/json": {
|
|
121
|
+
"schema": {
|
|
122
|
+
"$ref": "#/components/schemas/APIKeyTestRequest"
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
"required": true
|
|
127
|
+
},
|
|
128
|
+
"security": [
|
|
129
|
+
{
|
|
130
|
+
"jwtAuth": []
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"cookieAuth": []
|
|
134
|
+
}
|
|
135
|
+
],
|
|
136
|
+
"responses": {
|
|
137
|
+
"200": {
|
|
138
|
+
"content": {
|
|
139
|
+
"application/json": {
|
|
140
|
+
"schema": {
|
|
141
|
+
"$ref": "#/components/schemas/APIKeyTestResult"
|
|
142
|
+
},
|
|
143
|
+
"examples": {
|
|
144
|
+
"ValidKey": {
|
|
145
|
+
"value": {
|
|
146
|
+
"valid": true,
|
|
147
|
+
"user_id": "42"
|
|
148
|
+
},
|
|
149
|
+
"summary": "Valid Key"
|
|
150
|
+
},
|
|
151
|
+
"InvalidKey": {
|
|
152
|
+
"value": {
|
|
153
|
+
"valid": false,
|
|
154
|
+
"user_id": null
|
|
155
|
+
},
|
|
156
|
+
"summary": "Invalid Key"
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
"description": ""
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
"x-async-capable": false
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
"/cfg/accounts/oauth/connections/": {
|
|
168
|
+
"get": {
|
|
169
|
+
"operationId": "cfg_accounts_oauth_connections_list",
|
|
170
|
+
"description": "Get all OAuth connections for the current user.",
|
|
171
|
+
"summary": "List OAuth connections",
|
|
172
|
+
"tags": [
|
|
173
|
+
"cfg_accounts_oauth"
|
|
174
|
+
],
|
|
175
|
+
"security": [
|
|
176
|
+
{
|
|
177
|
+
"apiKeyAuth": []
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"jwtAuthWithLastLogin": []
|
|
181
|
+
}
|
|
182
|
+
],
|
|
183
|
+
"responses": {
|
|
184
|
+
"200": {
|
|
185
|
+
"content": {
|
|
186
|
+
"application/json": {
|
|
187
|
+
"schema": {
|
|
188
|
+
"$ref": "#/components/schemas/cfg_accounts_oauth_connections_response_200_AutoRef"
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
"description": ""
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
"x-async-capable": false
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
"/cfg/accounts/oauth/disconnect/": {
|
|
199
|
+
"post": {
|
|
200
|
+
"operationId": "cfg_accounts_oauth_disconnect_create",
|
|
201
|
+
"description": "Remove OAuth connection for the specified provider.",
|
|
202
|
+
"summary": "Disconnect OAuth provider",
|
|
203
|
+
"tags": [
|
|
204
|
+
"cfg_accounts_oauth"
|
|
205
|
+
],
|
|
206
|
+
"requestBody": {
|
|
207
|
+
"content": {
|
|
208
|
+
"application/json": {
|
|
209
|
+
"schema": {
|
|
210
|
+
"$ref": "#/components/schemas/OAuthDisconnectRequestRequest"
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
"required": true
|
|
215
|
+
},
|
|
216
|
+
"security": [
|
|
217
|
+
{
|
|
218
|
+
"apiKeyAuth": []
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
"jwtAuthWithLastLogin": []
|
|
222
|
+
}
|
|
223
|
+
],
|
|
224
|
+
"responses": {
|
|
225
|
+
"200": {
|
|
226
|
+
"content": {
|
|
227
|
+
"application/json": {
|
|
228
|
+
"schema": {
|
|
229
|
+
"$ref": "#/components/schemas/cfg_accounts_oauth_disconnect_response_200_AutoRef"
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
"description": ""
|
|
234
|
+
},
|
|
235
|
+
"400": {
|
|
236
|
+
"content": {
|
|
237
|
+
"application/json": {
|
|
238
|
+
"schema": {
|
|
239
|
+
"$ref": "#/components/schemas/OAuthError"
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
"description": ""
|
|
244
|
+
},
|
|
245
|
+
"404": {
|
|
246
|
+
"content": {
|
|
247
|
+
"application/json": {
|
|
248
|
+
"schema": {
|
|
249
|
+
"$ref": "#/components/schemas/OAuthError"
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
"description": ""
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
"x-async-capable": false
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
"/cfg/accounts/oauth/github/authorize/": {
|
|
260
|
+
"post": {
|
|
261
|
+
"operationId": "cfg_accounts_oauth_github_authorize_create",
|
|
262
|
+
"description": "Generate GitHub OAuth authorization URL. Redirect user to this URL to start authentication.",
|
|
263
|
+
"summary": "Start GitHub OAuth",
|
|
264
|
+
"tags": [
|
|
265
|
+
"cfg_accounts_oauth"
|
|
266
|
+
],
|
|
267
|
+
"requestBody": {
|
|
268
|
+
"content": {
|
|
269
|
+
"application/json": {
|
|
270
|
+
"schema": {
|
|
271
|
+
"$ref": "#/components/schemas/OAuthAuthorizeRequestRequest"
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
"security": [
|
|
277
|
+
{}
|
|
278
|
+
],
|
|
279
|
+
"responses": {
|
|
280
|
+
"200": {
|
|
281
|
+
"content": {
|
|
282
|
+
"application/json": {
|
|
283
|
+
"schema": {
|
|
284
|
+
"$ref": "#/components/schemas/OAuthAuthorizeResponse"
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
"description": ""
|
|
289
|
+
},
|
|
290
|
+
"503": {
|
|
291
|
+
"content": {
|
|
292
|
+
"application/json": {
|
|
293
|
+
"schema": {
|
|
294
|
+
"$ref": "#/components/schemas/OAuthError"
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
},
|
|
298
|
+
"description": ""
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
"x-async-capable": false
|
|
302
|
+
}
|
|
303
|
+
},
|
|
304
|
+
"/cfg/accounts/oauth/github/callback/": {
|
|
305
|
+
"post": {
|
|
306
|
+
"operationId": "cfg_accounts_oauth_github_callback_create",
|
|
307
|
+
"description": "Exchange authorization code for JWT tokens. Call this after GitHub redirects back with code.",
|
|
308
|
+
"summary": "Complete GitHub OAuth",
|
|
309
|
+
"tags": [
|
|
310
|
+
"cfg_accounts_oauth"
|
|
311
|
+
],
|
|
312
|
+
"requestBody": {
|
|
313
|
+
"content": {
|
|
314
|
+
"application/json": {
|
|
315
|
+
"schema": {
|
|
316
|
+
"$ref": "#/components/schemas/OAuthCallbackRequestRequest"
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
},
|
|
320
|
+
"required": true
|
|
321
|
+
},
|
|
322
|
+
"security": [
|
|
323
|
+
{}
|
|
324
|
+
],
|
|
325
|
+
"responses": {
|
|
326
|
+
"200": {
|
|
327
|
+
"content": {
|
|
328
|
+
"application/json": {
|
|
329
|
+
"schema": {
|
|
330
|
+
"$ref": "#/components/schemas/OAuthTokenResponse"
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
"description": ""
|
|
335
|
+
},
|
|
336
|
+
"400": {
|
|
337
|
+
"content": {
|
|
338
|
+
"application/json": {
|
|
339
|
+
"schema": {
|
|
340
|
+
"$ref": "#/components/schemas/OAuthError"
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
},
|
|
344
|
+
"description": ""
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
"x-async-capable": false
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
"/cfg/accounts/oauth/providers/": {
|
|
351
|
+
"get": {
|
|
352
|
+
"operationId": "cfg_accounts_oauth_providers_retrieve",
|
|
353
|
+
"description": "Get list of available OAuth providers for authentication.",
|
|
354
|
+
"summary": "List OAuth providers",
|
|
355
|
+
"tags": [
|
|
356
|
+
"cfg_accounts_oauth"
|
|
357
|
+
],
|
|
358
|
+
"security": [
|
|
359
|
+
{}
|
|
360
|
+
],
|
|
361
|
+
"responses": {
|
|
362
|
+
"200": {
|
|
363
|
+
"content": {
|
|
364
|
+
"application/json": {
|
|
365
|
+
"schema": {
|
|
366
|
+
"$ref": "#/components/schemas/OAuthProvidersResponse"
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
},
|
|
370
|
+
"description": ""
|
|
371
|
+
}
|
|
372
|
+
},
|
|
373
|
+
"x-async-capable": false
|
|
374
|
+
}
|
|
375
|
+
},
|
|
376
|
+
"/cfg/accounts/otp/request/": {
|
|
377
|
+
"post": {
|
|
378
|
+
"operationId": "cfg_accounts_otp_request_create",
|
|
379
|
+
"description": "Request OTP code to email.",
|
|
380
|
+
"tags": [
|
|
381
|
+
"cfg_accounts"
|
|
382
|
+
],
|
|
383
|
+
"requestBody": {
|
|
384
|
+
"content": {
|
|
385
|
+
"application/json": {
|
|
386
|
+
"schema": {
|
|
387
|
+
"$ref": "#/components/schemas/OTPRequestRequest"
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
"required": true
|
|
392
|
+
},
|
|
393
|
+
"security": [
|
|
394
|
+
{
|
|
395
|
+
"apiKeyAuth": []
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
"jwtAuthWithLastLogin": []
|
|
399
|
+
},
|
|
400
|
+
{}
|
|
401
|
+
],
|
|
402
|
+
"responses": {
|
|
403
|
+
"200": {
|
|
404
|
+
"content": {
|
|
405
|
+
"application/json": {
|
|
406
|
+
"schema": {
|
|
407
|
+
"$ref": "#/components/schemas/OTPRequestResponse"
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
},
|
|
411
|
+
"description": ""
|
|
412
|
+
},
|
|
413
|
+
"400": {
|
|
414
|
+
"content": {
|
|
415
|
+
"application/json": {
|
|
416
|
+
"schema": {
|
|
417
|
+
"$ref": "#/components/schemas/OTPErrorResponse"
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
},
|
|
421
|
+
"description": ""
|
|
422
|
+
},
|
|
423
|
+
"429": {
|
|
424
|
+
"content": {
|
|
425
|
+
"application/json": {
|
|
426
|
+
"schema": {
|
|
427
|
+
"$ref": "#/components/schemas/OTPErrorResponse"
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
},
|
|
431
|
+
"description": ""
|
|
432
|
+
},
|
|
433
|
+
"500": {
|
|
434
|
+
"content": {
|
|
435
|
+
"application/json": {
|
|
436
|
+
"schema": {
|
|
437
|
+
"$ref": "#/components/schemas/OTPErrorResponse"
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
},
|
|
441
|
+
"description": ""
|
|
442
|
+
}
|
|
443
|
+
},
|
|
444
|
+
"x-async-capable": false
|
|
445
|
+
}
|
|
446
|
+
},
|
|
447
|
+
"/cfg/accounts/otp/verify/": {
|
|
448
|
+
"post": {
|
|
449
|
+
"operationId": "cfg_accounts_otp_verify_create",
|
|
450
|
+
"description": "Verify OTP code and return JWT tokens or 2FA session.\n\nIf user has 2FA enabled:\n- Returns requires_2fa=True with session_id\n- Client must complete 2FA verification at /cfg/totp/verify/\n\nIf user has no 2FA:\n- Returns JWT tokens and user data directly",
|
|
451
|
+
"tags": [
|
|
452
|
+
"cfg_accounts"
|
|
453
|
+
],
|
|
454
|
+
"requestBody": {
|
|
455
|
+
"content": {
|
|
456
|
+
"application/json": {
|
|
457
|
+
"schema": {
|
|
458
|
+
"$ref": "#/components/schemas/OTPVerifyRequest"
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
},
|
|
462
|
+
"required": true
|
|
463
|
+
},
|
|
464
|
+
"security": [
|
|
465
|
+
{
|
|
466
|
+
"apiKeyAuth": []
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
"jwtAuthWithLastLogin": []
|
|
470
|
+
},
|
|
471
|
+
{}
|
|
472
|
+
],
|
|
473
|
+
"responses": {
|
|
474
|
+
"200": {
|
|
475
|
+
"content": {
|
|
476
|
+
"application/json": {
|
|
477
|
+
"schema": {
|
|
478
|
+
"$ref": "#/components/schemas/OTPVerifyResponse"
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
},
|
|
482
|
+
"description": ""
|
|
483
|
+
},
|
|
484
|
+
"401": {
|
|
485
|
+
"content": {
|
|
486
|
+
"application/json": {
|
|
487
|
+
"schema": {
|
|
488
|
+
"$ref": "#/components/schemas/OTPErrorResponse"
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
},
|
|
492
|
+
"description": ""
|
|
493
|
+
},
|
|
494
|
+
"429": {
|
|
495
|
+
"content": {
|
|
496
|
+
"application/json": {
|
|
497
|
+
"schema": {
|
|
498
|
+
"$ref": "#/components/schemas/OTPErrorResponse"
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
},
|
|
502
|
+
"description": ""
|
|
503
|
+
}
|
|
504
|
+
},
|
|
505
|
+
"x-async-capable": false
|
|
506
|
+
}
|
|
507
|
+
},
|
|
508
|
+
"/cfg/accounts/profile/": {
|
|
509
|
+
"get": {
|
|
510
|
+
"operationId": "cfg_accounts_profile_retrieve",
|
|
511
|
+
"description": "Retrieve the current authenticated user's profile information.",
|
|
512
|
+
"summary": "Get current user profile",
|
|
513
|
+
"tags": [
|
|
514
|
+
"cfg_accounts_profile"
|
|
515
|
+
],
|
|
516
|
+
"security": [
|
|
517
|
+
{
|
|
518
|
+
"jwtAuth": []
|
|
519
|
+
},
|
|
520
|
+
{
|
|
521
|
+
"cookieAuth": []
|
|
522
|
+
}
|
|
523
|
+
],
|
|
524
|
+
"responses": {
|
|
525
|
+
"200": {
|
|
526
|
+
"content": {
|
|
527
|
+
"application/json": {
|
|
528
|
+
"schema": {
|
|
529
|
+
"$ref": "#/components/schemas/User"
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
},
|
|
533
|
+
"description": ""
|
|
534
|
+
},
|
|
535
|
+
"401": {
|
|
536
|
+
"content": {
|
|
537
|
+
"application/json": {
|
|
538
|
+
"schema": {
|
|
539
|
+
"description": "Authentication credentials were not provided."
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
},
|
|
543
|
+
"description": ""
|
|
544
|
+
}
|
|
545
|
+
},
|
|
546
|
+
"x-async-capable": false
|
|
547
|
+
}
|
|
548
|
+
},
|
|
549
|
+
"/cfg/accounts/profile/avatar/": {
|
|
550
|
+
"post": {
|
|
551
|
+
"operationId": "cfg_accounts_profile_avatar_create",
|
|
552
|
+
"description": "Upload avatar image for the current authenticated user. Accepts multipart/form-data with 'avatar' field.",
|
|
553
|
+
"summary": "Upload user avatar",
|
|
554
|
+
"tags": [
|
|
555
|
+
"cfg_accounts_profile"
|
|
556
|
+
],
|
|
557
|
+
"requestBody": {
|
|
558
|
+
"content": {
|
|
559
|
+
"multipart/form-data": {
|
|
560
|
+
"schema": {
|
|
561
|
+
"type": "object",
|
|
562
|
+
"properties": {
|
|
563
|
+
"avatar": {
|
|
564
|
+
"type": "string",
|
|
565
|
+
"format": "binary",
|
|
566
|
+
"description": "Avatar image file (JPEG, PNG, GIF, WebP, max 5MB)"
|
|
567
|
+
}
|
|
568
|
+
},
|
|
569
|
+
"required": [
|
|
570
|
+
"avatar"
|
|
571
|
+
]
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
},
|
|
576
|
+
"security": [
|
|
577
|
+
{
|
|
578
|
+
"apiKeyAuth": []
|
|
579
|
+
},
|
|
580
|
+
{
|
|
581
|
+
"jwtAuthWithLastLogin": []
|
|
582
|
+
}
|
|
583
|
+
],
|
|
584
|
+
"responses": {
|
|
585
|
+
"200": {
|
|
586
|
+
"content": {
|
|
587
|
+
"application/json": {
|
|
588
|
+
"schema": {
|
|
589
|
+
"$ref": "#/components/schemas/User"
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
},
|
|
593
|
+
"description": ""
|
|
594
|
+
},
|
|
595
|
+
"400": {
|
|
596
|
+
"content": {
|
|
597
|
+
"application/json": {
|
|
598
|
+
"schema": {
|
|
599
|
+
"description": "Invalid file or validation error."
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
},
|
|
603
|
+
"description": ""
|
|
604
|
+
},
|
|
605
|
+
"401": {
|
|
606
|
+
"content": {
|
|
607
|
+
"application/json": {
|
|
608
|
+
"schema": {
|
|
609
|
+
"description": "Authentication credentials were not provided."
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
},
|
|
613
|
+
"description": ""
|
|
614
|
+
}
|
|
615
|
+
},
|
|
616
|
+
"x-async-capable": false
|
|
617
|
+
}
|
|
618
|
+
},
|
|
619
|
+
"/cfg/accounts/profile/delete/": {
|
|
620
|
+
"post": {
|
|
621
|
+
"operationId": "cfg_accounts_profile_delete_create",
|
|
622
|
+
"description": "\n Permanently delete the current user's account.\n\n This operation:\n - Deactivates the account (user cannot log in)\n - Anonymizes personal data (GDPR compliance)\n - Frees up the email address for re-registration\n - Preserves audit trail\n\n The account can be restored by an administrator if needed.\n ",
|
|
623
|
+
"summary": "Delete user account",
|
|
624
|
+
"tags": [
|
|
625
|
+
"cfg_accounts_profile"
|
|
626
|
+
],
|
|
627
|
+
"security": [
|
|
628
|
+
{
|
|
629
|
+
"jwtAuth": []
|
|
630
|
+
},
|
|
631
|
+
{
|
|
632
|
+
"cookieAuth": []
|
|
633
|
+
}
|
|
634
|
+
],
|
|
635
|
+
"responses": {
|
|
636
|
+
"200": {
|
|
637
|
+
"content": {
|
|
638
|
+
"application/json": {
|
|
639
|
+
"schema": {
|
|
640
|
+
"$ref": "#/components/schemas/AccountDeleteResponse"
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
},
|
|
644
|
+
"description": ""
|
|
645
|
+
},
|
|
646
|
+
"401": {
|
|
647
|
+
"content": {
|
|
648
|
+
"application/json": {
|
|
649
|
+
"schema": {
|
|
650
|
+
"description": "Authentication credentials were not provided."
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
},
|
|
654
|
+
"description": ""
|
|
655
|
+
},
|
|
656
|
+
"400": {
|
|
657
|
+
"content": {
|
|
658
|
+
"application/json": {
|
|
659
|
+
"schema": {
|
|
660
|
+
"description": "Account is already deleted."
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
},
|
|
664
|
+
"description": ""
|
|
665
|
+
}
|
|
666
|
+
},
|
|
667
|
+
"x-async-capable": false
|
|
668
|
+
}
|
|
669
|
+
},
|
|
670
|
+
"/cfg/accounts/profile/partial/": {
|
|
671
|
+
"put": {
|
|
672
|
+
"operationId": "cfg_accounts_profile_partial_update",
|
|
673
|
+
"description": "Partially update the current authenticated user's profile information. Supports avatar upload.",
|
|
674
|
+
"summary": "Partial update user profile",
|
|
675
|
+
"tags": [
|
|
676
|
+
"cfg_accounts_profile"
|
|
677
|
+
],
|
|
678
|
+
"requestBody": {
|
|
679
|
+
"content": {
|
|
680
|
+
"application/json": {
|
|
681
|
+
"schema": {
|
|
682
|
+
"$ref": "#/components/schemas/CfgUserUpdateRequest"
|
|
683
|
+
},
|
|
684
|
+
"examples": {
|
|
685
|
+
"ProfileUpdateWithAvatar": {
|
|
686
|
+
"value": {
|
|
687
|
+
"first_name": "John",
|
|
688
|
+
"last_name": "Doe",
|
|
689
|
+
"company": "Tech Corp",
|
|
690
|
+
"phone": "+1 (555) 123-4567",
|
|
691
|
+
"position": "Software Engineer"
|
|
692
|
+
},
|
|
693
|
+
"summary": "Profile Update with Avatar"
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
},
|
|
699
|
+
"security": [
|
|
700
|
+
{
|
|
701
|
+
"jwtAuth": []
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
"cookieAuth": []
|
|
705
|
+
}
|
|
706
|
+
],
|
|
707
|
+
"responses": {
|
|
708
|
+
"200": {
|
|
709
|
+
"content": {
|
|
710
|
+
"application/json": {
|
|
711
|
+
"schema": {
|
|
712
|
+
"$ref": "#/components/schemas/User"
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
},
|
|
716
|
+
"description": ""
|
|
717
|
+
},
|
|
718
|
+
"400": {
|
|
719
|
+
"content": {
|
|
720
|
+
"application/json": {
|
|
721
|
+
"schema": {
|
|
722
|
+
"description": "Invalid data provided."
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
},
|
|
726
|
+
"description": ""
|
|
727
|
+
},
|
|
728
|
+
"401": {
|
|
729
|
+
"content": {
|
|
730
|
+
"application/json": {
|
|
731
|
+
"schema": {
|
|
732
|
+
"description": "Authentication credentials were not provided."
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
},
|
|
736
|
+
"description": ""
|
|
737
|
+
}
|
|
738
|
+
},
|
|
739
|
+
"x-async-capable": false
|
|
740
|
+
},
|
|
741
|
+
"patch": {
|
|
742
|
+
"operationId": "cfg_accounts_profile_partial_partial_update",
|
|
743
|
+
"description": "Partially update the current authenticated user's profile information. Supports avatar upload.",
|
|
744
|
+
"summary": "Partial update user profile",
|
|
745
|
+
"tags": [
|
|
746
|
+
"cfg_accounts_profile"
|
|
747
|
+
],
|
|
748
|
+
"requestBody": {
|
|
749
|
+
"content": {
|
|
750
|
+
"application/json": {
|
|
751
|
+
"schema": {
|
|
752
|
+
"$ref": "#/components/schemas/PatchedCfgUserUpdateRequest"
|
|
753
|
+
},
|
|
754
|
+
"examples": {
|
|
755
|
+
"ProfileUpdateWithAvatar": {
|
|
756
|
+
"value": {
|
|
757
|
+
"first_name": "John",
|
|
758
|
+
"last_name": "Doe",
|
|
759
|
+
"company": "Tech Corp",
|
|
760
|
+
"phone": "+1 (555) 123-4567",
|
|
761
|
+
"position": "Software Engineer"
|
|
762
|
+
},
|
|
763
|
+
"summary": "Profile Update with Avatar"
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
},
|
|
769
|
+
"security": [
|
|
770
|
+
{
|
|
771
|
+
"jwtAuth": []
|
|
772
|
+
},
|
|
773
|
+
{
|
|
774
|
+
"cookieAuth": []
|
|
775
|
+
}
|
|
776
|
+
],
|
|
777
|
+
"responses": {
|
|
778
|
+
"200": {
|
|
779
|
+
"content": {
|
|
780
|
+
"application/json": {
|
|
781
|
+
"schema": {
|
|
782
|
+
"$ref": "#/components/schemas/User"
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
},
|
|
786
|
+
"description": ""
|
|
787
|
+
},
|
|
788
|
+
"400": {
|
|
789
|
+
"content": {
|
|
790
|
+
"application/json": {
|
|
791
|
+
"schema": {
|
|
792
|
+
"description": "Invalid data provided."
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
},
|
|
796
|
+
"description": ""
|
|
797
|
+
},
|
|
798
|
+
"401": {
|
|
799
|
+
"content": {
|
|
800
|
+
"application/json": {
|
|
801
|
+
"schema": {
|
|
802
|
+
"description": "Authentication credentials were not provided."
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
},
|
|
806
|
+
"description": ""
|
|
807
|
+
}
|
|
808
|
+
},
|
|
809
|
+
"x-async-capable": false
|
|
810
|
+
}
|
|
811
|
+
},
|
|
812
|
+
"/cfg/accounts/profile/update/": {
|
|
813
|
+
"put": {
|
|
814
|
+
"operationId": "cfg_accounts_profile_update_update",
|
|
815
|
+
"description": "Update the current authenticated user's profile information.",
|
|
816
|
+
"summary": "Update user profile",
|
|
817
|
+
"tags": [
|
|
818
|
+
"cfg_accounts_profile"
|
|
819
|
+
],
|
|
820
|
+
"requestBody": {
|
|
821
|
+
"content": {
|
|
822
|
+
"application/json": {
|
|
823
|
+
"schema": {
|
|
824
|
+
"$ref": "#/components/schemas/CfgUserUpdateRequest"
|
|
825
|
+
},
|
|
826
|
+
"examples": {
|
|
827
|
+
"ValidProfileUpdate": {
|
|
828
|
+
"value": {
|
|
829
|
+
"first_name": "John",
|
|
830
|
+
"last_name": "Doe",
|
|
831
|
+
"company": "Tech Corp",
|
|
832
|
+
"phone": "+1 (555) 123-4567",
|
|
833
|
+
"position": "Software Engineer"
|
|
834
|
+
},
|
|
835
|
+
"summary": "Valid Profile Update"
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
},
|
|
841
|
+
"security": [
|
|
842
|
+
{
|
|
843
|
+
"jwtAuth": []
|
|
844
|
+
},
|
|
845
|
+
{
|
|
846
|
+
"cookieAuth": []
|
|
847
|
+
}
|
|
848
|
+
],
|
|
849
|
+
"responses": {
|
|
850
|
+
"200": {
|
|
851
|
+
"content": {
|
|
852
|
+
"application/json": {
|
|
853
|
+
"schema": {
|
|
854
|
+
"$ref": "#/components/schemas/User"
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
},
|
|
858
|
+
"description": ""
|
|
859
|
+
},
|
|
860
|
+
"400": {
|
|
861
|
+
"content": {
|
|
862
|
+
"application/json": {
|
|
863
|
+
"schema": {
|
|
864
|
+
"description": "Invalid data provided."
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
},
|
|
868
|
+
"description": ""
|
|
869
|
+
},
|
|
870
|
+
"401": {
|
|
871
|
+
"content": {
|
|
872
|
+
"application/json": {
|
|
873
|
+
"schema": {
|
|
874
|
+
"description": "Authentication credentials were not provided."
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
},
|
|
878
|
+
"description": ""
|
|
879
|
+
}
|
|
880
|
+
},
|
|
881
|
+
"x-async-capable": false
|
|
882
|
+
},
|
|
883
|
+
"patch": {
|
|
884
|
+
"operationId": "cfg_accounts_profile_update_partial_update",
|
|
885
|
+
"description": "Update the current authenticated user's profile information.",
|
|
886
|
+
"summary": "Update user profile",
|
|
887
|
+
"tags": [
|
|
888
|
+
"cfg_accounts_profile"
|
|
889
|
+
],
|
|
890
|
+
"requestBody": {
|
|
891
|
+
"content": {
|
|
892
|
+
"application/json": {
|
|
893
|
+
"schema": {
|
|
894
|
+
"$ref": "#/components/schemas/PatchedCfgUserUpdateRequest"
|
|
895
|
+
},
|
|
896
|
+
"examples": {
|
|
897
|
+
"ValidProfileUpdate": {
|
|
898
|
+
"value": {
|
|
899
|
+
"first_name": "John",
|
|
900
|
+
"last_name": "Doe",
|
|
901
|
+
"company": "Tech Corp",
|
|
902
|
+
"phone": "+1 (555) 123-4567",
|
|
903
|
+
"position": "Software Engineer"
|
|
904
|
+
},
|
|
905
|
+
"summary": "Valid Profile Update"
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
},
|
|
911
|
+
"security": [
|
|
912
|
+
{
|
|
913
|
+
"jwtAuth": []
|
|
914
|
+
},
|
|
915
|
+
{
|
|
916
|
+
"cookieAuth": []
|
|
917
|
+
}
|
|
918
|
+
],
|
|
919
|
+
"responses": {
|
|
920
|
+
"200": {
|
|
921
|
+
"content": {
|
|
922
|
+
"application/json": {
|
|
923
|
+
"schema": {
|
|
924
|
+
"$ref": "#/components/schemas/User"
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
},
|
|
928
|
+
"description": ""
|
|
929
|
+
},
|
|
930
|
+
"400": {
|
|
931
|
+
"content": {
|
|
932
|
+
"application/json": {
|
|
933
|
+
"schema": {
|
|
934
|
+
"description": "Invalid data provided."
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
},
|
|
938
|
+
"description": ""
|
|
939
|
+
},
|
|
940
|
+
"401": {
|
|
941
|
+
"content": {
|
|
942
|
+
"application/json": {
|
|
943
|
+
"schema": {
|
|
944
|
+
"description": "Authentication credentials were not provided."
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
},
|
|
948
|
+
"description": ""
|
|
949
|
+
}
|
|
950
|
+
},
|
|
951
|
+
"x-async-capable": false
|
|
952
|
+
}
|
|
953
|
+
},
|
|
954
|
+
"/cfg/accounts/token/refresh/": {
|
|
955
|
+
"post": {
|
|
956
|
+
"operationId": "cfg_accounts_token_refresh_create",
|
|
957
|
+
"description": "Refresh JWT token.",
|
|
958
|
+
"tags": [
|
|
959
|
+
"cfg_accounts_auth"
|
|
960
|
+
],
|
|
961
|
+
"requestBody": {
|
|
962
|
+
"content": {
|
|
963
|
+
"application/json": {
|
|
964
|
+
"schema": {
|
|
965
|
+
"$ref": "#/components/schemas/TokenRefreshRequest"
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
},
|
|
969
|
+
"required": true
|
|
970
|
+
},
|
|
971
|
+
"responses": {
|
|
972
|
+
"200": {
|
|
973
|
+
"content": {
|
|
974
|
+
"application/json": {
|
|
975
|
+
"schema": {
|
|
976
|
+
"$ref": "#/components/schemas/TokenRefresh"
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
},
|
|
980
|
+
"description": ""
|
|
981
|
+
}
|
|
982
|
+
},
|
|
983
|
+
"x-async-capable": false
|
|
984
|
+
}
|
|
985
|
+
},
|
|
986
|
+
"/cfg/centrifugo/auth/token/": {
|
|
987
|
+
"get": {
|
|
988
|
+
"operationId": "cfg_centrifugo_auth_token_retrieve",
|
|
989
|
+
"description": "Generate JWT token for WebSocket connection to Centrifugo. Token includes user's allowed channels based on their permissions. Requires authentication.",
|
|
990
|
+
"summary": "Get Centrifugo connection token",
|
|
991
|
+
"tags": [
|
|
992
|
+
"cfg_centrifugo"
|
|
993
|
+
],
|
|
994
|
+
"security": [
|
|
995
|
+
{
|
|
996
|
+
"apiKeyAuth": []
|
|
997
|
+
},
|
|
998
|
+
{
|
|
999
|
+
"jwtAuthWithLastLogin": []
|
|
1000
|
+
}
|
|
1001
|
+
],
|
|
1002
|
+
"responses": {
|
|
1003
|
+
"200": {
|
|
1004
|
+
"content": {
|
|
1005
|
+
"application/json": {
|
|
1006
|
+
"schema": {
|
|
1007
|
+
"$ref": "#/components/schemas/ConnectionTokenResponse"
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
},
|
|
1011
|
+
"description": ""
|
|
1012
|
+
},
|
|
1013
|
+
"401": {
|
|
1014
|
+
"content": {
|
|
1015
|
+
"application/json": {
|
|
1016
|
+
"schema": {
|
|
1017
|
+
"description": "Unauthorized - authentication required"
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
},
|
|
1021
|
+
"description": ""
|
|
1022
|
+
},
|
|
1023
|
+
"500": {
|
|
1024
|
+
"content": {
|
|
1025
|
+
"application/json": {
|
|
1026
|
+
"schema": {
|
|
1027
|
+
"description": "Server error"
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
},
|
|
1031
|
+
"description": ""
|
|
1032
|
+
}
|
|
1033
|
+
},
|
|
1034
|
+
"x-async-capable": false
|
|
1035
|
+
}
|
|
1036
|
+
},
|
|
1037
|
+
"/cfg/totp/backup-codes/": {
|
|
1038
|
+
"get": {
|
|
1039
|
+
"operationId": "cfg_totp_backup_codes_retrieve",
|
|
1040
|
+
"description": "Get backup codes status for user.",
|
|
1041
|
+
"tags": [
|
|
1042
|
+
"cfg_totp_backup_codes"
|
|
1043
|
+
],
|
|
1044
|
+
"security": [
|
|
1045
|
+
{
|
|
1046
|
+
"apiKeyAuth": []
|
|
1047
|
+
},
|
|
1048
|
+
{
|
|
1049
|
+
"jwtAuthWithLastLogin": []
|
|
1050
|
+
}
|
|
1051
|
+
],
|
|
1052
|
+
"responses": {
|
|
1053
|
+
"200": {
|
|
1054
|
+
"content": {
|
|
1055
|
+
"application/json": {
|
|
1056
|
+
"schema": {
|
|
1057
|
+
"$ref": "#/components/schemas/BackupCodesStatus"
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
},
|
|
1061
|
+
"description": ""
|
|
1062
|
+
}
|
|
1063
|
+
},
|
|
1064
|
+
"x-async-capable": false
|
|
1065
|
+
}
|
|
1066
|
+
},
|
|
1067
|
+
"/cfg/totp/backup-codes/regenerate/": {
|
|
1068
|
+
"post": {
|
|
1069
|
+
"operationId": "cfg_totp_backup_codes_regenerate_create",
|
|
1070
|
+
"description": "Regenerate backup codes.\n\nRequires TOTP code for verification.\nInvalidates all existing codes.",
|
|
1071
|
+
"tags": [
|
|
1072
|
+
"cfg_totp_backup_codes"
|
|
1073
|
+
],
|
|
1074
|
+
"requestBody": {
|
|
1075
|
+
"content": {
|
|
1076
|
+
"application/json": {
|
|
1077
|
+
"schema": {
|
|
1078
|
+
"$ref": "#/components/schemas/BackupCodesRegenerateRequest"
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
},
|
|
1082
|
+
"required": true
|
|
1083
|
+
},
|
|
1084
|
+
"security": [
|
|
1085
|
+
{
|
|
1086
|
+
"apiKeyAuth": []
|
|
1087
|
+
},
|
|
1088
|
+
{
|
|
1089
|
+
"jwtAuthWithLastLogin": []
|
|
1090
|
+
}
|
|
1091
|
+
],
|
|
1092
|
+
"responses": {
|
|
1093
|
+
"200": {
|
|
1094
|
+
"content": {
|
|
1095
|
+
"application/json": {
|
|
1096
|
+
"schema": {
|
|
1097
|
+
"$ref": "#/components/schemas/BackupCodesRegenerateResponse"
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
},
|
|
1101
|
+
"description": ""
|
|
1102
|
+
},
|
|
1103
|
+
"400": {
|
|
1104
|
+
"content": {
|
|
1105
|
+
"application/json": {
|
|
1106
|
+
"schema": {
|
|
1107
|
+
"description": "Invalid code or 2FA not enabled"
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
},
|
|
1111
|
+
"description": ""
|
|
1112
|
+
}
|
|
1113
|
+
},
|
|
1114
|
+
"x-async-capable": false
|
|
1115
|
+
}
|
|
1116
|
+
},
|
|
1117
|
+
"/cfg/totp/devices/": {
|
|
1118
|
+
"get": {
|
|
1119
|
+
"operationId": "cfg_totp_devices_retrieve",
|
|
1120
|
+
"description": "List all TOTP devices for user.",
|
|
1121
|
+
"tags": [
|
|
1122
|
+
"cfg_totp"
|
|
1123
|
+
],
|
|
1124
|
+
"security": [
|
|
1125
|
+
{
|
|
1126
|
+
"apiKeyAuth": []
|
|
1127
|
+
},
|
|
1128
|
+
{
|
|
1129
|
+
"jwtAuthWithLastLogin": []
|
|
1130
|
+
}
|
|
1131
|
+
],
|
|
1132
|
+
"responses": {
|
|
1133
|
+
"200": {
|
|
1134
|
+
"content": {
|
|
1135
|
+
"application/json": {
|
|
1136
|
+
"schema": {
|
|
1137
|
+
"$ref": "#/components/schemas/DeviceListResponse"
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
},
|
|
1141
|
+
"description": ""
|
|
1142
|
+
}
|
|
1143
|
+
},
|
|
1144
|
+
"x-async-capable": false
|
|
1145
|
+
}
|
|
1146
|
+
},
|
|
1147
|
+
"/cfg/totp/devices/{id}/": {
|
|
1148
|
+
"delete": {
|
|
1149
|
+
"operationId": "cfg_totp_devices_destroy",
|
|
1150
|
+
"description": "Delete a TOTP device.\n\nRequires verification code if removing the last/primary device.",
|
|
1151
|
+
"parameters": [
|
|
1152
|
+
{
|
|
1153
|
+
"in": "path",
|
|
1154
|
+
"name": "id",
|
|
1155
|
+
"schema": {
|
|
1156
|
+
"type": "string",
|
|
1157
|
+
"format": "uuid"
|
|
1158
|
+
},
|
|
1159
|
+
"required": true
|
|
1160
|
+
}
|
|
1161
|
+
],
|
|
1162
|
+
"tags": [
|
|
1163
|
+
"cfg_totp"
|
|
1164
|
+
],
|
|
1165
|
+
"security": [
|
|
1166
|
+
{
|
|
1167
|
+
"apiKeyAuth": []
|
|
1168
|
+
},
|
|
1169
|
+
{
|
|
1170
|
+
"jwtAuthWithLastLogin": []
|
|
1171
|
+
}
|
|
1172
|
+
],
|
|
1173
|
+
"responses": {
|
|
1174
|
+
"204": {
|
|
1175
|
+
"description": "No response body"
|
|
1176
|
+
}
|
|
1177
|
+
},
|
|
1178
|
+
"x-async-capable": false
|
|
1179
|
+
}
|
|
1180
|
+
},
|
|
1181
|
+
"/cfg/totp/disable/": {
|
|
1182
|
+
"post": {
|
|
1183
|
+
"operationId": "cfg_totp_disable_create",
|
|
1184
|
+
"description": "Completely disable 2FA for account.\n\nRequires verification code.",
|
|
1185
|
+
"tags": [
|
|
1186
|
+
"cfg_totp"
|
|
1187
|
+
],
|
|
1188
|
+
"requestBody": {
|
|
1189
|
+
"content": {
|
|
1190
|
+
"application/json": {
|
|
1191
|
+
"schema": {
|
|
1192
|
+
"$ref": "#/components/schemas/DisableRequest"
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
},
|
|
1196
|
+
"required": true
|
|
1197
|
+
},
|
|
1198
|
+
"security": [
|
|
1199
|
+
{
|
|
1200
|
+
"apiKeyAuth": []
|
|
1201
|
+
},
|
|
1202
|
+
{
|
|
1203
|
+
"jwtAuthWithLastLogin": []
|
|
1204
|
+
}
|
|
1205
|
+
],
|
|
1206
|
+
"responses": {
|
|
1207
|
+
"200": {
|
|
1208
|
+
"content": {
|
|
1209
|
+
"application/json": {
|
|
1210
|
+
"schema": {
|
|
1211
|
+
"$ref": "#/components/schemas/cfg_totp_disable_response_200_AutoRef"
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
},
|
|
1215
|
+
"description": ""
|
|
1216
|
+
},
|
|
1217
|
+
"400": {
|
|
1218
|
+
"content": {
|
|
1219
|
+
"application/json": {
|
|
1220
|
+
"schema": {
|
|
1221
|
+
"description": "Invalid code"
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
},
|
|
1225
|
+
"description": ""
|
|
1226
|
+
}
|
|
1227
|
+
},
|
|
1228
|
+
"x-async-capable": false
|
|
1229
|
+
}
|
|
1230
|
+
},
|
|
1231
|
+
"/cfg/totp/setup/": {
|
|
1232
|
+
"post": {
|
|
1233
|
+
"operationId": "cfg_totp_setup_create",
|
|
1234
|
+
"description": "Start 2FA setup process.\n\nCreates a new TOTP device and returns QR code for scanning.",
|
|
1235
|
+
"tags": [
|
|
1236
|
+
"cfg_totp_setup"
|
|
1237
|
+
],
|
|
1238
|
+
"requestBody": {
|
|
1239
|
+
"content": {
|
|
1240
|
+
"application/json": {
|
|
1241
|
+
"schema": {
|
|
1242
|
+
"$ref": "#/components/schemas/SetupRequest"
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
},
|
|
1247
|
+
"security": [
|
|
1248
|
+
{
|
|
1249
|
+
"apiKeyAuth": []
|
|
1250
|
+
},
|
|
1251
|
+
{
|
|
1252
|
+
"jwtAuthWithLastLogin": []
|
|
1253
|
+
}
|
|
1254
|
+
],
|
|
1255
|
+
"responses": {
|
|
1256
|
+
"200": {
|
|
1257
|
+
"content": {
|
|
1258
|
+
"application/json": {
|
|
1259
|
+
"schema": {
|
|
1260
|
+
"$ref": "#/components/schemas/SetupResponse"
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
},
|
|
1264
|
+
"description": ""
|
|
1265
|
+
},
|
|
1266
|
+
"400": {
|
|
1267
|
+
"content": {
|
|
1268
|
+
"application/json": {
|
|
1269
|
+
"schema": {
|
|
1270
|
+
"description": "2FA already enabled or invalid request"
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
},
|
|
1274
|
+
"description": ""
|
|
1275
|
+
}
|
|
1276
|
+
},
|
|
1277
|
+
"x-async-capable": false
|
|
1278
|
+
}
|
|
1279
|
+
},
|
|
1280
|
+
"/cfg/totp/setup/confirm/": {
|
|
1281
|
+
"post": {
|
|
1282
|
+
"operationId": "cfg_totp_setup_confirm_create",
|
|
1283
|
+
"description": "Confirm 2FA setup with first valid code.\n\nActivates the device and generates backup codes.",
|
|
1284
|
+
"tags": [
|
|
1285
|
+
"cfg_totp_setup"
|
|
1286
|
+
],
|
|
1287
|
+
"requestBody": {
|
|
1288
|
+
"content": {
|
|
1289
|
+
"application/json": {
|
|
1290
|
+
"schema": {
|
|
1291
|
+
"$ref": "#/components/schemas/ConfirmSetupRequest"
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
},
|
|
1295
|
+
"required": true
|
|
1296
|
+
},
|
|
1297
|
+
"security": [
|
|
1298
|
+
{
|
|
1299
|
+
"apiKeyAuth": []
|
|
1300
|
+
},
|
|
1301
|
+
{
|
|
1302
|
+
"jwtAuthWithLastLogin": []
|
|
1303
|
+
}
|
|
1304
|
+
],
|
|
1305
|
+
"responses": {
|
|
1306
|
+
"200": {
|
|
1307
|
+
"content": {
|
|
1308
|
+
"application/json": {
|
|
1309
|
+
"schema": {
|
|
1310
|
+
"$ref": "#/components/schemas/ConfirmSetupResponse"
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
},
|
|
1314
|
+
"description": ""
|
|
1315
|
+
},
|
|
1316
|
+
"400": {
|
|
1317
|
+
"content": {
|
|
1318
|
+
"application/json": {
|
|
1319
|
+
"schema": {
|
|
1320
|
+
"description": "Invalid code or setup expired"
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
},
|
|
1324
|
+
"description": ""
|
|
1325
|
+
}
|
|
1326
|
+
},
|
|
1327
|
+
"x-async-capable": false
|
|
1328
|
+
}
|
|
1329
|
+
},
|
|
1330
|
+
"/cfg/totp/verify/": {
|
|
1331
|
+
"post": {
|
|
1332
|
+
"operationId": "cfg_totp_verify_create",
|
|
1333
|
+
"description": "Verify TOTP code for 2FA session.\n\nCompletes authentication and returns JWT tokens on success.",
|
|
1334
|
+
"tags": [
|
|
1335
|
+
"cfg_totp_verify"
|
|
1336
|
+
],
|
|
1337
|
+
"requestBody": {
|
|
1338
|
+
"content": {
|
|
1339
|
+
"application/json": {
|
|
1340
|
+
"schema": {
|
|
1341
|
+
"$ref": "#/components/schemas/VerifyRequest"
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
},
|
|
1345
|
+
"required": true
|
|
1346
|
+
},
|
|
1347
|
+
"security": [
|
|
1348
|
+
{
|
|
1349
|
+
"apiKeyAuth": []
|
|
1350
|
+
},
|
|
1351
|
+
{
|
|
1352
|
+
"jwtAuthWithLastLogin": []
|
|
1353
|
+
},
|
|
1354
|
+
{}
|
|
1355
|
+
],
|
|
1356
|
+
"responses": {
|
|
1357
|
+
"200": {
|
|
1358
|
+
"content": {
|
|
1359
|
+
"application/json": {
|
|
1360
|
+
"schema": {
|
|
1361
|
+
"$ref": "#/components/schemas/VerifyResponse"
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
},
|
|
1365
|
+
"description": ""
|
|
1366
|
+
},
|
|
1367
|
+
"400": {
|
|
1368
|
+
"content": {
|
|
1369
|
+
"application/json": {
|
|
1370
|
+
"schema": {
|
|
1371
|
+
"description": "Invalid code or session"
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
},
|
|
1375
|
+
"description": ""
|
|
1376
|
+
},
|
|
1377
|
+
"403": {
|
|
1378
|
+
"content": {
|
|
1379
|
+
"application/json": {
|
|
1380
|
+
"schema": {
|
|
1381
|
+
"description": "Too many attempts"
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
},
|
|
1385
|
+
"description": ""
|
|
1386
|
+
}
|
|
1387
|
+
},
|
|
1388
|
+
"x-async-capable": false
|
|
1389
|
+
}
|
|
1390
|
+
},
|
|
1391
|
+
"/cfg/totp/verify/backup/": {
|
|
1392
|
+
"post": {
|
|
1393
|
+
"operationId": "cfg_totp_verify_backup_create",
|
|
1394
|
+
"description": "Verify backup recovery code for 2FA session.\n\nAlternative verification method when TOTP device unavailable.",
|
|
1395
|
+
"tags": [
|
|
1396
|
+
"cfg_totp_verify"
|
|
1397
|
+
],
|
|
1398
|
+
"requestBody": {
|
|
1399
|
+
"content": {
|
|
1400
|
+
"application/json": {
|
|
1401
|
+
"schema": {
|
|
1402
|
+
"$ref": "#/components/schemas/VerifyBackupRequest"
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
},
|
|
1406
|
+
"required": true
|
|
1407
|
+
},
|
|
1408
|
+
"security": [
|
|
1409
|
+
{
|
|
1410
|
+
"apiKeyAuth": []
|
|
1411
|
+
},
|
|
1412
|
+
{
|
|
1413
|
+
"jwtAuthWithLastLogin": []
|
|
1414
|
+
},
|
|
1415
|
+
{}
|
|
1416
|
+
],
|
|
1417
|
+
"responses": {
|
|
1418
|
+
"200": {
|
|
1419
|
+
"content": {
|
|
1420
|
+
"application/json": {
|
|
1421
|
+
"schema": {
|
|
1422
|
+
"$ref": "#/components/schemas/VerifyResponse"
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
},
|
|
1426
|
+
"description": ""
|
|
1427
|
+
},
|
|
1428
|
+
"400": {
|
|
1429
|
+
"content": {
|
|
1430
|
+
"application/json": {
|
|
1431
|
+
"schema": {
|
|
1432
|
+
"description": "Invalid backup code or session"
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
},
|
|
1436
|
+
"description": ""
|
|
1437
|
+
}
|
|
1438
|
+
},
|
|
1439
|
+
"x-async-capable": false
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
},
|
|
1443
|
+
"components": {
|
|
1444
|
+
"schemas": {
|
|
1445
|
+
"APIKey": {
|
|
1446
|
+
"type": "object",
|
|
1447
|
+
"description": "Serializer for API key response (masked).",
|
|
1448
|
+
"properties": {
|
|
1449
|
+
"key": {
|
|
1450
|
+
"type": "string",
|
|
1451
|
+
"description": "Masked API key"
|
|
1452
|
+
},
|
|
1453
|
+
"reissued_at": {
|
|
1454
|
+
"type": [
|
|
1455
|
+
"string",
|
|
1456
|
+
"null"
|
|
1457
|
+
],
|
|
1458
|
+
"format": "date-time",
|
|
1459
|
+
"description": "When the key was last regenerated"
|
|
1460
|
+
},
|
|
1461
|
+
"created_at": {
|
|
1462
|
+
"type": "string",
|
|
1463
|
+
"format": "date-time",
|
|
1464
|
+
"description": "When the key was created"
|
|
1465
|
+
}
|
|
1466
|
+
},
|
|
1467
|
+
"required": [
|
|
1468
|
+
"created_at",
|
|
1469
|
+
"key",
|
|
1470
|
+
"reissued_at"
|
|
1471
|
+
]
|
|
1472
|
+
},
|
|
1473
|
+
"APIKeyRegenerate": {
|
|
1474
|
+
"type": "object",
|
|
1475
|
+
"description": "Serializer for API key regeneration response (full key shown once).",
|
|
1476
|
+
"properties": {
|
|
1477
|
+
"key": {
|
|
1478
|
+
"type": "string",
|
|
1479
|
+
"description": "New API key (shown only once)"
|
|
1480
|
+
},
|
|
1481
|
+
"reissued_at": {
|
|
1482
|
+
"type": "string",
|
|
1483
|
+
"format": "date-time",
|
|
1484
|
+
"description": "When the key was regenerated"
|
|
1485
|
+
}
|
|
1486
|
+
},
|
|
1487
|
+
"required": [
|
|
1488
|
+
"key",
|
|
1489
|
+
"reissued_at"
|
|
1490
|
+
]
|
|
1491
|
+
},
|
|
1492
|
+
"APIKeyRequest": {
|
|
1493
|
+
"type": "object",
|
|
1494
|
+
"description": "Serializer for API key response (masked).",
|
|
1495
|
+
"properties": {
|
|
1496
|
+
"key": {
|
|
1497
|
+
"type": "string",
|
|
1498
|
+
"minLength": 1,
|
|
1499
|
+
"description": "Masked API key"
|
|
1500
|
+
},
|
|
1501
|
+
"reissued_at": {
|
|
1502
|
+
"type": [
|
|
1503
|
+
"string",
|
|
1504
|
+
"null"
|
|
1505
|
+
],
|
|
1506
|
+
"format": "date-time",
|
|
1507
|
+
"description": "When the key was last regenerated"
|
|
1508
|
+
},
|
|
1509
|
+
"created_at": {
|
|
1510
|
+
"type": "string",
|
|
1511
|
+
"format": "date-time",
|
|
1512
|
+
"description": "When the key was created"
|
|
1513
|
+
}
|
|
1514
|
+
},
|
|
1515
|
+
"required": [
|
|
1516
|
+
"created_at",
|
|
1517
|
+
"key",
|
|
1518
|
+
"reissued_at"
|
|
1519
|
+
]
|
|
1520
|
+
},
|
|
1521
|
+
"APIKeyTestRequest": {
|
|
1522
|
+
"type": "object",
|
|
1523
|
+
"description": "Serializer for testing an API key.",
|
|
1524
|
+
"properties": {
|
|
1525
|
+
"key": {
|
|
1526
|
+
"type": "string",
|
|
1527
|
+
"minLength": 1,
|
|
1528
|
+
"description": "API key to test"
|
|
1529
|
+
}
|
|
1530
|
+
},
|
|
1531
|
+
"required": [
|
|
1532
|
+
"key"
|
|
1533
|
+
]
|
|
1534
|
+
},
|
|
1535
|
+
"APIKeyTestResult": {
|
|
1536
|
+
"type": "object",
|
|
1537
|
+
"description": "Serializer for API key test result.",
|
|
1538
|
+
"properties": {
|
|
1539
|
+
"valid": {
|
|
1540
|
+
"type": "boolean",
|
|
1541
|
+
"description": "Whether the key is valid"
|
|
1542
|
+
},
|
|
1543
|
+
"user_id": {
|
|
1544
|
+
"type": [
|
|
1545
|
+
"string",
|
|
1546
|
+
"null"
|
|
1547
|
+
],
|
|
1548
|
+
"description": "User ID if valid, null otherwise"
|
|
1549
|
+
}
|
|
1550
|
+
},
|
|
1551
|
+
"required": [
|
|
1552
|
+
"user_id",
|
|
1553
|
+
"valid"
|
|
1554
|
+
]
|
|
1555
|
+
},
|
|
1556
|
+
"AccountDeleteResponse": {
|
|
1557
|
+
"type": "object",
|
|
1558
|
+
"description": "Response serializer for account deletion.",
|
|
1559
|
+
"properties": {
|
|
1560
|
+
"success": {
|
|
1561
|
+
"type": "boolean",
|
|
1562
|
+
"description": "Whether the account was successfully deleted"
|
|
1563
|
+
},
|
|
1564
|
+
"message": {
|
|
1565
|
+
"type": "string",
|
|
1566
|
+
"description": "Human-readable message about the deletion"
|
|
1567
|
+
}
|
|
1568
|
+
},
|
|
1569
|
+
"required": [
|
|
1570
|
+
"message",
|
|
1571
|
+
"success"
|
|
1572
|
+
]
|
|
1573
|
+
},
|
|
1574
|
+
"BackupCodesRegenerateRequest": {
|
|
1575
|
+
"type": "object",
|
|
1576
|
+
"description": "Serializer for regenerating backup codes.",
|
|
1577
|
+
"properties": {
|
|
1578
|
+
"code": {
|
|
1579
|
+
"type": "string",
|
|
1580
|
+
"minLength": 6,
|
|
1581
|
+
"description": "TOTP code for verification",
|
|
1582
|
+
"maxLength": 6
|
|
1583
|
+
}
|
|
1584
|
+
},
|
|
1585
|
+
"required": [
|
|
1586
|
+
"code"
|
|
1587
|
+
]
|
|
1588
|
+
},
|
|
1589
|
+
"BackupCodesRegenerateResponse": {
|
|
1590
|
+
"type": "object",
|
|
1591
|
+
"description": "Response serializer for backup codes regeneration.",
|
|
1592
|
+
"properties": {
|
|
1593
|
+
"backup_codes": {
|
|
1594
|
+
"type": "array",
|
|
1595
|
+
"items": {
|
|
1596
|
+
"type": "string"
|
|
1597
|
+
},
|
|
1598
|
+
"description": "List of new backup codes (save these!)"
|
|
1599
|
+
},
|
|
1600
|
+
"warning": {
|
|
1601
|
+
"type": "string",
|
|
1602
|
+
"description": "Warning about previous codes being invalidated"
|
|
1603
|
+
}
|
|
1604
|
+
},
|
|
1605
|
+
"required": [
|
|
1606
|
+
"backup_codes",
|
|
1607
|
+
"warning"
|
|
1608
|
+
]
|
|
1609
|
+
},
|
|
1610
|
+
"BackupCodesStatus": {
|
|
1611
|
+
"type": "object",
|
|
1612
|
+
"description": "Serializer for backup codes status.",
|
|
1613
|
+
"properties": {
|
|
1614
|
+
"remaining_count": {
|
|
1615
|
+
"type": "integer",
|
|
1616
|
+
"description": "Number of unused backup codes"
|
|
1617
|
+
},
|
|
1618
|
+
"total_generated": {
|
|
1619
|
+
"type": "integer",
|
|
1620
|
+
"description": "Total number of codes generated"
|
|
1621
|
+
},
|
|
1622
|
+
"warning": {
|
|
1623
|
+
"type": [
|
|
1624
|
+
"string",
|
|
1625
|
+
"null"
|
|
1626
|
+
],
|
|
1627
|
+
"description": "Warning if running low on codes"
|
|
1628
|
+
}
|
|
1629
|
+
},
|
|
1630
|
+
"required": [
|
|
1631
|
+
"remaining_count",
|
|
1632
|
+
"total_generated"
|
|
1633
|
+
]
|
|
1634
|
+
},
|
|
1635
|
+
"CentrifugoToken": {
|
|
1636
|
+
"type": "object",
|
|
1637
|
+
"description": "Nested serializer for Centrifugo WebSocket connection token.",
|
|
1638
|
+
"properties": {
|
|
1639
|
+
"token": {
|
|
1640
|
+
"type": "string",
|
|
1641
|
+
"description": "JWT token for Centrifugo WebSocket connection"
|
|
1642
|
+
},
|
|
1643
|
+
"centrifugo_url": {
|
|
1644
|
+
"type": "string",
|
|
1645
|
+
"format": "uri",
|
|
1646
|
+
"description": "Centrifugo WebSocket URL"
|
|
1647
|
+
},
|
|
1648
|
+
"expires_at": {
|
|
1649
|
+
"type": "string",
|
|
1650
|
+
"format": "date-time",
|
|
1651
|
+
"description": "Token expiration time (ISO 8601)"
|
|
1652
|
+
},
|
|
1653
|
+
"channels": {
|
|
1654
|
+
"type": "array",
|
|
1655
|
+
"items": {
|
|
1656
|
+
"type": "string"
|
|
1657
|
+
},
|
|
1658
|
+
"description": "List of allowed channels for this user"
|
|
1659
|
+
}
|
|
1660
|
+
},
|
|
1661
|
+
"required": [
|
|
1662
|
+
"centrifugo_url",
|
|
1663
|
+
"channels",
|
|
1664
|
+
"expires_at",
|
|
1665
|
+
"token"
|
|
1666
|
+
]
|
|
1667
|
+
},
|
|
1668
|
+
"CfgUserUpdateRequest": {
|
|
1669
|
+
"type": "object",
|
|
1670
|
+
"description": "Serializer for updating user profile.",
|
|
1671
|
+
"properties": {
|
|
1672
|
+
"first_name": {
|
|
1673
|
+
"type": "string",
|
|
1674
|
+
"maxLength": 50
|
|
1675
|
+
},
|
|
1676
|
+
"last_name": {
|
|
1677
|
+
"type": "string",
|
|
1678
|
+
"maxLength": 50
|
|
1679
|
+
},
|
|
1680
|
+
"company": {
|
|
1681
|
+
"type": "string",
|
|
1682
|
+
"maxLength": 100
|
|
1683
|
+
},
|
|
1684
|
+
"phone": {
|
|
1685
|
+
"type": "string",
|
|
1686
|
+
"maxLength": 20
|
|
1687
|
+
},
|
|
1688
|
+
"position": {
|
|
1689
|
+
"type": "string",
|
|
1690
|
+
"maxLength": 100
|
|
1691
|
+
},
|
|
1692
|
+
"language": {
|
|
1693
|
+
"type": "string",
|
|
1694
|
+
"maxLength": 10
|
|
1695
|
+
},
|
|
1696
|
+
"timezone": {
|
|
1697
|
+
"type": "string",
|
|
1698
|
+
"description": "IANA timezone name (e.g. 'Asia/Seoul'). Auto-detected from browser via X-Timezone header.",
|
|
1699
|
+
"maxLength": 64
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
},
|
|
1703
|
+
"ConfirmSetupRequest": {
|
|
1704
|
+
"type": "object",
|
|
1705
|
+
"description": "Serializer for confirming 2FA setup with first code.",
|
|
1706
|
+
"properties": {
|
|
1707
|
+
"device_id": {
|
|
1708
|
+
"type": "string",
|
|
1709
|
+
"format": "uuid",
|
|
1710
|
+
"description": "Device ID from setup response"
|
|
1711
|
+
},
|
|
1712
|
+
"code": {
|
|
1713
|
+
"type": "string",
|
|
1714
|
+
"minLength": 6,
|
|
1715
|
+
"description": "6-digit TOTP code from authenticator app",
|
|
1716
|
+
"maxLength": 6
|
|
1717
|
+
}
|
|
1718
|
+
},
|
|
1719
|
+
"required": [
|
|
1720
|
+
"code",
|
|
1721
|
+
"device_id"
|
|
1722
|
+
]
|
|
1723
|
+
},
|
|
1724
|
+
"ConfirmSetupResponse": {
|
|
1725
|
+
"type": "object",
|
|
1726
|
+
"description": "Response serializer for setup confirmation.",
|
|
1727
|
+
"properties": {
|
|
1728
|
+
"message": {
|
|
1729
|
+
"type": "string"
|
|
1730
|
+
},
|
|
1731
|
+
"backup_codes": {
|
|
1732
|
+
"type": "array",
|
|
1733
|
+
"items": {
|
|
1734
|
+
"type": "string"
|
|
1735
|
+
},
|
|
1736
|
+
"description": "List of backup recovery codes (save these!)"
|
|
1737
|
+
},
|
|
1738
|
+
"backup_codes_warning": {
|
|
1739
|
+
"type": "string",
|
|
1740
|
+
"description": "Warning message about backup codes"
|
|
1741
|
+
}
|
|
1742
|
+
},
|
|
1743
|
+
"required": [
|
|
1744
|
+
"backup_codes",
|
|
1745
|
+
"backup_codes_warning",
|
|
1746
|
+
"message"
|
|
1747
|
+
]
|
|
1748
|
+
},
|
|
1749
|
+
"ConnectionTokenResponse": {
|
|
1750
|
+
"description": "Response model for Centrifugo connection token.",
|
|
1751
|
+
"properties": {
|
|
1752
|
+
"token": {
|
|
1753
|
+
"description": "JWT token for Centrifugo connection",
|
|
1754
|
+
"title": "Token",
|
|
1755
|
+
"type": "string"
|
|
1756
|
+
},
|
|
1757
|
+
"centrifugo_url": {
|
|
1758
|
+
"description": "Centrifugo WebSocket URL",
|
|
1759
|
+
"title": "Centrifugo Url",
|
|
1760
|
+
"type": "string"
|
|
1761
|
+
},
|
|
1762
|
+
"expires_at": {
|
|
1763
|
+
"description": "Token expiration time (ISO 8601)",
|
|
1764
|
+
"title": "Expires At",
|
|
1765
|
+
"type": "string"
|
|
1766
|
+
},
|
|
1767
|
+
"channels": {
|
|
1768
|
+
"description": "List of allowed channels",
|
|
1769
|
+
"items": {
|
|
1770
|
+
"type": "string"
|
|
1771
|
+
},
|
|
1772
|
+
"title": "Channels",
|
|
1773
|
+
"type": "array"
|
|
1774
|
+
}
|
|
1775
|
+
},
|
|
1776
|
+
"required": [
|
|
1777
|
+
"token",
|
|
1778
|
+
"centrifugo_url",
|
|
1779
|
+
"expires_at",
|
|
1780
|
+
"channels"
|
|
1781
|
+
],
|
|
1782
|
+
"title": "ConnectionTokenResponse",
|
|
1783
|
+
"type": "object"
|
|
1784
|
+
},
|
|
1785
|
+
"DeviceList": {
|
|
1786
|
+
"type": "object",
|
|
1787
|
+
"description": "Serializer for listing TOTP devices.",
|
|
1788
|
+
"properties": {
|
|
1789
|
+
"id": {
|
|
1790
|
+
"type": "string",
|
|
1791
|
+
"format": "uuid",
|
|
1792
|
+
"readOnly": true
|
|
1793
|
+
},
|
|
1794
|
+
"name": {
|
|
1795
|
+
"type": "string",
|
|
1796
|
+
"readOnly": true,
|
|
1797
|
+
"description": "Device name for identification"
|
|
1798
|
+
},
|
|
1799
|
+
"is_primary": {
|
|
1800
|
+
"type": "boolean",
|
|
1801
|
+
"readOnly": true,
|
|
1802
|
+
"description": "Primary device used for verification"
|
|
1803
|
+
},
|
|
1804
|
+
"status": {
|
|
1805
|
+
"allOf": [
|
|
1806
|
+
{
|
|
1807
|
+
"$ref": "#/components/schemas/DeviceStatusEnum"
|
|
1808
|
+
}
|
|
1809
|
+
],
|
|
1810
|
+
"readOnly": true
|
|
1811
|
+
},
|
|
1812
|
+
"created_at": {
|
|
1813
|
+
"type": "string",
|
|
1814
|
+
"format": "date-time",
|
|
1815
|
+
"readOnly": true
|
|
1816
|
+
},
|
|
1817
|
+
"confirmed_at": {
|
|
1818
|
+
"type": [
|
|
1819
|
+
"string",
|
|
1820
|
+
"null"
|
|
1821
|
+
],
|
|
1822
|
+
"format": "date-time",
|
|
1823
|
+
"readOnly": true,
|
|
1824
|
+
"description": "When device setup was confirmed"
|
|
1825
|
+
},
|
|
1826
|
+
"last_used_at": {
|
|
1827
|
+
"type": [
|
|
1828
|
+
"string",
|
|
1829
|
+
"null"
|
|
1830
|
+
],
|
|
1831
|
+
"format": "date-time",
|
|
1832
|
+
"readOnly": true,
|
|
1833
|
+
"description": "Last successful verification"
|
|
1834
|
+
}
|
|
1835
|
+
},
|
|
1836
|
+
"required": [
|
|
1837
|
+
"confirmed_at",
|
|
1838
|
+
"created_at",
|
|
1839
|
+
"id",
|
|
1840
|
+
"is_primary",
|
|
1841
|
+
"last_used_at",
|
|
1842
|
+
"name",
|
|
1843
|
+
"status"
|
|
1844
|
+
]
|
|
1845
|
+
},
|
|
1846
|
+
"DeviceListResponse": {
|
|
1847
|
+
"type": "object",
|
|
1848
|
+
"description": "Response serializer for device list endpoint.",
|
|
1849
|
+
"properties": {
|
|
1850
|
+
"devices": {
|
|
1851
|
+
"type": "array",
|
|
1852
|
+
"items": {
|
|
1853
|
+
"$ref": "#/components/schemas/DeviceList"
|
|
1854
|
+
}
|
|
1855
|
+
},
|
|
1856
|
+
"has_2fa_enabled": {
|
|
1857
|
+
"type": "boolean"
|
|
1858
|
+
}
|
|
1859
|
+
},
|
|
1860
|
+
"required": [
|
|
1861
|
+
"devices",
|
|
1862
|
+
"has_2fa_enabled"
|
|
1863
|
+
]
|
|
1864
|
+
},
|
|
1865
|
+
"DeviceStatusEnum": {
|
|
1866
|
+
"enum": [
|
|
1867
|
+
"pending",
|
|
1868
|
+
"active",
|
|
1869
|
+
"disabled"
|
|
1870
|
+
],
|
|
1871
|
+
"type": "string",
|
|
1872
|
+
"description": "* `pending` - Pending Confirmation\n* `active` - Active\n* `disabled` - Disabled"
|
|
1873
|
+
},
|
|
1874
|
+
"DisableRequest": {
|
|
1875
|
+
"type": "object",
|
|
1876
|
+
"description": "Serializer for completely disabling 2FA.",
|
|
1877
|
+
"properties": {
|
|
1878
|
+
"code": {
|
|
1879
|
+
"type": "string",
|
|
1880
|
+
"minLength": 6,
|
|
1881
|
+
"description": "TOTP code for verification",
|
|
1882
|
+
"maxLength": 6
|
|
1883
|
+
}
|
|
1884
|
+
},
|
|
1885
|
+
"required": [
|
|
1886
|
+
"code"
|
|
1887
|
+
]
|
|
1888
|
+
},
|
|
1889
|
+
"OAuthAuthorizeRequestRequest": {
|
|
1890
|
+
"type": "object",
|
|
1891
|
+
"description": "Request to start OAuth flow.",
|
|
1892
|
+
"properties": {
|
|
1893
|
+
"redirect_uri": {
|
|
1894
|
+
"type": "string",
|
|
1895
|
+
"format": "uri",
|
|
1896
|
+
"description": "URL to redirect after OAuth authorization. If not provided, uses config's site_url + callback_path"
|
|
1897
|
+
},
|
|
1898
|
+
"source_url": {
|
|
1899
|
+
"type": "string",
|
|
1900
|
+
"format": "uri",
|
|
1901
|
+
"description": "Optional source URL for registration tracking"
|
|
1902
|
+
}
|
|
1903
|
+
}
|
|
1904
|
+
},
|
|
1905
|
+
"OAuthAuthorizeResponse": {
|
|
1906
|
+
"type": "object",
|
|
1907
|
+
"description": "Response with OAuth authorization URL.",
|
|
1908
|
+
"properties": {
|
|
1909
|
+
"authorization_url": {
|
|
1910
|
+
"type": "string",
|
|
1911
|
+
"format": "uri",
|
|
1912
|
+
"description": "Full URL to redirect user to OAuth provider"
|
|
1913
|
+
},
|
|
1914
|
+
"state": {
|
|
1915
|
+
"type": "string",
|
|
1916
|
+
"description": "State token for CSRF protection. Store this and verify on callback."
|
|
1917
|
+
}
|
|
1918
|
+
},
|
|
1919
|
+
"required": [
|
|
1920
|
+
"authorization_url",
|
|
1921
|
+
"state"
|
|
1922
|
+
]
|
|
1923
|
+
},
|
|
1924
|
+
"OAuthCallbackRequestRequest": {
|
|
1925
|
+
"type": "object",
|
|
1926
|
+
"description": "Request to complete OAuth flow (callback handler).",
|
|
1927
|
+
"properties": {
|
|
1928
|
+
"code": {
|
|
1929
|
+
"type": "string",
|
|
1930
|
+
"minLength": 10,
|
|
1931
|
+
"description": "Authorization code from OAuth provider callback",
|
|
1932
|
+
"maxLength": 500
|
|
1933
|
+
},
|
|
1934
|
+
"state": {
|
|
1935
|
+
"type": "string",
|
|
1936
|
+
"minLength": 20,
|
|
1937
|
+
"description": "State token for CSRF verification (from authorize response)",
|
|
1938
|
+
"maxLength": 100
|
|
1939
|
+
},
|
|
1940
|
+
"redirect_uri": {
|
|
1941
|
+
"type": "string",
|
|
1942
|
+
"format": "uri",
|
|
1943
|
+
"description": "Same redirect_uri used in authorize request. If not provided, uses config's site_url + callback_path"
|
|
1944
|
+
}
|
|
1945
|
+
},
|
|
1946
|
+
"required": [
|
|
1947
|
+
"code",
|
|
1948
|
+
"state"
|
|
1949
|
+
]
|
|
1950
|
+
},
|
|
1951
|
+
"OAuthConnection": {
|
|
1952
|
+
"type": "object",
|
|
1953
|
+
"description": "Serializer for OAuth connection info (user-facing).",
|
|
1954
|
+
"properties": {
|
|
1955
|
+
"id": {
|
|
1956
|
+
"type": "integer",
|
|
1957
|
+
"readOnly": true
|
|
1958
|
+
},
|
|
1959
|
+
"provider": {
|
|
1960
|
+
"allOf": [
|
|
1961
|
+
{
|
|
1962
|
+
"$ref": "#/components/schemas/OAuthProviderEnum"
|
|
1963
|
+
}
|
|
1964
|
+
],
|
|
1965
|
+
"readOnly": true,
|
|
1966
|
+
"description": "OAuth provider name (github, google, etc.)\n\n* `github` - GitHub"
|
|
1967
|
+
},
|
|
1968
|
+
"provider_display": {
|
|
1969
|
+
"type": "string",
|
|
1970
|
+
"readOnly": true
|
|
1971
|
+
},
|
|
1972
|
+
"provider_username": {
|
|
1973
|
+
"type": "string",
|
|
1974
|
+
"readOnly": true,
|
|
1975
|
+
"description": "Username on the OAuth provider platform"
|
|
1976
|
+
},
|
|
1977
|
+
"provider_email": {
|
|
1978
|
+
"type": "string",
|
|
1979
|
+
"format": "email",
|
|
1980
|
+
"readOnly": true,
|
|
1981
|
+
"description": "Email from OAuth provider (may differ from user.email)"
|
|
1982
|
+
},
|
|
1983
|
+
"provider_avatar_url": {
|
|
1984
|
+
"type": "string",
|
|
1985
|
+
"format": "uri",
|
|
1986
|
+
"readOnly": true,
|
|
1987
|
+
"description": "Avatar URL from OAuth provider"
|
|
1988
|
+
},
|
|
1989
|
+
"connected_at": {
|
|
1990
|
+
"type": "string",
|
|
1991
|
+
"format": "date-time",
|
|
1992
|
+
"readOnly": true,
|
|
1993
|
+
"description": "When this OAuth connection was created"
|
|
1994
|
+
},
|
|
1995
|
+
"last_login_at": {
|
|
1996
|
+
"type": "string",
|
|
1997
|
+
"format": "date-time",
|
|
1998
|
+
"readOnly": true,
|
|
1999
|
+
"description": "Last time this OAuth connection was used for login"
|
|
2000
|
+
}
|
|
2001
|
+
},
|
|
2002
|
+
"required": [
|
|
2003
|
+
"connected_at",
|
|
2004
|
+
"id",
|
|
2005
|
+
"last_login_at",
|
|
2006
|
+
"provider",
|
|
2007
|
+
"provider_avatar_url",
|
|
2008
|
+
"provider_display",
|
|
2009
|
+
"provider_email",
|
|
2010
|
+
"provider_username"
|
|
2011
|
+
]
|
|
2012
|
+
},
|
|
2013
|
+
"OAuthDisconnectRequestRequest": {
|
|
2014
|
+
"type": "object",
|
|
2015
|
+
"description": "Request to disconnect OAuth provider.",
|
|
2016
|
+
"properties": {
|
|
2017
|
+
"provider": {
|
|
2018
|
+
"allOf": [
|
|
2019
|
+
{
|
|
2020
|
+
"$ref": "#/components/schemas/OAuthProviderEnum"
|
|
2021
|
+
}
|
|
2022
|
+
],
|
|
2023
|
+
"description": "OAuth provider to disconnect\n\n* `github` - GitHub"
|
|
2024
|
+
}
|
|
2025
|
+
},
|
|
2026
|
+
"required": [
|
|
2027
|
+
"provider"
|
|
2028
|
+
]
|
|
2029
|
+
},
|
|
2030
|
+
"OAuthError": {
|
|
2031
|
+
"type": "object",
|
|
2032
|
+
"description": "Error response for OAuth endpoints.",
|
|
2033
|
+
"properties": {
|
|
2034
|
+
"error": {
|
|
2035
|
+
"type": "string",
|
|
2036
|
+
"description": "Error code"
|
|
2037
|
+
},
|
|
2038
|
+
"error_description": {
|
|
2039
|
+
"type": "string",
|
|
2040
|
+
"description": "Human-readable error description"
|
|
2041
|
+
}
|
|
2042
|
+
},
|
|
2043
|
+
"required": [
|
|
2044
|
+
"error"
|
|
2045
|
+
]
|
|
2046
|
+
},
|
|
2047
|
+
"OAuthProviderEnum": {
|
|
2048
|
+
"enum": [
|
|
2049
|
+
"github"
|
|
2050
|
+
],
|
|
2051
|
+
"type": "string",
|
|
2052
|
+
"description": "* `github` - GitHub"
|
|
2053
|
+
},
|
|
2054
|
+
"OAuthProvidersResponse": {
|
|
2055
|
+
"type": "object",
|
|
2056
|
+
"description": "Response with available OAuth providers.",
|
|
2057
|
+
"properties": {
|
|
2058
|
+
"providers": {
|
|
2059
|
+
"type": "array",
|
|
2060
|
+
"items": {
|
|
2061
|
+
"type": "object",
|
|
2062
|
+
"additionalProperties": {}
|
|
2063
|
+
},
|
|
2064
|
+
"description": "List of available OAuth providers"
|
|
2065
|
+
}
|
|
2066
|
+
},
|
|
2067
|
+
"required": [
|
|
2068
|
+
"providers"
|
|
2069
|
+
]
|
|
2070
|
+
},
|
|
2071
|
+
"OAuthTokenResponse": {
|
|
2072
|
+
"type": "object",
|
|
2073
|
+
"description": "Response with JWT tokens after OAuth authentication.\n\nWhen 2FA is required:\n- requires_2fa: True\n- session_id: UUID of 2FA verification session\n- access/refresh/user: null\n\nWhen 2FA is not required:\n- requires_2fa: False\n- session_id: null\n- access/refresh/user: populated",
|
|
2074
|
+
"properties": {
|
|
2075
|
+
"requires_2fa": {
|
|
2076
|
+
"type": "boolean",
|
|
2077
|
+
"default": false,
|
|
2078
|
+
"description": "True if 2FA verification is required"
|
|
2079
|
+
},
|
|
2080
|
+
"session_id": {
|
|
2081
|
+
"type": [
|
|
2082
|
+
"string",
|
|
2083
|
+
"null"
|
|
2084
|
+
],
|
|
2085
|
+
"format": "uuid",
|
|
2086
|
+
"description": "2FA session ID (only when requires_2fa=True)"
|
|
2087
|
+
},
|
|
2088
|
+
"access": {
|
|
2089
|
+
"type": [
|
|
2090
|
+
"string",
|
|
2091
|
+
"null"
|
|
2092
|
+
],
|
|
2093
|
+
"description": "JWT access token (null when requires_2fa=True)"
|
|
2094
|
+
},
|
|
2095
|
+
"refresh": {
|
|
2096
|
+
"type": [
|
|
2097
|
+
"string",
|
|
2098
|
+
"null"
|
|
2099
|
+
],
|
|
2100
|
+
"description": "JWT refresh token (null when requires_2fa=True)"
|
|
2101
|
+
},
|
|
2102
|
+
"user": {
|
|
2103
|
+
"type": [
|
|
2104
|
+
"object",
|
|
2105
|
+
"null"
|
|
2106
|
+
],
|
|
2107
|
+
"additionalProperties": {},
|
|
2108
|
+
"description": "Authenticated user info (null when requires_2fa=True)"
|
|
2109
|
+
},
|
|
2110
|
+
"is_new_user": {
|
|
2111
|
+
"type": "boolean",
|
|
2112
|
+
"description": "True if a new user was created during this OAuth flow"
|
|
2113
|
+
},
|
|
2114
|
+
"is_new_connection": {
|
|
2115
|
+
"type": "boolean",
|
|
2116
|
+
"description": "True if a new OAuth connection was created"
|
|
2117
|
+
},
|
|
2118
|
+
"should_prompt_2fa": {
|
|
2119
|
+
"type": "boolean",
|
|
2120
|
+
"description": "True if user should be prompted to enable 2FA"
|
|
2121
|
+
}
|
|
2122
|
+
},
|
|
2123
|
+
"required": [
|
|
2124
|
+
"is_new_connection",
|
|
2125
|
+
"is_new_user"
|
|
2126
|
+
]
|
|
2127
|
+
},
|
|
2128
|
+
"OTPErrorResponse": {
|
|
2129
|
+
"type": "object",
|
|
2130
|
+
"description": "Typed error response for OTP operations.\n\nerror_code values:\n - invalid_identifier — malformed email\n - cooldown — too soon after last request (retry_after = seconds)\n - hourly_limit — hourly quota exceeded (retry_after = seconds until reset)\n - daily_limit — daily quota exceeded (retry_after = seconds until reset)\n - rate_limited — IP-level rate limit hit (no retry_after)\n - user_creation_failed — internal error creating account\n - send_failed — transport error (email / SMS)\n - internal_error — unexpected server error",
|
|
2131
|
+
"properties": {
|
|
2132
|
+
"error": {
|
|
2133
|
+
"type": "string",
|
|
2134
|
+
"description": "Human-readable error message"
|
|
2135
|
+
},
|
|
2136
|
+
"error_code": {
|
|
2137
|
+
"type": [
|
|
2138
|
+
"string",
|
|
2139
|
+
"null"
|
|
2140
|
+
],
|
|
2141
|
+
"description": "Machine-readable error code"
|
|
2142
|
+
},
|
|
2143
|
+
"retry_after": {
|
|
2144
|
+
"type": [
|
|
2145
|
+
"integer",
|
|
2146
|
+
"null"
|
|
2147
|
+
],
|
|
2148
|
+
"description": "Seconds until the client may retry (present only for rate-limit errors)"
|
|
2149
|
+
}
|
|
2150
|
+
},
|
|
2151
|
+
"required": [
|
|
2152
|
+
"error"
|
|
2153
|
+
]
|
|
2154
|
+
},
|
|
2155
|
+
"OTPRequestRequest": {
|
|
2156
|
+
"type": "object",
|
|
2157
|
+
"description": "Serializer for OTP request.",
|
|
2158
|
+
"properties": {
|
|
2159
|
+
"identifier": {
|
|
2160
|
+
"type": "string",
|
|
2161
|
+
"minLength": 1,
|
|
2162
|
+
"description": "Email address for OTP delivery"
|
|
2163
|
+
},
|
|
2164
|
+
"source_url": {
|
|
2165
|
+
"type": "string",
|
|
2166
|
+
"format": "uri",
|
|
2167
|
+
"description": "Source URL for tracking registration (e.g., https://my.djangocfg.com)"
|
|
2168
|
+
}
|
|
2169
|
+
},
|
|
2170
|
+
"required": [
|
|
2171
|
+
"identifier"
|
|
2172
|
+
]
|
|
2173
|
+
},
|
|
2174
|
+
"OTPRequestResponse": {
|
|
2175
|
+
"type": "object",
|
|
2176
|
+
"description": "OTP request response.",
|
|
2177
|
+
"properties": {
|
|
2178
|
+
"message": {
|
|
2179
|
+
"type": "string",
|
|
2180
|
+
"description": "Success message"
|
|
2181
|
+
}
|
|
2182
|
+
},
|
|
2183
|
+
"required": [
|
|
2184
|
+
"message"
|
|
2185
|
+
]
|
|
2186
|
+
},
|
|
2187
|
+
"OTPVerifyRequest": {
|
|
2188
|
+
"type": "object",
|
|
2189
|
+
"description": "Serializer for OTP verification.",
|
|
2190
|
+
"properties": {
|
|
2191
|
+
"identifier": {
|
|
2192
|
+
"type": "string",
|
|
2193
|
+
"minLength": 1,
|
|
2194
|
+
"description": "Email address used for OTP request"
|
|
2195
|
+
},
|
|
2196
|
+
"otp": {
|
|
2197
|
+
"type": "string",
|
|
2198
|
+
"minLength": 4,
|
|
2199
|
+
"maxLength": 4
|
|
2200
|
+
},
|
|
2201
|
+
"source_url": {
|
|
2202
|
+
"type": "string",
|
|
2203
|
+
"format": "uri",
|
|
2204
|
+
"description": "Source URL for tracking login (e.g., https://my.djangocfg.com)"
|
|
2205
|
+
}
|
|
2206
|
+
},
|
|
2207
|
+
"required": [
|
|
2208
|
+
"identifier",
|
|
2209
|
+
"otp"
|
|
2210
|
+
]
|
|
2211
|
+
},
|
|
2212
|
+
"OTPVerifyResponse": {
|
|
2213
|
+
"type": "object",
|
|
2214
|
+
"description": "OTP verification response.\n\nWhen 2FA is required:\n- requires_2fa: True\n- session_id: UUID of 2FA verification session\n- refresh/access/user: null\n\nWhen 2FA is not required:\n- requires_2fa: False\n- session_id: null\n- refresh/access/user: populated",
|
|
2215
|
+
"properties": {
|
|
2216
|
+
"requires_2fa": {
|
|
2217
|
+
"type": "boolean",
|
|
2218
|
+
"default": false,
|
|
2219
|
+
"description": "Whether 2FA verification is required"
|
|
2220
|
+
},
|
|
2221
|
+
"session_id": {
|
|
2222
|
+
"type": [
|
|
2223
|
+
"string",
|
|
2224
|
+
"null"
|
|
2225
|
+
],
|
|
2226
|
+
"format": "uuid",
|
|
2227
|
+
"description": "2FA session ID (if requires_2fa is True)"
|
|
2228
|
+
},
|
|
2229
|
+
"refresh": {
|
|
2230
|
+
"type": [
|
|
2231
|
+
"string",
|
|
2232
|
+
"null"
|
|
2233
|
+
],
|
|
2234
|
+
"description": "JWT refresh token (if requires_2fa is False)"
|
|
2235
|
+
},
|
|
2236
|
+
"access": {
|
|
2237
|
+
"type": [
|
|
2238
|
+
"string",
|
|
2239
|
+
"null"
|
|
2240
|
+
],
|
|
2241
|
+
"description": "JWT access token (if requires_2fa is False)"
|
|
2242
|
+
},
|
|
2243
|
+
"user": {
|
|
2244
|
+
"oneOf": [
|
|
2245
|
+
{
|
|
2246
|
+
"$ref": "#/components/schemas/User"
|
|
2247
|
+
},
|
|
2248
|
+
{
|
|
2249
|
+
"type": "null"
|
|
2250
|
+
}
|
|
2251
|
+
],
|
|
2252
|
+
"description": "User information (if requires_2fa is False)"
|
|
2253
|
+
},
|
|
2254
|
+
"should_prompt_2fa": {
|
|
2255
|
+
"type": "boolean",
|
|
2256
|
+
"description": "Whether user should be prompted to enable 2FA"
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2259
|
+
},
|
|
2260
|
+
"PatchedCfgUserUpdateRequest": {
|
|
2261
|
+
"type": "object",
|
|
2262
|
+
"description": "Serializer for updating user profile.",
|
|
2263
|
+
"properties": {
|
|
2264
|
+
"first_name": {
|
|
2265
|
+
"type": "string",
|
|
2266
|
+
"maxLength": 50
|
|
2267
|
+
},
|
|
2268
|
+
"last_name": {
|
|
2269
|
+
"type": "string",
|
|
2270
|
+
"maxLength": 50
|
|
2271
|
+
},
|
|
2272
|
+
"company": {
|
|
2273
|
+
"type": "string",
|
|
2274
|
+
"maxLength": 100
|
|
2275
|
+
},
|
|
2276
|
+
"phone": {
|
|
2277
|
+
"type": "string",
|
|
2278
|
+
"maxLength": 20
|
|
2279
|
+
},
|
|
2280
|
+
"position": {
|
|
2281
|
+
"type": "string",
|
|
2282
|
+
"maxLength": 100
|
|
2283
|
+
},
|
|
2284
|
+
"language": {
|
|
2285
|
+
"type": "string",
|
|
2286
|
+
"maxLength": 10
|
|
2287
|
+
},
|
|
2288
|
+
"timezone": {
|
|
2289
|
+
"type": "string",
|
|
2290
|
+
"description": "IANA timezone name (e.g. 'Asia/Seoul'). Auto-detected from browser via X-Timezone header.",
|
|
2291
|
+
"maxLength": 64
|
|
2292
|
+
}
|
|
2293
|
+
}
|
|
2294
|
+
},
|
|
2295
|
+
"SetupRequest": {
|
|
2296
|
+
"type": "object",
|
|
2297
|
+
"description": "Serializer for starting 2FA setup.",
|
|
2298
|
+
"properties": {
|
|
2299
|
+
"device_name": {
|
|
2300
|
+
"type": "string",
|
|
2301
|
+
"minLength": 1,
|
|
2302
|
+
"default": "Authenticator",
|
|
2303
|
+
"description": "Device name for identification (e.g., 'My iPhone')",
|
|
2304
|
+
"maxLength": 100
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
},
|
|
2308
|
+
"SetupResponse": {
|
|
2309
|
+
"type": "object",
|
|
2310
|
+
"description": "Response serializer for setup initiation.",
|
|
2311
|
+
"properties": {
|
|
2312
|
+
"device_id": {
|
|
2313
|
+
"type": "string",
|
|
2314
|
+
"format": "uuid",
|
|
2315
|
+
"description": "Device ID to use for confirmation"
|
|
2316
|
+
},
|
|
2317
|
+
"secret": {
|
|
2318
|
+
"type": "string",
|
|
2319
|
+
"description": "Base32-encoded TOTP secret (for manual entry)"
|
|
2320
|
+
},
|
|
2321
|
+
"provisioning_uri": {
|
|
2322
|
+
"type": "string",
|
|
2323
|
+
"description": "otpauth:// URI for QR code generation"
|
|
2324
|
+
},
|
|
2325
|
+
"qr_code_base64": {
|
|
2326
|
+
"type": "string",
|
|
2327
|
+
"description": "Base64-encoded QR code image (data URI)"
|
|
2328
|
+
},
|
|
2329
|
+
"expires_in": {
|
|
2330
|
+
"type": "integer",
|
|
2331
|
+
"description": "Seconds until setup expires (typically 600 = 10 minutes)"
|
|
2332
|
+
}
|
|
2333
|
+
},
|
|
2334
|
+
"required": [
|
|
2335
|
+
"device_id",
|
|
2336
|
+
"expires_in",
|
|
2337
|
+
"provisioning_uri",
|
|
2338
|
+
"qr_code_base64",
|
|
2339
|
+
"secret"
|
|
2340
|
+
]
|
|
2341
|
+
},
|
|
2342
|
+
"TokenRefresh": {
|
|
2343
|
+
"type": "object",
|
|
2344
|
+
"properties": {
|
|
2345
|
+
"access": {
|
|
2346
|
+
"type": "string",
|
|
2347
|
+
"readOnly": true
|
|
2348
|
+
},
|
|
2349
|
+
"refresh": {
|
|
2350
|
+
"type": "string"
|
|
2351
|
+
}
|
|
2352
|
+
},
|
|
2353
|
+
"required": [
|
|
2354
|
+
"access",
|
|
2355
|
+
"refresh"
|
|
2356
|
+
]
|
|
2357
|
+
},
|
|
2358
|
+
"TokenRefreshRequest": {
|
|
2359
|
+
"type": "object",
|
|
2360
|
+
"properties": {
|
|
2361
|
+
"refresh": {
|
|
2362
|
+
"type": "string",
|
|
2363
|
+
"minLength": 1
|
|
2364
|
+
}
|
|
2365
|
+
},
|
|
2366
|
+
"required": [
|
|
2367
|
+
"refresh"
|
|
2368
|
+
]
|
|
2369
|
+
},
|
|
2370
|
+
"TotpVerifyUser": {
|
|
2371
|
+
"type": "object",
|
|
2372
|
+
"description": "User data returned after 2FA verification.",
|
|
2373
|
+
"properties": {
|
|
2374
|
+
"id": {
|
|
2375
|
+
"type": "integer",
|
|
2376
|
+
"readOnly": true
|
|
2377
|
+
},
|
|
2378
|
+
"email": {
|
|
2379
|
+
"type": "string",
|
|
2380
|
+
"format": "email",
|
|
2381
|
+
"readOnly": true
|
|
2382
|
+
},
|
|
2383
|
+
"first_name": {
|
|
2384
|
+
"type": [
|
|
2385
|
+
"string",
|
|
2386
|
+
"null"
|
|
2387
|
+
],
|
|
2388
|
+
"maxLength": 50
|
|
2389
|
+
},
|
|
2390
|
+
"last_name": {
|
|
2391
|
+
"type": [
|
|
2392
|
+
"string",
|
|
2393
|
+
"null"
|
|
2394
|
+
],
|
|
2395
|
+
"maxLength": 50
|
|
2396
|
+
},
|
|
2397
|
+
"full_name": {
|
|
2398
|
+
"type": "string",
|
|
2399
|
+
"description": "Get user's full name.",
|
|
2400
|
+
"readOnly": true
|
|
2401
|
+
},
|
|
2402
|
+
"initials": {
|
|
2403
|
+
"type": "string",
|
|
2404
|
+
"description": "Get user's initials for avatar fallback.",
|
|
2405
|
+
"readOnly": true
|
|
2406
|
+
},
|
|
2407
|
+
"display_username": {
|
|
2408
|
+
"type": "string",
|
|
2409
|
+
"description": "Get formatted username for display.",
|
|
2410
|
+
"readOnly": true
|
|
2411
|
+
},
|
|
2412
|
+
"company": {
|
|
2413
|
+
"type": [
|
|
2414
|
+
"string",
|
|
2415
|
+
"null"
|
|
2416
|
+
],
|
|
2417
|
+
"maxLength": 100
|
|
2418
|
+
},
|
|
2419
|
+
"phone": {
|
|
2420
|
+
"type": [
|
|
2421
|
+
"string",
|
|
2422
|
+
"null"
|
|
2423
|
+
],
|
|
2424
|
+
"maxLength": 20
|
|
2425
|
+
},
|
|
2426
|
+
"position": {
|
|
2427
|
+
"type": [
|
|
2428
|
+
"string",
|
|
2429
|
+
"null"
|
|
2430
|
+
],
|
|
2431
|
+
"maxLength": 100
|
|
2432
|
+
},
|
|
2433
|
+
"language": {
|
|
2434
|
+
"type": [
|
|
2435
|
+
"string",
|
|
2436
|
+
"null"
|
|
2437
|
+
],
|
|
2438
|
+
"maxLength": 10
|
|
2439
|
+
},
|
|
2440
|
+
"timezone": {
|
|
2441
|
+
"type": [
|
|
2442
|
+
"string",
|
|
2443
|
+
"null"
|
|
2444
|
+
],
|
|
2445
|
+
"maxLength": 64
|
|
2446
|
+
},
|
|
2447
|
+
"avatar": {
|
|
2448
|
+
"type": [
|
|
2449
|
+
"string",
|
|
2450
|
+
"null"
|
|
2451
|
+
],
|
|
2452
|
+
"format": "uri",
|
|
2453
|
+
"readOnly": true
|
|
2454
|
+
},
|
|
2455
|
+
"is_staff": {
|
|
2456
|
+
"type": "boolean",
|
|
2457
|
+
"readOnly": true,
|
|
2458
|
+
"title": "Staff status",
|
|
2459
|
+
"description": "Designates whether the user can log into this admin site."
|
|
2460
|
+
},
|
|
2461
|
+
"is_superuser": {
|
|
2462
|
+
"type": "boolean",
|
|
2463
|
+
"readOnly": true,
|
|
2464
|
+
"title": "Superuser status",
|
|
2465
|
+
"description": "Designates that this user has all permissions without explicitly assigning them."
|
|
2466
|
+
},
|
|
2467
|
+
"date_joined": {
|
|
2468
|
+
"type": "string",
|
|
2469
|
+
"format": "date-time",
|
|
2470
|
+
"readOnly": true
|
|
2471
|
+
},
|
|
2472
|
+
"last_login": {
|
|
2473
|
+
"type": [
|
|
2474
|
+
"string",
|
|
2475
|
+
"null"
|
|
2476
|
+
],
|
|
2477
|
+
"format": "date-time",
|
|
2478
|
+
"readOnly": true
|
|
2479
|
+
},
|
|
2480
|
+
"unanswered_messages_count": {
|
|
2481
|
+
"type": "integer",
|
|
2482
|
+
"readOnly": true,
|
|
2483
|
+
"default": 0
|
|
2484
|
+
},
|
|
2485
|
+
"api_key": {
|
|
2486
|
+
"type": [
|
|
2487
|
+
"string",
|
|
2488
|
+
"null"
|
|
2489
|
+
],
|
|
2490
|
+
"readOnly": true
|
|
2491
|
+
}
|
|
2492
|
+
},
|
|
2493
|
+
"required": [
|
|
2494
|
+
"api_key",
|
|
2495
|
+
"avatar",
|
|
2496
|
+
"date_joined",
|
|
2497
|
+
"display_username",
|
|
2498
|
+
"email",
|
|
2499
|
+
"full_name",
|
|
2500
|
+
"id",
|
|
2501
|
+
"initials",
|
|
2502
|
+
"is_staff",
|
|
2503
|
+
"is_superuser",
|
|
2504
|
+
"last_login",
|
|
2505
|
+
"unanswered_messages_count"
|
|
2506
|
+
]
|
|
2507
|
+
},
|
|
2508
|
+
"User": {
|
|
2509
|
+
"type": "object",
|
|
2510
|
+
"description": "Serializer for user details.",
|
|
2511
|
+
"properties": {
|
|
2512
|
+
"id": {
|
|
2513
|
+
"type": "integer",
|
|
2514
|
+
"readOnly": true
|
|
2515
|
+
},
|
|
2516
|
+
"email": {
|
|
2517
|
+
"type": "string",
|
|
2518
|
+
"format": "email",
|
|
2519
|
+
"readOnly": true
|
|
2520
|
+
},
|
|
2521
|
+
"first_name": {
|
|
2522
|
+
"type": [
|
|
2523
|
+
"string",
|
|
2524
|
+
"null"
|
|
2525
|
+
],
|
|
2526
|
+
"maxLength": 50
|
|
2527
|
+
},
|
|
2528
|
+
"last_name": {
|
|
2529
|
+
"type": [
|
|
2530
|
+
"string",
|
|
2531
|
+
"null"
|
|
2532
|
+
],
|
|
2533
|
+
"maxLength": 50
|
|
2534
|
+
},
|
|
2535
|
+
"full_name": {
|
|
2536
|
+
"type": "string",
|
|
2537
|
+
"description": "Get user's full name.",
|
|
2538
|
+
"readOnly": true
|
|
2539
|
+
},
|
|
2540
|
+
"initials": {
|
|
2541
|
+
"type": "string",
|
|
2542
|
+
"description": "Get user's initials for avatar fallback.",
|
|
2543
|
+
"readOnly": true
|
|
2544
|
+
},
|
|
2545
|
+
"display_username": {
|
|
2546
|
+
"type": "string",
|
|
2547
|
+
"description": "Get formatted username for display.",
|
|
2548
|
+
"readOnly": true
|
|
2549
|
+
},
|
|
2550
|
+
"company": {
|
|
2551
|
+
"type": [
|
|
2552
|
+
"string",
|
|
2553
|
+
"null"
|
|
2554
|
+
],
|
|
2555
|
+
"maxLength": 100
|
|
2556
|
+
},
|
|
2557
|
+
"phone": {
|
|
2558
|
+
"type": [
|
|
2559
|
+
"string",
|
|
2560
|
+
"null"
|
|
2561
|
+
],
|
|
2562
|
+
"maxLength": 20
|
|
2563
|
+
},
|
|
2564
|
+
"position": {
|
|
2565
|
+
"type": [
|
|
2566
|
+
"string",
|
|
2567
|
+
"null"
|
|
2568
|
+
],
|
|
2569
|
+
"maxLength": 100
|
|
2570
|
+
},
|
|
2571
|
+
"language": {
|
|
2572
|
+
"type": [
|
|
2573
|
+
"string",
|
|
2574
|
+
"null"
|
|
2575
|
+
],
|
|
2576
|
+
"maxLength": 10
|
|
2577
|
+
},
|
|
2578
|
+
"timezone": {
|
|
2579
|
+
"type": [
|
|
2580
|
+
"string",
|
|
2581
|
+
"null"
|
|
2582
|
+
],
|
|
2583
|
+
"maxLength": 64
|
|
2584
|
+
},
|
|
2585
|
+
"avatar": {
|
|
2586
|
+
"type": [
|
|
2587
|
+
"string",
|
|
2588
|
+
"null"
|
|
2589
|
+
],
|
|
2590
|
+
"format": "uri",
|
|
2591
|
+
"readOnly": true
|
|
2592
|
+
},
|
|
2593
|
+
"is_staff": {
|
|
2594
|
+
"type": "boolean",
|
|
2595
|
+
"readOnly": true,
|
|
2596
|
+
"title": "Staff status",
|
|
2597
|
+
"description": "Designates whether the user can log into this admin site."
|
|
2598
|
+
},
|
|
2599
|
+
"is_superuser": {
|
|
2600
|
+
"type": "boolean",
|
|
2601
|
+
"readOnly": true,
|
|
2602
|
+
"title": "Superuser status",
|
|
2603
|
+
"description": "Designates that this user has all permissions without explicitly assigning them."
|
|
2604
|
+
},
|
|
2605
|
+
"date_joined": {
|
|
2606
|
+
"type": "string",
|
|
2607
|
+
"format": "date-time",
|
|
2608
|
+
"readOnly": true
|
|
2609
|
+
},
|
|
2610
|
+
"last_login": {
|
|
2611
|
+
"type": [
|
|
2612
|
+
"string",
|
|
2613
|
+
"null"
|
|
2614
|
+
],
|
|
2615
|
+
"format": "date-time",
|
|
2616
|
+
"readOnly": true
|
|
2617
|
+
},
|
|
2618
|
+
"unanswered_messages_count": {
|
|
2619
|
+
"type": "integer",
|
|
2620
|
+
"readOnly": true,
|
|
2621
|
+
"default": 0
|
|
2622
|
+
},
|
|
2623
|
+
"centrifugo": {
|
|
2624
|
+
"oneOf": [
|
|
2625
|
+
{
|
|
2626
|
+
"$ref": "#/components/schemas/CentrifugoToken"
|
|
2627
|
+
},
|
|
2628
|
+
{
|
|
2629
|
+
"type": "null"
|
|
2630
|
+
}
|
|
2631
|
+
],
|
|
2632
|
+
"readOnly": true
|
|
2633
|
+
},
|
|
2634
|
+
"api_key": {
|
|
2635
|
+
"type": [
|
|
2636
|
+
"string",
|
|
2637
|
+
"null"
|
|
2638
|
+
],
|
|
2639
|
+
"readOnly": true
|
|
2640
|
+
}
|
|
2641
|
+
},
|
|
2642
|
+
"required": [
|
|
2643
|
+
"api_key",
|
|
2644
|
+
"avatar",
|
|
2645
|
+
"centrifugo",
|
|
2646
|
+
"date_joined",
|
|
2647
|
+
"display_username",
|
|
2648
|
+
"email",
|
|
2649
|
+
"full_name",
|
|
2650
|
+
"id",
|
|
2651
|
+
"initials",
|
|
2652
|
+
"is_staff",
|
|
2653
|
+
"is_superuser",
|
|
2654
|
+
"last_login",
|
|
2655
|
+
"unanswered_messages_count"
|
|
2656
|
+
]
|
|
2657
|
+
},
|
|
2658
|
+
"VerifyBackupRequest": {
|
|
2659
|
+
"type": "object",
|
|
2660
|
+
"description": "Serializer for backup code verification during login.",
|
|
2661
|
+
"properties": {
|
|
2662
|
+
"session_id": {
|
|
2663
|
+
"type": "string",
|
|
2664
|
+
"format": "uuid",
|
|
2665
|
+
"description": "2FA session ID from login response"
|
|
2666
|
+
},
|
|
2667
|
+
"backup_code": {
|
|
2668
|
+
"type": "string",
|
|
2669
|
+
"minLength": 8,
|
|
2670
|
+
"description": "8-character backup recovery code",
|
|
2671
|
+
"maxLength": 8
|
|
2672
|
+
}
|
|
2673
|
+
},
|
|
2674
|
+
"required": [
|
|
2675
|
+
"backup_code",
|
|
2676
|
+
"session_id"
|
|
2677
|
+
]
|
|
2678
|
+
},
|
|
2679
|
+
"VerifyRequest": {
|
|
2680
|
+
"type": "object",
|
|
2681
|
+
"description": "Serializer for TOTP code verification during login.",
|
|
2682
|
+
"properties": {
|
|
2683
|
+
"session_id": {
|
|
2684
|
+
"type": "string",
|
|
2685
|
+
"format": "uuid",
|
|
2686
|
+
"description": "2FA session ID from login response"
|
|
2687
|
+
},
|
|
2688
|
+
"code": {
|
|
2689
|
+
"type": "string",
|
|
2690
|
+
"minLength": 6,
|
|
2691
|
+
"description": "6-digit TOTP code from authenticator app",
|
|
2692
|
+
"maxLength": 6
|
|
2693
|
+
}
|
|
2694
|
+
},
|
|
2695
|
+
"required": [
|
|
2696
|
+
"code",
|
|
2697
|
+
"session_id"
|
|
2698
|
+
]
|
|
2699
|
+
},
|
|
2700
|
+
"VerifyResponse": {
|
|
2701
|
+
"type": "object",
|
|
2702
|
+
"description": "Response serializer for successful 2FA verification.",
|
|
2703
|
+
"properties": {
|
|
2704
|
+
"message": {
|
|
2705
|
+
"type": "string"
|
|
2706
|
+
},
|
|
2707
|
+
"access_token": {
|
|
2708
|
+
"type": "string",
|
|
2709
|
+
"description": "JWT access token"
|
|
2710
|
+
},
|
|
2711
|
+
"refresh_token": {
|
|
2712
|
+
"type": "string",
|
|
2713
|
+
"description": "JWT refresh token"
|
|
2714
|
+
},
|
|
2715
|
+
"user": {
|
|
2716
|
+
"allOf": [
|
|
2717
|
+
{
|
|
2718
|
+
"$ref": "#/components/schemas/TotpVerifyUser"
|
|
2719
|
+
}
|
|
2720
|
+
],
|
|
2721
|
+
"description": "User profile data"
|
|
2722
|
+
},
|
|
2723
|
+
"remaining_backup_codes": {
|
|
2724
|
+
"type": "integer",
|
|
2725
|
+
"description": "Number of remaining backup codes (if backup code was used)"
|
|
2726
|
+
},
|
|
2727
|
+
"warning": {
|
|
2728
|
+
"type": "string",
|
|
2729
|
+
"description": "Warning message (e.g., low backup codes)"
|
|
2730
|
+
}
|
|
2731
|
+
},
|
|
2732
|
+
"required": [
|
|
2733
|
+
"access_token",
|
|
2734
|
+
"message",
|
|
2735
|
+
"refresh_token",
|
|
2736
|
+
"user"
|
|
2737
|
+
]
|
|
2738
|
+
},
|
|
2739
|
+
"cfg_accounts_oauth_connections_response_200_AutoRef": {
|
|
2740
|
+
"type": "array",
|
|
2741
|
+
"items": {
|
|
2742
|
+
"$ref": "#/components/schemas/OAuthConnection"
|
|
2743
|
+
}
|
|
2744
|
+
},
|
|
2745
|
+
"cfg_accounts_oauth_disconnect_response_200_AutoRef": {
|
|
2746
|
+
"type": "object",
|
|
2747
|
+
"properties": {
|
|
2748
|
+
"message": {
|
|
2749
|
+
"type": "string"
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
2752
|
+
},
|
|
2753
|
+
"cfg_totp_disable_response_200_AutoRef": {
|
|
2754
|
+
"description": "2FA disabled successfully"
|
|
2755
|
+
}
|
|
2756
|
+
},
|
|
2757
|
+
"securitySchemes": {
|
|
2758
|
+
"apiKeyAuth": {
|
|
2759
|
+
"type": "apiKey",
|
|
2760
|
+
"in": "header",
|
|
2761
|
+
"name": "X-API-Key"
|
|
2762
|
+
},
|
|
2763
|
+
"basicAuth": {
|
|
2764
|
+
"type": "http",
|
|
2765
|
+
"scheme": "basic"
|
|
2766
|
+
},
|
|
2767
|
+
"cookieAuth": {
|
|
2768
|
+
"type": "apiKey",
|
|
2769
|
+
"in": "cookie",
|
|
2770
|
+
"name": "sessionid"
|
|
2771
|
+
},
|
|
2772
|
+
"jwtAuth": {
|
|
2773
|
+
"type": "http",
|
|
2774
|
+
"scheme": "bearer",
|
|
2775
|
+
"bearerFormat": "JWT"
|
|
2776
|
+
},
|
|
2777
|
+
"jwtAuthWithLastLogin": {
|
|
2778
|
+
"type": "http",
|
|
2779
|
+
"scheme": "bearer",
|
|
2780
|
+
"bearerFormat": "JWT"
|
|
2781
|
+
}
|
|
2782
|
+
}
|
|
2783
|
+
},
|
|
2784
|
+
"servers": [
|
|
2785
|
+
{
|
|
2786
|
+
"url": "http://localhost:8000"
|
|
2787
|
+
}
|
|
2788
|
+
]
|
|
2789
|
+
}
|