@stackframe/react 2.8.2 → 2.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/components/api-key-dialogs.js +184 -0
  3. package/dist/components/api-key-dialogs.js.map +1 -0
  4. package/dist/components/api-key-table.js +149 -0
  5. package/dist/components/api-key-table.js.map +1 -0
  6. package/dist/components-page/account-settings/active-sessions/active-sessions-page.js +151 -0
  7. package/dist/components-page/account-settings/active-sessions/active-sessions-page.js.map +1 -0
  8. package/dist/components-page/account-settings/api-keys/api-keys-page.js +70 -0
  9. package/dist/components-page/account-settings/api-keys/api-keys-page.js.map +1 -0
  10. package/dist/components-page/account-settings/editable-text.js +75 -0
  11. package/dist/components-page/account-settings/editable-text.js.map +1 -0
  12. package/dist/components-page/account-settings/email-and-auth/email-and-auth-page.js +46 -0
  13. package/dist/components-page/account-settings/email-and-auth/email-and-auth-page.js.map +1 -0
  14. package/dist/components-page/account-settings/email-and-auth/emails-section.js +188 -0
  15. package/dist/components-page/account-settings/email-and-auth/emails-section.js.map +1 -0
  16. package/dist/components-page/account-settings/email-and-auth/mfa-section.js +146 -0
  17. package/dist/components-page/account-settings/email-and-auth/mfa-section.js.map +1 -0
  18. package/dist/components-page/account-settings/email-and-auth/otp-section.js +89 -0
  19. package/dist/components-page/account-settings/email-and-auth/otp-section.js.map +1 -0
  20. package/dist/components-page/account-settings/email-and-auth/passkey-section.js +92 -0
  21. package/dist/components-page/account-settings/email-and-auth/passkey-section.js.map +1 -0
  22. package/dist/components-page/account-settings/email-and-auth/password-section.js +181 -0
  23. package/dist/components-page/account-settings/email-and-auth/password-section.js.map +1 -0
  24. package/dist/components-page/account-settings/page-layout.js +34 -0
  25. package/dist/components-page/account-settings/page-layout.js.map +1 -0
  26. package/dist/components-page/account-settings/profile-page/profile-page.js +75 -0
  27. package/dist/components-page/account-settings/profile-page/profile-page.js.map +1 -0
  28. package/dist/components-page/account-settings/section.js +44 -0
  29. package/dist/components-page/account-settings/section.js.map +1 -0
  30. package/dist/components-page/account-settings/settings/delete-account-section.js +87 -0
  31. package/dist/components-page/account-settings/settings/delete-account-section.js.map +1 -0
  32. package/dist/components-page/account-settings/settings/settings-page.js +40 -0
  33. package/dist/components-page/account-settings/settings/settings-page.js.map +1 -0
  34. package/dist/components-page/account-settings/settings/sign-out-section.js +54 -0
  35. package/dist/components-page/account-settings/settings/sign-out-section.js.map +1 -0
  36. package/dist/components-page/account-settings/teams/leave-team-section.js +79 -0
  37. package/dist/components-page/account-settings/teams/leave-team-section.js.map +1 -0
  38. package/dist/components-page/account-settings/teams/team-api-keys-section.js +89 -0
  39. package/dist/components-page/account-settings/teams/team-api-keys-section.js.map +1 -0
  40. package/dist/components-page/account-settings/teams/team-creation-page.js +92 -0
  41. package/dist/components-page/account-settings/teams/team-creation-page.js.map +1 -0
  42. package/dist/components-page/account-settings/teams/team-display-name-section.js +57 -0
  43. package/dist/components-page/account-settings/teams/team-display-name-section.js.map +1 -0
  44. package/dist/components-page/account-settings/teams/team-member-invitation-section.js +131 -0
  45. package/dist/components-page/account-settings/teams/team-member-invitation-section.js.map +1 -0
  46. package/dist/components-page/account-settings/teams/team-member-list-section.js +61 -0
  47. package/dist/components-page/account-settings/teams/team-member-list-section.js.map +1 -0
  48. package/dist/components-page/account-settings/teams/team-page.js +50 -0
  49. package/dist/components-page/account-settings/teams/team-page.js.map +1 -0
  50. package/dist/components-page/account-settings/teams/team-profile-image-section.js +59 -0
  51. package/dist/components-page/account-settings/teams/team-profile-image-section.js.map +1 -0
  52. package/dist/components-page/account-settings/teams/team-profile-user-section.js +56 -0
  53. package/dist/components-page/account-settings/teams/team-profile-user-section.js.map +1 -0
  54. package/dist/components-page/account-settings.js +34 -1072
  55. package/dist/components-page/account-settings.js.map +1 -1
  56. package/dist/components-page/section.js +6 -0
  57. package/dist/components-page/section.js.map +1 -0
  58. package/dist/esm/components/api-key-dialogs.js +157 -0
  59. package/dist/esm/components/api-key-dialogs.js.map +1 -0
  60. package/dist/esm/components/api-key-table.js +125 -0
  61. package/dist/esm/components/api-key-table.js.map +1 -0
  62. package/dist/esm/components-page/account-settings/active-sessions/active-sessions-page.js +126 -0
  63. package/dist/esm/components-page/account-settings/active-sessions/active-sessions-page.js.map +1 -0
  64. package/dist/esm/components-page/account-settings/api-keys/api-keys-page.js +45 -0
  65. package/dist/esm/components-page/account-settings/api-keys/api-keys-page.js.map +1 -0
  66. package/dist/esm/components-page/account-settings/editable-text.js +50 -0
  67. package/dist/esm/components-page/account-settings/editable-text.js.map +1 -0
  68. package/dist/esm/components-page/account-settings/email-and-auth/email-and-auth-page.js +21 -0
  69. package/dist/esm/components-page/account-settings/email-and-auth/email-and-auth-page.js.map +1 -0
  70. package/dist/esm/components-page/account-settings/email-and-auth/emails-section.js +163 -0
  71. package/dist/esm/components-page/account-settings/email-and-auth/emails-section.js.map +1 -0
  72. package/dist/esm/components-page/account-settings/email-and-auth/mfa-section.js +111 -0
  73. package/dist/esm/components-page/account-settings/email-and-auth/mfa-section.js.map +1 -0
  74. package/dist/esm/components-page/account-settings/email-and-auth/otp-section.js +64 -0
  75. package/dist/esm/components-page/account-settings/email-and-auth/otp-section.js.map +1 -0
  76. package/dist/esm/components-page/account-settings/email-and-auth/passkey-section.js +67 -0
  77. package/dist/esm/components-page/account-settings/email-and-auth/passkey-section.js.map +1 -0
  78. package/dist/esm/components-page/account-settings/email-and-auth/password-section.js +146 -0
  79. package/dist/esm/components-page/account-settings/email-and-auth/password-section.js.map +1 -0
  80. package/dist/esm/components-page/account-settings/page-layout.js +9 -0
  81. package/dist/esm/components-page/account-settings/page-layout.js.map +1 -0
  82. package/dist/esm/components-page/account-settings/profile-page/profile-page.js +50 -0
  83. package/dist/esm/components-page/account-settings/profile-page/profile-page.js.map +1 -0
  84. package/dist/esm/components-page/account-settings/section.js +19 -0
  85. package/dist/esm/components-page/account-settings/section.js.map +1 -0
  86. package/dist/esm/components-page/account-settings/settings/delete-account-section.js +62 -0
  87. package/dist/esm/components-page/account-settings/settings/delete-account-section.js.map +1 -0
  88. package/dist/esm/components-page/account-settings/settings/settings-page.js +15 -0
  89. package/dist/esm/components-page/account-settings/settings/settings-page.js.map +1 -0
  90. package/dist/esm/components-page/account-settings/settings/sign-out-section.js +29 -0
  91. package/dist/esm/components-page/account-settings/settings/sign-out-section.js.map +1 -0
  92. package/dist/esm/components-page/account-settings/teams/leave-team-section.js +54 -0
  93. package/dist/esm/components-page/account-settings/teams/leave-team-section.js.map +1 -0
  94. package/dist/esm/components-page/account-settings/teams/team-api-keys-section.js +64 -0
  95. package/dist/esm/components-page/account-settings/teams/team-api-keys-section.js.map +1 -0
  96. package/dist/esm/components-page/account-settings/teams/team-creation-page.js +67 -0
  97. package/dist/esm/components-page/account-settings/teams/team-creation-page.js.map +1 -0
  98. package/dist/esm/components-page/account-settings/teams/team-display-name-section.js +32 -0
  99. package/dist/esm/components-page/account-settings/teams/team-display-name-section.js.map +1 -0
  100. package/dist/esm/components-page/account-settings/teams/team-member-invitation-section.js +106 -0
  101. package/dist/esm/components-page/account-settings/teams/team-member-invitation-section.js.map +1 -0
  102. package/dist/esm/components-page/account-settings/teams/team-member-list-section.js +36 -0
  103. package/dist/esm/components-page/account-settings/teams/team-member-list-section.js.map +1 -0
  104. package/dist/esm/components-page/account-settings/teams/team-page.js +25 -0
  105. package/dist/esm/components-page/account-settings/teams/team-page.js.map +1 -0
  106. package/dist/esm/components-page/account-settings/teams/team-profile-image-section.js +34 -0
  107. package/dist/esm/components-page/account-settings/teams/team-profile-image-section.js.map +1 -0
  108. package/dist/esm/components-page/account-settings/teams/team-profile-user-section.js +31 -0
  109. package/dist/esm/components-page/account-settings/teams/team-profile-user-section.js.map +1 -0
  110. package/dist/esm/components-page/account-settings.js +34 -1061
  111. package/dist/esm/components-page/account-settings.js.map +1 -1
  112. package/dist/esm/components-page/section.js +4 -0
  113. package/dist/esm/components-page/section.js.map +1 -0
  114. package/dist/esm/lib/stack-app/api-keys/index.js +14 -6
  115. package/dist/esm/lib/stack-app/api-keys/index.js.map +1 -1
  116. package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js +26 -23
  117. package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
  118. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js +169 -0
  119. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
  120. package/dist/esm/lib/stack-app/apps/implementations/common.js +1 -1
  121. package/dist/esm/lib/stack-app/apps/implementations/common.js.map +1 -1
  122. package/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js +148 -8
  123. package/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js.map +1 -1
  124. package/dist/esm/lib/stack-app/apps/interfaces/admin-app.js.map +1 -1
  125. package/dist/esm/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
  126. package/dist/esm/lib/stack-app/apps/interfaces/server-app.js.map +1 -1
  127. package/dist/esm/lib/stack-app/index.js.map +1 -1
  128. package/dist/esm/lib/stack-app/internal-api-keys/index.js +14 -0
  129. package/dist/esm/lib/stack-app/internal-api-keys/index.js.map +1 -0
  130. package/dist/esm/lib/stack-app/projects/index.js +3 -1
  131. package/dist/esm/lib/stack-app/projects/index.js.map +1 -1
  132. package/dist/esm/lib/stack-app/teams/index.js.map +1 -1
  133. package/dist/esm/lib/stack-app/users/index.js.map +1 -1
  134. package/dist/index.d.mts +103 -35
  135. package/dist/index.d.ts +103 -35
  136. package/dist/lib/stack-app/api-keys/index.js +16 -7
  137. package/dist/lib/stack-app/api-keys/index.js.map +1 -1
  138. package/dist/lib/stack-app/apps/implementations/admin-app-impl.js +25 -22
  139. package/dist/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
  140. package/dist/lib/stack-app/apps/implementations/client-app-impl.js +169 -0
  141. package/dist/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
  142. package/dist/lib/stack-app/apps/implementations/common.js +1 -1
  143. package/dist/lib/stack-app/apps/implementations/common.js.map +1 -1
  144. package/dist/lib/stack-app/apps/implementations/server-app-impl.js +148 -8
  145. package/dist/lib/stack-app/apps/implementations/server-app-impl.js.map +1 -1
  146. package/dist/lib/stack-app/apps/interfaces/admin-app.js.map +1 -1
  147. package/dist/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
  148. package/dist/lib/stack-app/apps/interfaces/server-app.js.map +1 -1
  149. package/dist/lib/stack-app/index.js.map +1 -1
  150. package/dist/lib/stack-app/internal-api-keys/index.js +39 -0
  151. package/dist/lib/stack-app/internal-api-keys/index.js.map +1 -0
  152. package/dist/lib/stack-app/project-configs/index.js.map +1 -1
  153. package/dist/lib/stack-app/projects/index.js +3 -1
  154. package/dist/lib/stack-app/projects/index.js.map +1 -1
  155. package/dist/lib/stack-app/teams/index.js.map +1 -1
  156. package/dist/lib/stack-app/users/index.js.map +1 -1
  157. package/package.json +4 -3
