@aurabase/auth 0.5.4 → 0.6.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.
package/dist/index.cjs CHANGED
@@ -13,6 +13,9 @@ var AuthAdminService = class extends core.BaseService {
13
13
  return "/v1/auth/admin";
14
14
  }
15
15
  // -- Users ----------------------------------------------------------------
16
+ /**
17
+ * Liste les utilisateurs du projet, avec recherche (`search`) et pagination (`limit`, `offset`).
18
+ */
16
19
  async listUsers(params) {
17
20
  const query = new URLSearchParams();
18
21
  if (params?.limit !== void 0) query.set("limit", String(params.limit));
@@ -21,34 +24,52 @@ var AuthAdminService = class extends core.BaseService {
21
24
  const qs = query.toString();
22
25
  return this.request("GET", `${this.prefix}/users${qs ? "?" + qs : ""}`);
23
26
  }
27
+ /** Lit un utilisateur par son identifiant. */
24
28
  async getUser(userId) {
25
29
  return this.request("GET", `${this.prefix}/users/${userId}`);
26
30
  }
31
+ /**
32
+ * Crée un utilisateur sans passer par l'inscription publique (e-mail, mot de passe, métadonnées, rôle).
33
+ */
27
34
  async createUser(data) {
28
35
  return this.request("POST", `${this.prefix}/users`, data);
29
36
  }
37
+ /** Met à jour un utilisateur : seuls les champs fournis changent. */
30
38
  async updateUser(userId, data) {
31
39
  return this.request("PUT", `${this.prefix}/users/${userId}`, data);
32
40
  }
41
+ /** Supprime un utilisateur. */
33
42
  async deleteUser(userId) {
34
43
  return this.request("DELETE", `${this.prefix}/users/${userId}`);
35
44
  }
45
+ /** Bannit un utilisateur : il ne peut plus se connecter. */
36
46
  async banUser(userId) {
37
47
  return this.request("POST", `${this.prefix}/users/${userId}/ban`, {});
38
48
  }
49
+ /** Lève le bannissement d'un utilisateur. */
39
50
  async unbanUser(userId) {
40
51
  return this.request("POST", `${this.prefix}/users/${userId}/unban`, {});
41
52
  }
53
+ /**
54
+ * Génère un lien à usage unique pour un utilisateur (`'magic'`, `'recovery'` ou `'invite'`) et renvoie `{ link, token }`.
55
+ */
42
56
  async generateLink(userId, type) {
43
57
  return this.request("POST", `${this.prefix}/users/${userId}/generate-link`, { type });
44
58
  }
59
+ /**
60
+ * Statistiques des utilisateurs : total, vérifiés, bannis, avec MFA et nouveaux sur 7 jours.
61
+ */
45
62
  async getUserStats() {
46
63
  return this.request("GET", `${this.prefix}/users/stats`);
47
64
  }
65
+ /** Liste les identités liées à un utilisateur (fournisseurs OAuth, e-mail). */
48
66
  async listUserIdentities(userId) {
49
67
  return this.request("GET", `${this.prefix}/users/${userId}/identities`);
50
68
  }
51
69
  // -- Sessions ---------------------------------------------------------------
70
+ /**
71
+ * Liste les sessions actives de tous les utilisateurs, filtrables par `userId`, avec pagination.
72
+ */
52
73
  async listSessions(params) {
53
74
  const query = new URLSearchParams();
54
75
  if (params?.userId !== void 0) query.set("user_id", params.userId);
@@ -57,10 +78,14 @@ var AuthAdminService = class extends core.BaseService {
57
78
  const qs = query.toString();
58
79
  return this.request("GET", `${this.prefix}/sessions${qs ? "?" + qs : ""}`);
59
80
  }
81
+ /** Révoque une session par son identifiant. */
60
82
  async revokeSession(sessionId) {
61
83
  return this.request("DELETE", `${this.prefix}/sessions/${sessionId}`);
62
84
  }
63
85
  // -- Audit log ------------------------------------------------------------
86
+ /**
87
+ * Lit le journal d'audit (action, adresse IP, agent utilisateur, date), filtrable par `userId`, avec pagination.
88
+ */
64
89
  async getAuditLog(params) {
65
90
  const query = new URLSearchParams();
66
91
  if (params?.userId !== void 0) query.set("user_id", params.userId);
@@ -70,6 +95,9 @@ var AuthAdminService = class extends core.BaseService {
70
95
  return this.request("GET", `${this.prefix}/audit-log${qs ? "?" + qs : ""}`);
71
96
  }
72
97
  // -- Settings -------------------------------------------------------------
98
+ /**
99
+ * Lit les réglages d'authentification du projet. Les secrets (mot de passe SMTP, clés) ne sont jamais renvoyés.
100
+ */
73
101
  async getSettings() {
74
102
  return this.request("GET", `${this.prefix}/settings`);
75
103
  }
@@ -92,18 +120,23 @@ var AuthAdminService = class extends core.BaseService {
92
120
  return this.request("PUT", `${this.prefix}/settings`, data);
93
121
  }
94
122
  // -- Email templates ------------------------------------------------------
123
+ /** Liste les modèles d'e-mail d'authentification du projet. */
95
124
  async listEmailTemplates() {
96
125
  return this.request("GET", `${this.prefix}/email-templates`);
97
126
  }
127
+ /** Lit le modèle d'e-mail d'un type donné (par exemple confirmation, récupération). */
98
128
  async getEmailTemplate(type) {
99
129
  return this.request("GET", `${this.prefix}/email-templates/${type}`);
100
130
  }
131
+ /** Remplace le contenu du modèle d'e-mail d'un type donné. */
101
132
  async updateEmailTemplate(type, data) {
102
133
  return this.request("PUT", `${this.prefix}/email-templates/${type}`, data);
103
134
  }
135
+ /** Supprime le modèle personnalisé d'un type d'e-mail. */
104
136
  async deleteEmailTemplate(type) {
105
137
  return this.request("DELETE", `${this.prefix}/email-templates/${type}`);
106
138
  }
139
+ /** Envoie un e-mail de test avec le modèle d'un type à l'adresse `to_email`. */
107
140
  async testEmailTemplate(type, body) {
108
141
  return this.request("POST", `${this.prefix}/email-templates/${type}/test`, body);
109
142
  }
@@ -632,6 +665,10 @@ var AuthService = class extends core.BaseService {
632
665
  return `aura-${core.clientScope(this.client.baseUrl)}-oauth-implicit-initiated`;
633
666
  }
634
667
  // -- Auth state change ------------------------------------------------------
668
+ /**
669
+ * Écoute les changements d'état de la session (`SIGNED_IN`, `SIGNED_OUT`, `TOKEN_REFRESHED`, `USER_UPDATED`,
670
+ * `MFA_CHALLENGE`…). Renvoie de quoi se désabonner : `unsubscribe()` ou `data.subscription.unsubscribe()`.
671
+ */
635
672
  onAuthStateChange(callback) {
636
673
  const unsub = () => {
637
674
  this._stateListeners.delete(callback);
@@ -681,8 +718,24 @@ var AuthService = class extends core.BaseService {
681
718
  }
682
719
  }
683
720
  // -- Sign up / sign in / sign out -------------------------------------------
721
+ /**
722
+ * Crée un compte avec e-mail et mot de passe. Si le projet n'exige pas de confirmation et que le MFA n'est pas actif,
723
+ * la session est enregistrée et `SIGNED_IN` est émis ; sinon la réponse est un défi MFA (voir `isMfaChallenge`).
724
+ */
684
725
  async signUp(req) {
685
- const res = await this.request("POST", `${this.prefix}/register`, req);
726
+ const payload = {
727
+ email: req.email,
728
+ password: req.password
729
+ };
730
+ if (req.captcha_token) payload.captcha_token = req.captcha_token;
731
+ if (req.name) {
732
+ payload.name = req.name;
733
+ } else if (req.options?.data && typeof req.options.data.name === "string") {
734
+ payload.name = req.options.data.name;
735
+ }
736
+ if (req.options?.data) payload.data = req.options.data;
737
+ if (req.options?.emailRedirectTo) payload.email_redirect_to = req.options.emailRedirectTo;
738
+ const res = await this.request("POST", `${this.prefix}/register`, payload);
686
739
  if (res.data && !isMfaChallenge(res.data)) {
687
740
  const tp = res.data;
688
741
  tp.accessToken = tp.access_token;
@@ -715,8 +768,18 @@ var AuthService = class extends core.BaseService {
715
768
  }
716
769
  return res;
717
770
  }
771
+ /**
772
+ * Connecte un utilisateur par e-mail et mot de passe. Enregistre la session et émet `SIGNED_IN` ;
773
+ * si le MFA est actif, renvoie un défi (`isMfaChallenge`) à compléter par `mfaVerify`.
774
+ */
718
775
  async signInWithPassword(req) {
719
- const res = await this.request("POST", `${this.prefix}/login`, req);
776
+ const payload = {
777
+ email: req.email,
778
+ password: req.password
779
+ };
780
+ if (req.captcha_token) payload.captcha_token = req.captcha_token;
781
+ if (req.mfa) payload.mfa = req.mfa;
782
+ const res = await this.request("POST", `${this.prefix}/login`, payload);
720
783
  if (res.data && !isMfaChallenge(res.data)) {
721
784
  const tp = res.data;
722
785
  tp.accessToken = tp.access_token;
@@ -749,37 +812,32 @@ var AuthService = class extends core.BaseService {
749
812
  }
750
813
  return res;
751
814
  }
752
- /**
753
- * Démarre un flux OAuth : renvoie toujours `{ url }` (et redirige en plus le navigateur
754
- * si un `window` existe).
755
- *
756
- * ### `options.queryParams` — contrat (N22)
757
- *
758
- * Les clés listées par {@link OAUTH_FORWARDABLE_QUERY_PARAMS} — `prompt`, `login_hint`,
759
- * `display`, `ui_locales`, `max_age`, `acr_values`, `claims_locales`, `access_type`,
760
- * `include_granted_scopes`, `hd` — sont **réellement transmises au provider**, jusque
761
- * dans l'URL d'autorisation.
762
- *
763
- * Toute autre clé est **refusée** : la méthode renvoie
764
- * `error.code === 'invalid_oauth_query_param'` et n'amorce aucune redirection. Rien
765
- * n'est jamais accepté puis jeté en silence. Sont notamment refusés :
766
- * - les paramètres du protocole (`state`, `nonce`, `client_id`, `response_type`,
767
- * `scope`, `code_challenge`…) — ils sont calculés par le serveur ;
768
- * - les paramètres construits par cette méthode (`redirect_uri`, `scopes`) — passez par
769
- * `redirectTo`, `scopes` ou `flowType` ;
770
- * - `project_id` : le projet est porté par l'URL du client, jamais par un paramètre ;
771
- * - les variantes de casse (`Prompt`, `State`) et les clés inconnues.
772
- *
773
- * L'autorité est le **backend** (`OAUTH_FORWARDABLE_PARAMS` de
774
- * `services/aura-auth/src/handlers/oauth.rs`), qui répond `400` sur les mêmes règles :
775
- * l'endpoint de démarrage est public et appelable sans SDK. Ce filtre-ci n'est que son
776
- * miroir, pour échouer avant la redirection ; un test de parité interdit qu'ils divergent.
777
- *
778
- * Les **valeurs**, elles, ne sont validées que par le backend (non vide, sans caractère
779
- * de contrôle, 512 caractères au plus, jamais deux fois la même clé) — un manquement
780
- * donne un `400` au démarrage du flux, pas une erreur de cette méthode.
781
- */
782
- async signInWithOAuth(provider, options) {
815
+ async signInWithOAuth(providerOrOptions, rawOptions) {
816
+ let provider;
817
+ let options;
818
+ if (typeof providerOrOptions === "object" && providerOrOptions !== null) {
819
+ provider = providerOrOptions.provider;
820
+ const nestedOptions = providerOrOptions.options;
821
+ options = {
822
+ ...providerOrOptions,
823
+ ...nestedOptions,
824
+ ...rawOptions
825
+ };
826
+ } else {
827
+ provider = providerOrOptions;
828
+ options = rawOptions;
829
+ }
830
+ if (typeof provider !== "string" || provider.trim() === "") {
831
+ return {
832
+ data: null,
833
+ error: new core.AuraError(0, {
834
+ error: {
835
+ code: "invalid_provider",
836
+ message: "signInWithOAuth: le fournisseur doit \xEAtre une cha\xEEne non vide, par exemple signInWithOAuth('google', { redirectTo }) ou signInWithOAuth({ provider: 'google', redirectTo })"
837
+ }
838
+ })
839
+ };
840
+ }
783
841
  const params = new URLSearchParams();
784
842
  if (options?.redirectTo) params.set("redirect_uri", options.redirectTo);
785
843
  if (options?.scopes) params.set("scopes", options.scopes);
@@ -841,9 +899,15 @@ var AuthService = class extends core.BaseService {
841
899
  }
842
900
  return { data: { url }, error: null };
843
901
  }
902
+ /**
903
+ * Envoie un lien de connexion par e-mail (« magic link »). La session s'obtient ensuite par `verifyOtp({ type: 'magiclink' })`.
904
+ */
844
905
  async signInWithMagicLink(req) {
845
906
  return this.request("POST", `${this.prefix}/magic-link`, req);
846
907
  }
908
+ /**
909
+ * Crée une session anonyme (utilisateur sans e-mail), enregistrée et signalée par `SIGNED_IN`.
910
+ */
847
911
  async signInAnonymously() {
848
912
  const res = await this.request("POST", `${this.prefix}/anonymous`);
849
913
  if (res.data) {
@@ -852,6 +916,9 @@ var AuthService = class extends core.BaseService {
852
916
  }
853
917
  return res;
854
918
  }
919
+ /**
920
+ * Déconnecte : révoque le jeton de rafraîchissement côté serveur s'il existe, vide la session locale et émet `SIGNED_OUT`.
921
+ */
855
922
  async signOut() {
856
923
  const refreshToken = this.client.authStore.refreshToken;
857
924
  if (!refreshToken) {
@@ -872,6 +939,10 @@ var AuthService = class extends core.BaseService {
872
939
  return res;
873
940
  }
874
941
  // -- Session management -----------------------------------------------------
942
+ /**
943
+ * Rafraîchit la session avec le jeton de rafraîchissement et émet `TOKEN_REFRESHED`.
944
+ * Les rafraîchissements concurrents sont fusionnés en un seul appel.
945
+ */
875
946
  async refreshSession() {
876
947
  const res = await core.refreshOnce(this.client);
877
948
  if (res.data) {
@@ -906,6 +977,10 @@ var AuthService = class extends core.BaseService {
906
977
  user
907
978
  });
908
979
  }
980
+ /**
981
+ * Installe une session à partir d'un jeton d'accès et d'un jeton de rafraîchissement existants (par exemple reçus d'un serveur).
982
+ * Un jeton d'accès expiré est rafraîchi ; une session invalide est refusée et l'état précédent est restauré.
983
+ */
909
984
  async setSession(accessToken, refreshToken) {
910
985
  const store = this.client.authStore;
911
986
  const prev = { token: store.token, refreshToken: store.refreshToken, user: store.user };
@@ -992,6 +1067,9 @@ var AuthService = class extends core.BaseService {
992
1067
  this.client.authStore.removeItem(verifierKey);
993
1068
  }
994
1069
  }
1070
+ /**
1071
+ * Liste les sessions de l'utilisateur connecté (appareil, adresse IP, dates) ; `is_current` repère la session courante.
1072
+ */
995
1073
  async listSessions() {
996
1074
  const store = this.client.authStore;
997
1075
  if (store.token && store.refreshToken && !store.isValid) {
@@ -1005,9 +1083,13 @@ var AuthService = class extends core.BaseService {
1005
1083
  headers: refreshToken ? { "x-refresh-token": refreshToken } : void 0
1006
1084
  });
1007
1085
  }
1086
+ /** Révoque une session de l'utilisateur connecté par son identifiant. */
1008
1087
  async revokeSession(sessionId) {
1009
1088
  return this.request("DELETE", `${this.prefix}/sessions/${sessionId}`);
1010
1089
  }
1090
+ /**
1091
+ * Déconnecte l'utilisateur partout : révoque toutes ses sessions, vide la session locale et émet `SIGNED_OUT`.
1092
+ */
1011
1093
  async revokeAllSessions() {
1012
1094
  const rt = this.client.authStore.refreshToken;
1013
1095
  if (!rt) {
@@ -1188,6 +1270,9 @@ var AuthService = class extends core.BaseService {
1188
1270
  error: new core.AuraError(0, { error: { code: r.code, message: `getClaims: ${r.code}` } })
1189
1271
  };
1190
1272
  }
1273
+ /**
1274
+ * Supprime le compte de l'utilisateur connecté après confirmation par son mot de passe, puis vide la session locale.
1275
+ */
1191
1276
  async deleteUser(password) {
1192
1277
  const res = await this.request("DELETE", `${this.prefix}/user`, { password });
1193
1278
  if (!res.error) {
@@ -1196,6 +1281,9 @@ var AuthService = class extends core.BaseService {
1196
1281
  }
1197
1282
  return res;
1198
1283
  }
1284
+ /**
1285
+ * Met à jour l'utilisateur connecté (métadonnées, mot de passe…) et émet `USER_UPDATED`. Un changement d'e-mail ne prend effet qu'après confirmation par `verifyOtp({ type: 'email_change' })`.
1286
+ */
1199
1287
  async updateUser(req) {
1200
1288
  const res = await this.request("PUT", `${this.prefix}/user`, req);
1201
1289
  if (res.data) {
@@ -1208,9 +1296,13 @@ var AuthService = class extends core.BaseService {
1208
1296
  return res;
1209
1297
  }
1210
1298
  // -- Password recovery ------------------------------------------------------
1299
+ /** Envoie un e-mail de réinitialisation du mot de passe. */
1211
1300
  async resetPasswordForEmail(req) {
1212
1301
  return this.request("POST", `${this.prefix}/forgot-password`, req);
1213
1302
  }
1303
+ /**
1304
+ * Change le mot de passe de l'utilisateur connecté. Le serveur révoque toutes ses sessions : le SDK vide la session locale et émet `SIGNED_OUT`.
1305
+ */
1214
1306
  async updatePassword(newPassword, currentPassword) {
1215
1307
  const res = await this.request("PUT", `${this.prefix}/user`, {
1216
1308
  password: newPassword,
@@ -1223,12 +1315,39 @@ var AuthService = class extends core.BaseService {
1223
1315
  return res;
1224
1316
  }
1225
1317
  // -- MFA --------------------------------------------------------------------
1318
+ /**
1319
+ * Façade unifiée pour les opérations MFA (TOTP).
1320
+ * Permet d'appeler indifféremment `aura.auth.mfa.enroll()` ou `aura.auth.mfaEnroll()`.
1321
+ */
1322
+ get mfa() {
1323
+ return {
1324
+ enroll: () => this.mfaEnroll(),
1325
+ verifySetup: (codeOrParams) => {
1326
+ const code = typeof codeOrParams === "string" ? codeOrParams : codeOrParams.code;
1327
+ return this.mfaVerifySetup(code);
1328
+ },
1329
+ verify: (req) => this.mfaVerify(req),
1330
+ unenroll: (passwordOrParams) => {
1331
+ const password = typeof passwordOrParams === "string" ? passwordOrParams : passwordOrParams.password;
1332
+ return this.mfaUnenroll(password);
1333
+ },
1334
+ regenerateRecoveryCodes: (codeOrParams) => {
1335
+ const code = typeof codeOrParams === "string" ? codeOrParams : codeOrParams.code;
1336
+ return this.regenerateRecoveryCodes(code);
1337
+ }
1338
+ };
1339
+ }
1340
+ /** MFA : démarre l'enrôlement TOTP et renvoie le `secret` et l'URL `otpauth_url` à afficher en QR code. */
1226
1341
  async mfaEnroll() {
1227
1342
  return this.request("POST", `${this.prefix}/mfa/setup`);
1228
1343
  }
1344
+ /** MFA : confirme l'enrôlement avec un premier code et renvoie les codes de récupération. */
1229
1345
  async mfaVerifySetup(code) {
1230
1346
  return this.request("POST", `${this.prefix}/mfa/setup/verify`, { code });
1231
1347
  }
1348
+ /**
1349
+ * MFA : termine une connexion qui a renvoyé un défi (`mfa_token` et code TOTP). Enregistre la session et émet `SIGNED_IN`.
1350
+ */
1232
1351
  async mfaVerify(req) {
1233
1352
  const res = await this.request("POST", `${this.prefix}/mfa/verify-login`, req);
1234
1353
  if (res.data) {
@@ -1237,6 +1356,7 @@ var AuthService = class extends core.BaseService {
1237
1356
  }
1238
1357
  return res;
1239
1358
  }
1359
+ /** MFA : désactive le MFA après confirmation par le mot de passe. */
1240
1360
  async mfaUnenroll(password) {
1241
1361
  return this.request("POST", `${this.prefix}/mfa/disable`, { password });
1242
1362
  }
@@ -1308,6 +1428,7 @@ var AuthService = class extends core.BaseService {
1308
1428
  return res;
1309
1429
  }
1310
1430
  // -- Email verification -----------------------------------------------------
1431
+ /** Renvoie l'e-mail de vérification, à `email` ou à l'adresse de l'utilisateur connecté. */
1311
1432
  async resendVerificationEmail(email) {
1312
1433
  const e = email ?? this.client.authStore.user?.email;
1313
1434
  if (!e) {
@@ -1319,24 +1440,34 @@ var AuthService = class extends core.BaseService {
1319
1440
  return this.request("POST", `${this.prefix}/resend-verification`, { email: e });
1320
1441
  }
1321
1442
  // -- Email OTP (Phase 2) --------------------------------------------------
1443
+ /**
1444
+ * Envoie un code à usage unique par e-mail ; à confirmer par `verifyOtp({ type: 'email' })`.
1445
+ */
1322
1446
  async signInWithEmailOtp(email) {
1323
1447
  return this.request("POST", `${this.prefix}/email-otp/send`, { email });
1324
1448
  }
1325
1449
  // -- SMS OTP (Phase 2) ----------------------------------------------------
1450
+ /** Envoie un code à usage unique par SMS ; à confirmer par `verifyOtp({ type: 'sms' })`. */
1326
1451
  async signInWithSmsOtp(phone) {
1327
1452
  return this.request("POST", `${this.prefix}/sms/send`, { phone });
1328
1453
  }
1329
1454
  // -- Identity linking (Phase 2) -------------------------------------------
1455
+ /** Liste les identités (fournisseurs) liées à l'utilisateur connecté. */
1330
1456
  async listIdentities() {
1331
1457
  return this.request("GET", `${this.prefix}/user/identities`);
1332
1458
  }
1459
+ /**
1460
+ * Démarre la liaison d'un fournisseur OAuth au compte connecté et renvoie l'URL d'autorisation à ouvrir.
1461
+ */
1333
1462
  async linkIdentity(provider) {
1334
1463
  return this.request("POST", `${this.prefix}/user/identities/link/${provider}`);
1335
1464
  }
1465
+ /** Détache une identité du compte connecté par son identifiant. */
1336
1466
  async unlinkIdentity(identityId) {
1337
1467
  return this.request("DELETE", `${this.prefix}/user/identities/${identityId}`);
1338
1468
  }
1339
1469
  // -- MFA recovery codes (Phase 2) -----------------------------------------
1470
+ /** MFA : régénère les codes de récupération après confirmation par un code TOTP. */
1340
1471
  async regenerateRecoveryCodes(code) {
1341
1472
  return this.request("POST", `${this.prefix}/mfa/recovery-codes/regenerate`, { code });
1342
1473
  }