@stackframe/stack 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 +5 -4
@@ -18,6 +18,7 @@ import * as cookie from "cookie";
18
18
  import { constructRedirectUrl } from "../../../../utils/url";
19
19
  import { addNewOAuthProviderOrScope, callOAuthCallback, signInWithOAuth } from "../../../auth";
20
20
  import { createBrowserCookieHelper, createCookieHelper, createPlaceholderCookieHelper, deleteCookieClient, getCookieClient, setOrDeleteCookie, setOrDeleteCookieClient } from "../../../cookie";
21
+ import { apiKeyCreationOptionsToCrud } from "../../api-keys";
21
22
  import { stackAppInternalsSymbol } from "../../common";
22
23
  import { contactChannelCreateOptionsToCrud, contactChannelUpdateOptionsToCrud } from "../../contact-channels";
23
24
  import { adminProjectCreateOptionsToCrud } from "../../projects";
@@ -109,6 +110,18 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
109
110
  return await this._interface.listClientContactChannels(session);
110
111
  }
111
112
  );
113
+ this._userApiKeysCache = createCacheBySession(
114
+ async (session) => {
115
+ const results = await this._interface.listProjectApiKeys({ user_id: "me" }, session, "client");
116
+ return results;
117
+ }
118
+ );
119
+ this._teamApiKeysCache = createCacheBySession(
120
+ async (session, [teamId]) => {
121
+ const results = await this._interface.listProjectApiKeys({ team_id: teamId }, session, "client");
122
+ return results;
123
+ }
124
+ );
112
125
  this._anonymousSignUpInProgress = null;
113
126
  this._memoryTokenStore = createEmptyTokenStore();
114
127
  this._nextServerCookiesTokenStores = /* @__PURE__ */ new WeakMap();
@@ -445,6 +458,8 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
445
458
  passkeyEnabled: crud.config.passkey_enabled,
446
459
  clientTeamCreationEnabled: crud.config.client_team_creation_enabled,
447
460
  clientUserDeletionEnabled: crud.config.client_user_deletion_enabled,
461
+ allowTeamApiKeys: crud.config.allow_team_api_keys,
462
+ allowUserApiKeys: crud.config.allow_user_api_keys,
448
463
  oauthProviders: crud.config.enabled_oauth_providers.map((p) => ({
449
464
  id: p.id
450
465
  }))
@@ -476,6 +491,47 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
476
491
  }
477
492
  };
478
493
  }
494
+ _baseApiKeyFromCrud(crud) {
495
+ return {
496
+ id: crud.id,
497
+ description: crud.description,
498
+ expiresAt: crud.expires_at_millis ? new Date(crud.expires_at_millis) : void 0,
499
+ manuallyRevokedAt: crud.manually_revoked_at_millis ? new Date(crud.manually_revoked_at_millis) : null,
500
+ createdAt: new Date(crud.created_at_millis),
501
+ ...crud.type === "team" ? { type: "team", teamId: crud.team_id } : { type: "user", userId: crud.user_id },
502
+ value: typeof crud.value === "string" ? crud.value : {
503
+ lastFour: crud.value.last_four
504
+ },
505
+ isValid: function() {
506
+ return this.whyInvalid() === null;
507
+ },
508
+ whyInvalid: function() {
509
+ if (this.manuallyRevokedAt) {
510
+ return "manually-revoked";
511
+ }
512
+ if (this.expiresAt && this.expiresAt < /* @__PURE__ */ new Date()) {
513
+ return "expired";
514
+ }
515
+ return null;
516
+ }
517
+ };
518
+ }
519
+ _clientApiKeyFromCrud(session, crud) {
520
+ return {
521
+ ...this._baseApiKeyFromCrud(crud),
522
+ async revoke() {
523
+ await this.update({ revoked: true });
524
+ },
525
+ update: async (options) => {
526
+ await this._interface.updateProjectApiKey(crud.type === "team" ? { team_id: crud.team_id } : { user_id: crud.user_id }, crud.id, options, session, "client");
527
+ if (crud.type === "team") {
528
+ await this._teamApiKeysCache.refresh([session, crud.team_id]);
529
+ } else {
530
+ await this._userApiKeysCache.refresh([session]);
531
+ }
532
+ }
533
+ };
534
+ }
479
535
  _clientTeamFromCrud(crud, session) {
480
536
  const app = this;
481
537
  return {
@@ -516,6 +572,23 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
516
572
  async delete() {
517
573
  await app._interface.deleteTeam(crud.id, session);
518
574
  await app._currentUserTeamsCache.refresh([session]);
575
+ },
576
+ useApiKeys() {
577
+ const result = useAsyncCache(app._teamApiKeysCache, [session, crud.id], "team.useApiKeys()");
578
+ return result.map((crud2) => app._clientApiKeyFromCrud(session, crud2));
579
+ },
580
+ async listApiKeys() {
581
+ const results = Result.orThrow(await app._teamApiKeysCache.getOrWait([session, crud.id], "write-only"));
582
+ return results.map((crud2) => app._clientApiKeyFromCrud(session, crud2));
583
+ },
584
+ async createApiKey(options) {
585
+ const result = await app._interface.createProjectApiKey(
586
+ await apiKeyCreationOptionsToCrud("team", crud.id, options),
587
+ session,
588
+ "client"
589
+ );
590
+ await app._teamApiKeysCache.refresh([session, crud.id]);
591
+ return app._clientApiKeyFromCrud(session, result);
519
592
  }
520
593
  };
521
594
  }