@@ -17,6 +17,7 @@ import * as cookie from "cookie";
17
17
  import { constructRedirectUrl } from "../../../../utils/url";
18
18
  import { addNewOAuthProviderOrScope, callOAuthCallback, signInWithOAuth } from "../../../auth";
19
19
  import { createBrowserCookieHelper, createCookieHelper, createPlaceholderCookieHelper, deleteCookieClient, getCookieClient, setOrDeleteCookie, setOrDeleteCookieClient } from "../../../cookie";
20
+ import { apiKeyCreationOptionsToCrud } from "../../api-keys";
20
21
  import { stackAppInternalsSymbol } from "../../common";
21
22
  import { contactChannelCreateOptionsToCrud, contactChannelUpdateOptionsToCrud } from "../../contact-channels";
22
23
  import { adminProjectCreateOptionsToCrud } from "../../projects";
@@ -104,6 +105,18 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
104
105
  return await this._interface.listClientContactChannels(session);
105
106
  }
106
107
  );
108
+ this._userApiKeysCache = createCacheBySession(
109
+ async (session) => {
110
+ const results = await this._interface.listProjectApiKeys({ user_id: "me" }, session, "client");
111
+ return results;
112
+ }
113
+ );
114
+ this._teamApiKeysCache = createCacheBySession(
115
+ async (session, [teamId]) => {
116
+ const results = await this._interface.listProjectApiKeys({ team_id: teamId }, session, "client");
117
+ return results;
118
+ }
119
+ );
107
120
  this._anonymousSignUpInProgress = null;
