academe-kit 0.8.9 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -221,6 +221,221 @@ export interface paths {
221
221
  };
222
222
  trace?: never;
223
223
  };
224
+ "/auth/forgot-password": {
225
+ parameters: {
226
+ query?: never;
227
+ header?: never;
228
+ path?: never;
229
+ cookie?: never;
230
+ };
231
+ get?: never;
232
+ put?: never;
233
+ /**
234
+ * Request password reset email
235
+ * @description Sends a password reset email to the specified address if a user with that email exists.
236
+ *
237
+ * **Security Note:**
238
+ * For security reasons, this endpoint always returns a success response regardless of whether
239
+ * the email exists in the system. This prevents email enumeration attacks.
240
+ *
241
+ * **Flow:**
242
+ * 1. Client sends email address
243
+ * 2. Backend searches for user by email in Keycloak
244
+ * 3. If user exists, Keycloak sends password reset email with UPDATE_PASSWORD action
245
+ * 4. User receives email with link valid for 1 hour
246
+ * 5. Endpoint returns success (regardless of whether email was found)
247
+ *
248
+ * **Email Template:**
249
+ * The email sent uses the Keycloak realm's configured email template for password reset.
250
+ */
251
+ post: {
252
+ parameters: {
253
+ query?: never;
254
+ header?: never;
255
+ path?: never;
256
+ cookie?: never;
257
+ };
258
+ requestBody: {
259
+ content: {
260
+ "application/json": {
261
+ /**
262
+ * Format: email
263
+ * @description User's email address
264
+ * @example user@example.com
265
+ */
266
+ email: string;
267
+ };
268
+ };
269
+ };
270
+ responses: {
271
+ /** @description Request processed successfully (always returned for security) */
272
+ 200: {
273
+ headers: {
274
+ [name: string]: unknown;
275
+ };
276
+ content: {
277
+ "application/json": {
278
+ /** @example success */
279
+ status?: string;
280
+ /** @example If this email is registered, you will receive password reset instructions. */
281
+ message?: string;
282
+ };
283
+ };
284
+ };
285
+ /** @description Bad Request - Email not provided */
286
+ 400: {
287
+ headers: {
288
+ [name: string]: unknown;
289
+ };
290
+ content: {
291
+ "application/json": {
292
+ /** @example error */
293
+ status?: string;
294
+ /** @example Email is required */
295
+ message?: string;
296
+ };
297
+ };
298
+ };
299
+ /** @description Internal Server Error */
300
+ 500: {
301
+ headers: {
302
+ [name: string]: unknown;
303
+ };
304
+ content: {
305
+ "application/json": {
306
+ /** @example error */
307
+ status?: string;
308
+ /** @example Internal server error */
309
+ message?: string;
310
+ };
311
+ };
312
+ };
313
+ };
314
+ };
315
+ delete?: never;
316
+ options?: never;
317
+ head?: never;
318
+ patch?: never;
319
+ trace?: never;
320
+ };
321
+ "/auth/google-exchange": {
322
+ parameters: {
323
+ query?: never;
324
+ header?: never;
325
+ path?: never;
326
+ cookie?: never;
327
+ };
328
+ get?: never;
329
+ put?: never;
330
+ /**
331
+ * Exchange Google access token for Keycloak tokens
332
+ * @description Exchanges a Google access token for Keycloak tokens.
333
+ *
334
+ * **Flow:**
335
+ * 1. Client sends Google access token
336
+ * 2. Backend fetches user email from Google Userinfo API
337
+ * 3. Backend verifies the email exists in the local database
338
+ * 4. If user exists, performs Keycloak token exchange
339
+ * 5. Returns Keycloak tokens (access_token, refresh_token, etc.)
340
+ *
341
+ * **Error Cases:**
342
+ * - 400: Invalid or expired Google token
343
+ * - 404: User email not found in database
344
+ */
345
+ post: {
346
+ parameters: {
347
+ query?: never;
348
+ header?: never;
349
+ path?: never;
350
+ cookie?: never;
351
+ };
352
+ requestBody: {
353
+ content: {
354
+ "application/json": {
355
+ /**
356
+ * @description Google OAuth2 access token
357
+ * @example ya29.a0AfH6SM...
358
+ */
359
+ googleAccessToken: string;
360
+ };
361
+ };
362
+ };
363
+ responses: {
364
+ /** @description Token exchange successful */
365
+ 200: {
366
+ headers: {
367
+ [name: string]: unknown;
368
+ };
369
+ content: {
370
+ "application/json": {
371
+ /** @example success */
372
+ status?: string;
373
+ data?: {
374
+ /** @description Keycloak access token */
375
+ access_token?: string;
376
+ /** @description Keycloak refresh token */
377
+ refresh_token?: string;
378
+ /** @description Token expiration time in seconds */
379
+ expires_in?: number;
380
+ /** @description Refresh token expiration time in seconds */
381
+ refresh_expires_in?: number;
382
+ /** @example Bearer */
383
+ token_type?: string;
384
+ scope?: string;
385
+ };
386
+ };
387
+ };
388
+ };
389
+ /** @description Bad Request - Invalid Google token or missing googleAccessToken */
390
+ 400: {
391
+ headers: {
392
+ [name: string]: unknown;
393
+ };
394
+ content: {
395
+ "application/json": {
396
+ /** @example error */
397
+ status?: string;
398
+ /** @example Token do Google inválido ou expirado */
399
+ message?: string;
400
+ };
401
+ };
402
+ };
403
+ /** @description Not Found - User email not registered in database */
404
+ 404: {
405
+ headers: {
406
+ [name: string]: unknown;
407
+ };
408
+ content: {
409
+ "application/json": {
410
+ /** @example error */
411
+ status?: string;
412
+ /** @example Usuário não encontrado */
413
+ message?: string;
414
+ };
415
+ };
416
+ };
417
+ /** @description Internal Server Error */
418
+ 500: {
419
+ headers: {
420
+ [name: string]: unknown;
421
+ };
422
+ content: {
423
+ "application/json": {
424
+ /** @example error */
425
+ status?: string;
426
+ /** @example Internal server error */
427
+ message?: string;
428
+ };
429
+ };
430
+ };
431
+ };
432
+ };
433
+ delete?: never;
434
+ options?: never;
435
+ head?: never;
436
+ patch?: never;
437
+ trace?: never;
438
+ };
224
439
  "/auth/token": {
225
440
  parameters: {
226
441
  query?: never;
@@ -832,13 +1047,24 @@ export interface paths {
832
1047
  };
833
1048
  /**
834
1049
  * List all certificates
835
- * @description Retrieve a list of all certificates in the system.
1050
+ * @description Retrieve a paginated list of all certificates in the system.
836
1051
  * Each certificate includes course information (id, title, description) when available.
837
1052
  * Course data is extracted from the related Quiz through QuizAttempt.
838
1053
  */
839
1054
  get: {
840
1055
  parameters: {
841
- query?: never;
1056
+ query?: {
1057
+ /** @description Filter certificates by user ID */
1058
+ userId?: string;
1059
+ /** @description Search term */
1060
+ search?: components["parameters"]["search"];
1061
+ /** @description Page number */
1062
+ page?: components["parameters"]["page"];
1063
+ /** @description Items per page */
1064
+ limit?: components["parameters"]["limit"];
1065
+ /** @description Whether to include course data in the response (default true). Pass false to skip course lookup. */
1066
+ includeCourse?: boolean;
1067
+ };
842
1068
  header?: never;
843
1069
  path?: never;
844
1070
  cookie?: never;
@@ -855,6 +1081,16 @@ export interface paths {
855
1081
  /** @example success */
856
1082
  status?: string;
857
1083
  data?: components["schemas"]["Certificate"][];
1084
+ meta?: {
1085
+ /** @example 10 */
1086
+ total?: number;
1087
+ /** @example 1 */
1088
+ page?: number;
1089
+ /** @example 10 */
1090
+ limit?: number;
1091
+ /** @example 1 */
1092
+ totalPages?: number;
1093
+ };
858
1094
  };
859
1095
  };
860
1096
  };
@@ -890,8 +1126,6 @@ export interface paths {
890
1126
  /** @example success */
891
1127
  status?: string;
892
1128
  data?: components["schemas"]["Certificate"];
893
- /** @example Certificate created successfully */
894
- message?: string;
895
1129
  };
896
1130
  };
897
1131
  };