@@ -803,6 +876,23 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
803
876
  const crud2 = await app._interface.createClientContactChannel(contactChannelCreateOptionsToCrud("me", data), session);
804
877
  await app._clientContactChannelsCache.refresh([session]);
805
878
  return app._clientContactChannelFromCrud(crud2, session);
879
+ },
880
+ useApiKeys() {
881
+ const result = useAsyncCache(app._userApiKeysCache, [session], "user.useApiKeys()");
882
+ return result.map((crud2) => app._clientApiKeyFromCrud(session, crud2));
883
+ },
884
+ async listApiKeys() {
885
+ const results = await app._interface.listProjectApiKeys({ user_id: "me" }, session, "client");
886
+ return results.map((crud2) => app._clientApiKeyFromCrud(session, crud2));
887
+ },
888
+ async createApiKey(options) {
889
+ const result = await app._interface.createProjectApiKey(
890
+ await apiKeyCreationOptionsToCrud("user", "me", options),
891
+ session,
892
+ "client"
893
+ );
894
+ await app._userApiKeysCache.refresh([session]);
895
+ return app._clientApiKeyFromCrud(session, result);
806
896
  }
807
897
  };
808
898
  }
@@ -1238,6 +1328,85 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
1238
1328
  return Result.error(result.error);
1239
1329
  }
1240
1330
  }
1331
+ /**
1332
+ * Initiates a CLI authentication process that allows a command line application
1333
+ * to get a refresh token for a user's account.
1334
+ *
1335
+ * This process works as follows:
1336
+ * 1. The CLI app calls this method, which initiates the auth process with the server
1337
+ * 2. The server returns a polling code and a login code
1338
+ * 3. The CLI app opens a browser window to the appUrl with the login code as a parameter
1339
+ * 4. The user logs in through the browser and confirms the authorization
1340
+ * 5. The CLI app polls for the refresh token using the polling code
1341
+ *
1342
+ * @param options Options for the CLI login
1343
+ * @param options.appUrl The URL of the app that will handle the CLI auth confirmation
1344
+ * @param options.expiresInMillis Optional duration in milliseconds before the auth attempt expires (default: 2 hours)
1345
+ * @param options.maxAttempts Optional maximum number of polling attempts (default: Infinity)
1346
+ * @param options.waitTimeMillis Optional time to wait between polling attempts (default: 2 seconds)
1347
+ * @param options.promptLink Optional function to call with the login URL to prompt the user to open the browser
1348
+ * @returns Result containing either the refresh token or an error
1349
+ */
1350
+ async promptCliLogin(options) {
1351
+ const response = await this._interface.sendClientRequest(
1352
+ "/auth/cli",
1353
+ {
1354
+ method: "POST",
1355
+ headers: {
1356
+ "Content-Type": "application/json"
1357
+ },
1358
+ body: JSON.stringify({
1359
+ expires_in_millis: options.expiresInMillis
1360
+ })
1361
+ },
1362
+ null
1363
+ );
1364
+ if (!response.ok) {
1365
+ return Result.error(new KnownErrors.CliAuthError(`Failed to initiate CLI auth: ${response.status} ${await response.text()}`));
1366
+ }
1367
+ const initResult = await response.json();
1368
+ const pollingCode = initResult.polling_code;
1369
+ const loginCode = initResult.login_code;
1370
+ const url = `${options.appUrl}/handler/cli-auth-confirm?login_code=${encodeURIComponent(loginCode)}`;
1371
+ if (options.promptLink) {
1372
+ options.promptLink(url);
1373
+ } else {
1374
+ console.log(`Please visit the following URL to authenticate:
1375
+ ${url}`);
1376
+ }
1377
+ let attempts = 0;
1378
+ while (attempts < (options.maxAttempts ?? Infinity)) {
1379
+ attempts++;
1380
+ const pollResponse = await this._interface.sendClientRequest("/auth/cli/poll", {
1381
+ method: "POST",
1382
+ headers: {
1383
+ "Content-Type": "application/json"
1384
+ },
1385
+ body: JSON.stringify({
1386
+ polling_code: pollingCode
1387
+ })
1388
+ }, null);
1389
+ if (!pollResponse.ok) {
1390
+ return Result.error(new KnownErrors.CliAuthError(`Failed to initiate CLI auth: ${pollResponse.status} ${await pollResponse.text()}`));
1391
+ }
1392
+ const pollResult = await pollResponse.json();
1393
+ if (pollResponse.status === 201 && pollResult.status === "success") {
1394
+ return Result.ok(pollResult.refresh_token);
1395
+ }
1396
+ if (pollResult.status === "waiting") {
1397
+ await wait(options.waitTimeMillis ?? 2e3);
1398
+ continue;
1399
+ }
1400
+ if (pollResult.status === "expired") {
1401
+ return Result.error(new KnownErrors.CliAuthExpiredError("CLI authentication request expired. Please try again."));
1402
+ }
1403
+ if (pollResult.status === "used") {
1404
+ return Result.error(new KnownErrors.CliAuthUsedError("This authentication token has already been used."));
1405
+ }
1406
+ return Result.error(new KnownErrors.CliAuthError(`Unexpected status from CLI auth polling: ${pollResult.status}`));
1407
+ }
1408
+ return Result.error(new KnownErrors.CliAuthError("Timed out waiting for CLI authentication."));
1409
+ }
1241
1410
  async signInWithPasskey() {
1242
1411
  this._ensurePersistentTokenStore();
1243
1412
  const session = await this._getSession();