108
121
  this._memoryTokenStore = createEmptyTokenStore();
109
122
  this._nextServerCookiesTokenStores = /* @__PURE__ */ new WeakMap();
@@ -438,6 +451,8 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
438
451
  passkeyEnabled: crud.config.passkey_enabled,
439
452
  clientTeamCreationEnabled: crud.config.client_team_creation_enabled,
440
453
  clientUserDeletionEnabled: crud.config.client_user_deletion_enabled,
454
+ allowTeamApiKeys: crud.config.allow_team_api_keys,
455
+ allowUserApiKeys: crud.config.allow_user_api_keys,
441
456
  oauthProviders: crud.config.enabled_oauth_providers.map((p) => ({
442
457
  id: p.id
443
458
  }))
@@ -469,6 +484,47 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
469
484
  }
470
485
  };
471
486
  }
487
+ _baseApiKeyFromCrud(crud) {
488
+ return {
489
+ id: crud.id,
490
+ description: crud.description,
491
+ expiresAt: crud.expires_at_millis ? new Date(crud.expires_at_millis) : void 0,
492
+ manuallyRevokedAt: crud.manually_revoked_at_millis ? new Date(crud.manually_revoked_at_millis) : null,
493
+ createdAt: new Date(crud.created_at_millis),
494
+ ...crud.type === "team" ? { type: "team", teamId: crud.team_id } : { type: "user", userId: crud.user_id },
495
+ value: typeof crud.value === "string" ? crud.value : {
496
+ lastFour: crud.value.last_four
497
+ },
498
+ isValid: function() {
499
+ return this.whyInvalid() === null;
500
+ },
501
+ whyInvalid: function() {
502
+ if (this.manuallyRevokedAt) {
503
+ return "manually-revoked";
504
+ }
505
+ if (this.expiresAt && this.expiresAt < /* @__PURE__ */ new Date()) {
506
+ return "expired";
507
+ }
508
+ return null;
509
+ }
510
+ };
511
+ }
512
+ _clientApiKeyFromCrud(session, crud) {
513
+ return {
514
+ ...this._baseApiKeyFromCrud(crud),
515
+ async revoke() {
516
+ await this.update({ revoked: true });
517
+ },
518
+ update: async (options) => {
519
+ await this._interface.updateProjectApiKey(crud.type === "team" ? { team_id: crud.team_id } : { user_id: crud.user_id }, crud.id, options, session, "client");
520
+ if (crud.type === "team") {
521
+ await this._teamApiKeysCache.refresh([session, crud.team_id]);
522
+ } else {
523
+ await this._userApiKeysCache.refresh([session]);
524
+ }
525
+ }
526
+ };
527
+ }
472
528
  _clientTeamFromCrud(crud, session) {
473
529
  const app = this;
474
530
  return {
@@ -509,6 +565,23 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
509
565
  async delete() {
510
566
  await app._interface.deleteTeam(crud.id, session);
511
567
  await app._currentUserTeamsCache.refresh([session]);
568
+ },
569
+ useApiKeys() {
570
+ const result = useAsyncCache(app._teamApiKeysCache, [session, crud.id], "team.useApiKeys()");
571
+ return result.map((crud2) => app._clientApiKeyFromCrud(session, crud2));
572
+ },
573
+ async listApiKeys() {
574
+ const results = Result.orThrow(await app._teamApiKeysCache.getOrWait([session, crud.id], "write-only"));
575
+ return results.map((crud2) => app._clientApiKeyFromCrud(session, crud2));
576
+ },
577
+ async createApiKey(options) {
578
+ const result = await app._interface.createProjectApiKey(
579
+ await apiKeyCreationOptionsToCrud("team", crud.id, options),
580
+ session,
581
+ "client"
582
+ );
583
+ await app._teamApiKeysCache.refresh([session, crud.id]);
584
+ return app._clientApiKeyFromCrud(session, result);
512
585
  }
513
586
  };
514
587
  }