@@ -969,18 +1203,11 @@ export interface paths {
969
1203
  requestBody?: never;
970
1204
  responses: {
971
1205
  /** @description Certificate deleted successfully */
972
- 200: {
1206
+ 204: {
973
1207
  headers: {
974
1208
  [name: string]: unknown;
975
1209
  };
976
- content: {
977
- "application/json": {
978
- /** @example success */
979
- status?: string;
980
- /** @example Certificate deleted successfully */
981
- message?: string;
982
- };
983
- };
1210
+ content?: never;
984
1211
  };
985
1212
  400: components["responses"]["BadRequest"];
986
1213
  401: components["responses"]["Unauthorized"];
@@ -1020,8 +1247,6 @@ export interface paths {
1020
1247
  /** @example success */
1021
1248
  status?: string;
1022
1249
  data?: components["schemas"]["Certificate"];
1023
- /** @example Certificate updated successfully */
1024
- message?: string;
1025
1250
  };
1026
1251
  };
1027
1252
  };
@@ -1033,6 +1258,109 @@ export interface paths {
1033
1258
  };
1034
1259
  trace?: never;
1035
1260
  };
1261
+ "/certificates/{id}/download": {
1262
+ parameters: {
1263
+ query?: never;
1264
+ header?: never;
1265
+ path?: never;
1266
+ cookie?: never;
1267
+ };
1268
+ /**
1269
+ * Download certificate PDF
1270
+ * @description Download the PDF of a specific certificate.
1271
+ * Acts as a proxy to download from S3, avoiding CORS issues.
1272
+ * Only the certificate owner can download their certificate.
1273
+ */
1274
+ get: {
1275
+ parameters: {
1276
+ query?: never;
1277
+ header?: never;
1278
+ path: {
1279
+ /** @description Resource ID */
1280
+ id: components["parameters"]["id"];
1281
+ };
1282
+ cookie?: never;
1283
+ };
1284
+ requestBody?: never;
1285
+ responses: {
1286
+ /** @description Certificate PDF file */
1287
+ 200: {
1288
+ headers: {
1289
+ [name: string]: unknown;
1290
+ };
1291
+ content: {
1292
+ "application/pdf": string;
1293
+ };
1294
+ };
1295
+ 401: components["responses"]["Unauthorized"];
1296
+ 403: components["responses"]["Forbidden"];
1297
+ 404: components["responses"]["NotFound"];
1298
+ 500: components["responses"]["ServerError"];
1299
+ };
1300
+ };
1301
+ put?: never;
1302
+ post?: never;
1303
+ delete?: never;
1304
+ options?: never;
1305
+ head?: never;
1306
+ patch?: never;
1307
+ trace?: never;
1308
+ };
1309
+ "/certificates/generate": {
1310
+ parameters: {
1311
+ query?: never;
1312
+ header?: never;
1313
+ path?: never;
1314
+ cookie?: never;
1315
+ };
1316
+ get?: never;
1317
+ put?: never;
1318
+ /**
1319
+ * Generate a certificate PDF server-side
1320
+ * @description Generates a certificate PDF on the server and creates the certificate record.
1321
+ * This eliminates CORS issues by downloading the template image on the server.
1322
+ */
1323
+ post: {
1324
+ parameters: {
1325
+ query?: never;
1326
+ header?: never;
1327
+ path?: never;
1328
+ cookie?: never;
1329
+ };
1330
+ requestBody: {
1331
+ content: {
1332
+ "application/json": components["schemas"]["GenerateCertificateDto"];
1333
+ };
1334
+ };
1335
+ responses: {
1336
+ /** @description Certificate generated and created successfully */
1337
+ 201: {
1338
+ headers: {
1339
+ [name: string]: unknown;
1340
+ };
1341
+ content: {
1342
+ "application/json": {
1343
+ /** @example success */
1344
+ status?: string;
1345
+ data?: {
1346
+ certificate?: components["schemas"]["Certificate"];
1347
+ /** @example https://s3.amazonaws.com/bucket/certificate.pdf */
1348
+ pdfUrl?: string;
1349
+ };
1350
+ };
1351
+ };
1352
+ };
1353
+ 400: components["responses"]["BadRequest"];
1354
+ 401: components["responses"]["Unauthorized"];
1355
+ 500: components["responses"]["ServerError"];
1356
+ };
1357
+ };
1358
+ delete?: never;
1359
+ options?: never;
1360
+ head?: never;
1361
+ patch?: never;
1362
+ trace?: never;
1363
+ };
1036
1364
  "/classrooms": {
1037
1365
  parameters: {
1038
1366
  query?: never;
@@ -9540,6 +9868,8 @@ export interface paths {
9540
9868
  requestBody: {
9541
9869
  content: {
9542
9870
  "application/json": {
9871
+ /** @example sa@academe.com.br */
9872
+ email?: string;
9543
9873
  /** @example John */
9544
9874
  firstName?: string;
9545
9875
  /** @example Doe */
@@ -9939,7 +10269,19 @@ export interface paths {
9939
10269
  head?: never;
9940
10270
  /**
9941
10271
  * Update user
9942
- * @description Update user information
10272
+ * @description Update user information.
10273
+ *
10274
+ * **Profile and seat code behavior:**
10275
+ * - Send `groupId` to change the user's profile/group.
10276
+ * - When `groupId` changes, the system will:
10277
+ * 1. Release the previous seat code used by the user (`isReserved = false`)
10278
+ * 2. Allocate a seat code for the new group in the same institution registration
10279
+ * 3. Create a new seat code automatically if none is available for that group
10280
+ *
10281
+ * **Important:**
10282
+ * - The target group must exist.
10283
+ * - The institution must have a seat configured for the target group.
10284
+ * - If any institution registration cannot be migrated to the new group, the operation fails.
9943
10285
  */
9944
10286
  patch: {
9945
10287
  parameters: {
@@ -10255,6 +10597,165 @@ export interface paths {
10255
10597
  patch?: never;
10256
10598
  trace?: never;
10257
10599
  };
10600
+ "/users/register-hotmart": {
10601
+ parameters: {
10602
+ query?: never;
10603
+ header?: never;
10604
+ path?: never;
10605
+ cookie?: never;
10606
+ };
10607
+ get?: never;
10608
+ put?: never;
10609
+ /**
10610
+ * Hotmart webhook for user registration and lifecycle
10611
+ * @description Public endpoint that receives webhook events from Hotmart.
10612
+ * Handles user creation and deactivation based on purchase events.
10613
+ *
10614
+ * **Supported Events:**
10615
+ *
10616
+ * | Event | Action |
10617
+ * |-------|--------|
10618
+ * | `PURCHASE_APPROVED` | Enqueues user creation with buyer data |
10619
+ * | `PURCHASE_CANCELED` | Deactivates (soft deletes) the user |
10620
+ * | `PURCHASE_REFUNDED` | Deactivates (soft deletes) the user |
10621
+ * | `PURCHASE_CHARGEBACK` | Deactivates (soft deletes) the user |
10622
+ *
10623
+ * **User Creation Flow (PURCHASE_APPROVED):**
10624
+ * 1. Extracts buyer information from the Hotmart payload
10625
+ * 2. Determines institution based on offer code
10626
+ * 3. Enqueues user creation request for async processing
10627
+ * 4. User is created in Keycloak and database by the worker
10628
+ *
10629
+ * **Offer-based Institution Assignment:**
10630
+ * - Offer code `d9to7y3w` → Institution `580268b1-458d-4f4c-901d-281eccf3b40d`
10631
+ *
10632
+ * **User Deactivation Flow:**
10633
+ * 1. Looks up the user by buyer email
10634
+ * 2. Soft deletes the user (marks as inactive)
10635
+ * 3. Disables the user in Keycloak
10636
+ *
10637
+ * All events return HTTP 200 to acknowledge receipt.
10638
+ * Unrecognized events are logged and ignored.
10639
+ */
10640
+ post: {
10641
+ parameters: {
10642
+ query?: never;
10643
+ header?: never;
10644
+ path?: never;
10645
+ cookie?: never;
10646
+ };
10647
+ requestBody: {
10648
+ content: {
10649
+ "application/json": {
10650
+ /**
10651
+ * Format: uuid
10652
+ * @description Unique webhook event ID
10653
+ * @example d96fafd0-75ed-4ca7-8fa8-c6a57f48e384
10654
+ */
10655
+ id: string;
10656
+ /**
10657
+ * @description Hotmart event type
10658
+ * @example PURCHASE_APPROVED
10659
+ * @enum {string}
10660
+ */
10661
+ event: "PURCHASE_APPROVED" | "PURCHASE_CANCELED" | "PURCHASE_REFUNDED" | "PURCHASE_CHARGEBACK" | "PURCHASE_COMPLETE" | "PURCHASE_PROTEST" | "PURCHASE_DELAYED";
10662
+ /**
10663
+ * @description Event creation timestamp (Unix milliseconds)
10664
+ * @example 1773161133350
10665
+ */
10666
+ creation_date: number;
10667
+ /**
10668
+ * @description Webhook payload version
10669
+ * @example 2.0.0
10670
+ */
10671
+ version: string;
10672
+ data: {
10673
+ buyer: {
10674
+ /**
10675
+ * Format: email
10676
+ * @example buyer@example.com
10677
+ */
10678
+ email: string;
10679
+ /** @example Teste */
10680
+ first_name: string;
10681
+ /** @example Comprador */
10682
+ last_name: string;
10683
+ /** @example Teste Comprador */
10684
+ name?: string;
10685
+ /** @example 69526128664 */
10686
+ document?: string;
10687
+ /** @example CPF */
10688
+ document_type?: string;
10689
+ /** @example 99999999900 */
10690
+ checkout_phone?: string;
10691
+ };
10692
+ purchase: {
10693
+ /** @example HP16015479281022 */
10694
+ transaction: string;
10695
+ /** @example APPROVED */
10696
+ status: string;
10697
+ offer?: {
10698
+ /**
10699
+ * @description Offer code used to determine institution assignment
10700
+ * @example d9to7y3w
10701
+ */
10702
+ code?: string;
10703
+ };
10704
+ };
10705
+ product: {
10706
+ id?: number;
10707
+ name?: string;
10708
+ /** Format: uuid */
10709
+ ucode?: string;
10710
+ };
10711
+ subscription?: {
10712
+ subscriber?: {
10713
+ code?: string;
10714
+ };
10715
+ plan?: {
10716
+ name?: string;
10717
+ id?: number;
10718
+ };
10719
+ status?: string;
10720
+ };
10721
+ };
10722
+ };
10723
+ };
10724
+ };
10725
+ responses: {
10726
+ /** @description Webhook event processed successfully */
10727
+ 200: {
10728
+ headers: {
10729
+ [name: string]: unknown;
10730
+ };
10731
+ content: {
10732
+ "application/json": {
10733
+ /** @example success */
10734
+ status?: string;
10735
+ /**
10736
+ * @description Action taken for the event
10737
+ * @example user_creation_enqueued
10738
+ * @enum {string}
10739
+ */
10740
+ action?: "user_creation_enqueued" | "user_deactivated" | "user_not_found" | "event_ignored";
10741
+ /**
10742
+ * Format: uuid
10743
+ * @description Request ID for tracking (only on user_creation_enqueued)
10744
+ * @example 550e8400-e29b-41d4-a716-446655440000
10745
+ */
10746
+ requestId?: string;
10747
+ };
10748
+ };
10749
+ };
10750
+ 500: components["responses"]["ServerError"];
10751
+ };
10752
+ };
10753
+ delete?: never;
10754
+ options?: never;
10755
+ head?: never;
10756
+ patch?: never;
10757
+ trace?: never;
10758
+ };
10258
10759
  }
10259
10760
  export type webhooks = Record<string, never>;
10260
10761
  export interface components {
@@ -11500,6 +12001,20 @@ export interface components {
11500
12001
  };
11501
12002
  };
11502
12003
  };
12004
+ ForgotPasswordRequest: {
12005
+ /**
12006
+ * Format: email
12007
+ * @description User's email address for password reset
12008
+ * @example user@example.com
12009
+ */
12010
+ email: string;
12011
+ };
12012
+ ForgotPasswordResponse: {
12013
+ /** @example success */
12014
+ status?: string;
12015
+ /** @example If this email is registered, you will receive password reset instructions. */
12016
+ message?: string;
12017
+ };
11503
12018
  CreateInstitutionClassroomDto: {
11504
12019
  /**
11505
12020
  * Format: uuid
@@ -11680,10 +12195,14 @@ export interface components {
11680
12195
  * @description Product ID associated with this seat
11681
12196
  */
11682
12197
  productId?: string;
12198
+ /** @description Total number of seat codes for this seat */
12199
+ total?: number;
11683
12200
  /** @description Available quantity for this group in the institution */
11684
12201
  availableQuantity?: number;
11685
12202
  /** @description Number of users currently assigned to this group in the institution */
11686
12203
  usedQuantity?: number;
12204
+ /** @description Number of reserved seat codes without active registration */
12205
+ reservedQuantity?: number;
11687
12206
  /** Format: date-time */
11688
12207
  createdAt?: string;
11689
12208
  /** Format: date-time */
@@ -12172,6 +12691,27 @@ export interface components {
12172
12691
  /** Format: uri */
12173
12692
  url?: string;
12174
12693
  };
12694
+ GenerateCertificateDto: {
12695
+ /** Format: uuid */
12696
+ userId: string;
12697
+ /** Format: uuid */
12698
+ quizAttemptId?: string;
12699
+ /** Format: uuid */
12700
+ certificateTemplateId: string;
12701
+ /** @example João Silva */
12702
+ studentName: string;
12703
+ /** @example Introdução ao JavaScript */
12704
+ quizTitle: string;
12705
+ /** @example 85 */
12706
+ score?: number;
12707
+ /** @example CERT-2024-000001 */
12708
+ certificateNumber?: string;
12709
+ /**
12710
+ * Format: date-time
12711
+ * @example 2024-01-01T00:00:00.000Z
12712
+ */
12713
+ issuedAt?: string;
12714
+ };
12175
12715
  CreateGuardianDto: {
12176
12716
  /**
12177
12717
  * Format: email
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "academe-kit",
3
- "version": "0.8.9",
3
+ "version": "0.9.1",
4
4
  "type": "module",
5
5
  "description": "Official React SDK for Academe ecosystem - Authentication, protected routes, API services, and UI components for educational management applications",
6
6
  "main": "dist/index.cjs",