@@ -796,6 +869,23 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
796
869
  const crud2 = await app._interface.createClientContactChannel(contactChannelCreateOptionsToCrud("me", data), session);
797
870
  await app._clientContactChannelsCache.refresh([session]);
798
871
  return app._clientContactChannelFromCrud(crud2, session);
872
+ },
873
+ useApiKeys() {
874
+ const result = useAsyncCache(app._userApiKeysCache, [session], "user.useApiKeys()");
875
+ return result.map((crud2) => app._clientApiKeyFromCrud(session, crud2));
876
+ },
877
+ async listApiKeys() {
878
+ const results = await app._interface.listProjectApiKeys({ user_id: "me" }, session, "client");
879
+ return results.map((crud2) => app._clientApiKeyFromCrud(session, crud2));
880
+ },
881
+ async createApiKey(options) {
882
+ const result = await app._interface.createProjectApiKey(
883
+ await apiKeyCreationOptionsToCrud("user", "me", options),
884
+ session,
885
+ "client"
886
+ );
887
+ await app._userApiKeysCache.refresh([session]);
888
+ return app._clientApiKeyFromCrud(session, result);
799
889
  }
800
890
  };
801
891
  }
@@ -1226,6 +1316,85 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
1226
1316
  return Result.error(result.error);
1227
1317
  }
1228
1318
  }
1319
+ /**
1320
+ * Initiates a CLI authentication process that allows a command line application
1321
+ * to get a refresh token for a user's account.
1322
+ *
1323
+ * This process works as follows:
1324
+ * 1. The CLI app calls this method, which initiates the auth process with the server
1325
+ * 2. The server returns a polling code and a login code
1326
+ * 3. The CLI app opens a browser window to the appUrl with the login code as a parameter
1327
+ * 4. The user logs in through the browser and confirms the authorization
1328
+ * 5. The CLI app polls for the refresh token using the polling code
1329
+ *
1330
+ * @param options Options for the CLI login
1331
+ * @param options.appUrl The URL of the app that will handle the CLI auth confirmation
1332
+ * @param options.expiresInMillis Optional duration in milliseconds before the auth attempt expires (default: 2 hours)
1333
+ * @param options.maxAttempts Optional maximum number of polling attempts (default: Infinity)
1334
+ * @param options.waitTimeMillis Optional time to wait between polling attempts (default: 2 seconds)
1335
+ * @param options.promptLink Optional function to call with the login URL to prompt the user to open the browser
1336
+ * @returns Result containing either the refresh token or an error
1337
+ */
1338
+ async promptCliLogin(options) {
1339
+ const response = await this._interface.sendClientRequest(
1340
+ "/auth/cli",
1341
+ {
1342
+ method: "POST",
1343
+ headers: {
1344
+ "Content-Type": "application/json"
1345
+ },
1346
+ body: JSON.stringify({
1347
+ expires_in_millis: options.expiresInMillis
1348
+ })
1349
+ },
1350
+ null
1351
+ );
1352
+ if (!response.ok) {
1353
+ return Result.error(new KnownErrors.CliAuthError(`Failed to initiate CLI auth: ${response.status} ${await response.text()}`));
1354
+ }
1355
+ const initResult = await response.json();
1356
+ const pollingCode = initResult.polling_code;
1357
+ const loginCode = initResult.login_code;
1358
+ const url = `${options.appUrl}/handler/cli-auth-confirm?login_code=${encodeURIComponent(loginCode)}`;
1359
+ if (options.promptLink) {
1360
+ options.promptLink(url);
1361
+ } else {
1362
+ console.log(`Please visit the following URL to authenticate:
1363
+ ${url}`);
1364
+ }
1365
+ let attempts = 0;
1366
+ while (attempts < (options.maxAttempts ?? Infinity)) {
1367
+ attempts++;
1368
+ const pollResponse = await this._interface.sendClientRequest("/auth/cli/poll", {
1369
+ method: "POST",
1370
+ headers: {
1371
+ "Content-Type": "application/json"
1372
+ },
1373
+ body: JSON.stringify({
1374
+ polling_code: pollingCode
1375
+ })
1376
+ }, null);
1377
+ if (!pollResponse.ok) {
1378
+ return Result.error(new KnownErrors.CliAuthError(`Failed to initiate CLI auth: ${pollResponse.status} ${await pollResponse.text()}`));
1379
+ }
1380
+ const pollResult = await pollResponse.json();
1381
+ if (pollResponse.status === 201 && pollResult.status === "success") {
1382
+ return Result.ok(pollResult.refresh_token);
1383
+ }
1384
+ if (pollResult.status === "waiting") {
1385
+ await wait(options.waitTimeMillis ?? 2e3);
1386
+ continue;
1387
+ }
1388
+ if (pollResult.status === "expired") {
1389
+ return Result.error(new KnownErrors.CliAuthExpiredError("CLI authentication request expired. Please try again."));
1390
+ }
1391
+ if (pollResult.status === "used") {
1392
+ return Result.error(new KnownErrors.CliAuthUsedError("This authentication token has already been used."));
1393
+ }
1394
+ return Result.error(new KnownErrors.CliAuthError(`Unexpected status from CLI auth polling: ${pollResult.status}`));
1395
+ }
1396
+ return Result.error(new KnownErrors.CliAuthError("Timed out waiting for CLI authentication."));
1397
+ }
1229
1398
  async signInWithPasskey() {
1230
1399
  this._ensurePersistentTokenStore();
1231
1400
  const session = await this._getSession();