@stackframe/stack 2.5.18 → 2.5.19

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 (58) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/components/credential-sign-in.js +1 -3
  3. package/dist/components/credential-sign-in.js.map +1 -1
  4. package/dist/components/elements/sidebar-layout.d.mts +21 -0
  5. package/dist/components/elements/sidebar-layout.d.ts +21 -0
  6. package/dist/components/elements/sidebar-layout.js +125 -0
  7. package/dist/components/elements/sidebar-layout.js.map +1 -0
  8. package/dist/components/elements/user-avatar.d.mts +5 -12
  9. package/dist/components/elements/user-avatar.d.ts +5 -12
  10. package/dist/components/elements/user-avatar.js.map +1 -1
  11. package/dist/components/selected-team-switcher.js +35 -5
  12. package/dist/components/selected-team-switcher.js.map +1 -1
  13. package/dist/components-page/account-settings.js +47 -49
  14. package/dist/components-page/account-settings.js.map +1 -1
  15. package/dist/components-page/stack-handler.js +20 -0
  16. package/dist/components-page/stack-handler.js.map +1 -1
  17. package/dist/components-page/team-creation.d.mts +7 -0
  18. package/dist/components-page/team-creation.d.ts +7 -0
  19. package/dist/components-page/team-creation.js +92 -0
  20. package/dist/components-page/team-creation.js.map +1 -0
  21. package/dist/components-page/team-settings.d.mts +8 -0
  22. package/dist/components-page/team-settings.d.ts +8 -0
  23. package/dist/components-page/team-settings.js +139 -0
  24. package/dist/components-page/team-settings.js.map +1 -0
  25. package/dist/esm/components/credential-sign-in.js +1 -3
  26. package/dist/esm/components/credential-sign-in.js.map +1 -1
  27. package/dist/esm/components/elements/sidebar-layout.js +90 -0
  28. package/dist/esm/components/elements/sidebar-layout.js.map +1 -0
  29. package/dist/esm/components/elements/user-avatar.js.map +1 -1
  30. package/dist/esm/components/selected-team-switcher.js +39 -7
  31. package/dist/esm/components/selected-team-switcher.js.map +1 -1
  32. package/dist/esm/components-page/account-settings.js +33 -35
  33. package/dist/esm/components-page/account-settings.js.map +1 -1
  34. package/dist/esm/components-page/stack-handler.js +20 -0
  35. package/dist/esm/components-page/stack-handler.js.map +1 -1
  36. package/dist/esm/components-page/team-creation.js +68 -0
  37. package/dist/esm/components-page/team-creation.js.map +1 -0
  38. package/dist/esm/components-page/team-settings.js +115 -0
  39. package/dist/esm/components-page/team-settings.js.map +1 -0
  40. package/dist/esm/generated/global-css.js +1 -1
  41. package/dist/esm/generated/global-css.js.map +1 -1
  42. package/dist/esm/lib/auth.js +4 -0
  43. package/dist/esm/lib/auth.js.map +1 -1
  44. package/dist/esm/lib/stack-app.js +178 -34
  45. package/dist/esm/lib/stack-app.js.map +1 -1
  46. package/dist/generated/global-css.d.mts +1 -1
  47. package/dist/generated/global-css.d.ts +1 -1
  48. package/dist/generated/global-css.js +1 -1
  49. package/dist/generated/global-css.js.map +1 -1
  50. package/dist/index.d.mts +1 -1
  51. package/dist/index.d.ts +1 -1
  52. package/dist/lib/auth.js +4 -0
  53. package/dist/lib/auth.js.map +1 -1
  54. package/dist/lib/stack-app.d.mts +35 -5
  55. package/dist/lib/stack-app.d.ts +35 -5
  56. package/dist/lib/stack-app.js +178 -34
  57. package/dist/lib/stack-app.js.map +1 -1
  58. package/package.json +7 -6
@@ -24,7 +24,7 @@ import { constructRedirectUrl } from "../utils/url";
24
24
  import { addNewOAuthProviderOrScope, callOAuthCallback, signInWithOAuth } from "./auth";
25
25
  import { deleteCookie, getCookie, setOrDeleteCookie } from "./cookie";
26
26
  var NextNavigation = scrambleDuringCompileTime(NextNavigationUnscrambled);
27
- var clientVersion = "js @stackframe/stack@2.5.18";
27
+ var clientVersion = "js @stackframe/stack@2.5.19";
28
28
  function getUrls(partial) {
29
29
  const handler = partial.handler ?? "/handler";
30
30
  const home = partial.home ?? "/";
@@ -46,6 +46,7 @@ function getUrls(partial) {
46
46
  accountSettings: `${handler}/account-settings`,
47
47
  error: `${handler}/error`,
48
48
  teamInvitation: `${handler}/team-invitation`,
49
+ teamCreation: `${handler}/team-creation`,
49
50
  ...filterUndefined(partial)
50
51
  };
51
52
  }
@@ -177,6 +178,16 @@ var _StackClientAppImpl = class __StackClientAppImpl {
177
178
  });
178
179
  }
179
180
  );
181
+ this._teamMemberProfilesCache = createCacheBySession(
182
+ async (session, [teamId]) => {
183
+ return await this._interface.listTeamMemberProfiles({ teamId }, session);
184
+ }
185
+ );
186
+ this._currentUserTeamProfileCache = createCacheBySession(
187
+ async (session, [teamId]) => {
188
+ return await this._interface.getTeamMemberProfile({ teamId, userId: "me" }, session);
189
+ }
190
+ );
180
191
  this._memoryTokenStore = createEmptyTokenStore();
181
192
  this._requestTokenStores = /* @__PURE__ */ new WeakMap();
182
193
  this._storedCookieTokenStore = null;
@@ -458,6 +469,9 @@ var _StackClientAppImpl = class __StackClientAppImpl {
458
469
  return React.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
459
470
  }
460
471
  async _signInToAccountWithTokens(tokens) {
472
+ if (!("accessToken" in tokens) || !("refreshToken" in tokens)) {
473
+ throw new StackAssertionError("Invalid tokens object; can't sign in with this", { tokens });
474
+ }
461
475
  const tokenStore = this._getOrCreateTokenStore();
462
476
  tokenStore.set(tokens);
463
477
  }
@@ -485,6 +499,7 @@ var _StackClientAppImpl = class __StackClientAppImpl {
485
499
  signUpEnabled: crud.config.sign_up_enabled,
486
500
  credentialEnabled: crud.config.credential_enabled,
487
501
  magicLinkEnabled: crud.config.magic_link_enabled,
502
+ clientTeamCreationEnabled: crud.config.client_team_creation_enabled,
488
503
  oauthProviders: crud.config.enabled_oauth_providers.map((p) => ({
489
504
  id: p.id
490
505
  }))
@@ -496,6 +511,15 @@ var _StackClientAppImpl = class __StackClientAppImpl {
496
511
  id: crud.id
497
512
  };
498
513
  }
514
+ _clientTeamUserFromCrud(crud) {
515
+ return {
516
+ id: crud.user_id,
517
+ teamProfile: {
518
+ displayName: crud.display_name,
519
+ profileImageUrl: crud.profile_image_url
520
+ }
521
+ };
522
+ }
499
523
  _clientTeamFromCrud(crud) {
500
524
  const app = this;
501
525
  return {
@@ -509,6 +533,14 @@ var _StackClientAppImpl = class __StackClientAppImpl {
509
533
  session: app._getSession(),
510
534
  callbackUrl: constructRedirectUrl(app.urls.teamInvitation)
511
535
  });
536
+ },
537
+ async listUsers() {
538
+ const result = await app._teamMemberProfilesCache.getOrWait([app._getSession(), crud.id], "write-only");
539
+ return result.map((crud2) => app._clientTeamUserFromCrud(crud2));
540
+ },
541
+ useUsers() {
542
+ const result = useAsyncCache(app._teamMemberProfilesCache, [app._getSession(), crud.id], "team.useUsers()");
543
+ return result.map((crud2) => app._clientTeamUserFromCrud(crud2));
512
544
  }
513
545
  };
514
546
  }
@@ -561,6 +593,24 @@ var _StackClientAppImpl = class __StackClientAppImpl {
561
593
  }
562
594
  };
563
595
  }
596
+ _editableTeamProfileFromCrud(crud) {
597
+ const app = this;
598
+ return {
599
+ displayName: crud.display_name,
600
+ profileImageUrl: crud.profile_image_url,
601
+ async update(update) {
602
+ await app._interface.updateTeamMemberProfile({
603
+ teamId: crud.team_id,
604
+ userId: crud.user_id,
605
+ profile: {
606
+ display_name: update.displayName,
607
+ profile_image_url: update.profileImageUrl
608
+ }
609
+ }, app._getSession());
610
+ await app._currentUserTeamProfileCache.refresh([app._getSession(), crud.team_id]);
611
+ }
612
+ };
613
+ }
564
614
  _createUserExtra(crud, session) {
565
615
  const app = this;
566
616
  async function getConnectedAccount(id, options) {
@@ -606,6 +656,9 @@ var _StackClientAppImpl = class __StackClientAppImpl {
606
656
  await app._currentUserTeamsCache.refresh([session]);
607
657
  return app._clientTeamFromCrud(crud2);
608
658
  },
659
+ async leaveTeam(team) {
660
+ await app._interface.leaveTeam(team.id, session);
661
+ },
609
662
  async listPermissions(scope, options) {
610
663
  const recursive = options?.recursive ?? true;
611
664
  const permissions = await app._currentUserPermissionsCache.getOrWait([session, scope.id, recursive], "write-only");
@@ -638,6 +691,14 @@ var _StackClientAppImpl = class __StackClientAppImpl {
638
691
  },
639
692
  async updatePassword(options) {
640
693
  return await app._updatePassword(options, session);
694
+ },
695
+ async getTeamProfile(team) {
696
+ const result = await app._currentUserTeamProfileCache.getOrWait([session, team.id], "write-only");
697
+ return app._editableTeamProfileFromCrud(result);
698
+ },
699
+ useTeamProfile(team) {
700
+ const result = useAsyncCache(app._currentUserTeamProfileCache, [session, team.id], "user.useTeamProfile()");
701
+ return app._editableTeamProfileFromCrud(result);
641
702
  }
642
703
  };
643
704
  }
@@ -774,6 +835,9 @@ var _StackClientAppImpl = class __StackClientAppImpl {
774
835
  async redirectToTeamInvitation(options) {
775
836
  return await this._redirectToHandler("teamInvitation", options);
776
837
  }
838
+ async redirectToTeamCreation(options) {
839
+ return await this._redirectToHandler("teamCreation", options);
840
+ }
777
841
  async sendForgotPasswordEmail(email) {
778
842
  const redirectUrl = constructRedirectUrl(this.urls.passwordReset);
779
843
  const error = await this._interface.sendForgotPasswordEmail(email, redirectUrl);
@@ -891,33 +955,48 @@ var _StackClientAppImpl = class __StackClientAppImpl {
891
955
  }
892
956
  );
893
957
  }
958
+ /**
959
+ * @deprecated
960
+ * TODO remove
961
+ */
962
+ async _experimentalMfa(error, session) {
963
+ const otp = prompt("Please enter the six-digit TOTP code from your authenticator app.");
964
+ if (!otp) {
965
+ throw new KnownErrors.InvalidTotpCode();
966
+ }
967
+ return await this._interface.totpMfa(
968
+ error.details?.attempt_code ?? throwErr("attempt code missing"),
969
+ otp,
970
+ session
971
+ );
972
+ }
973
+ /**
974
+ * @deprecated
975
+ * TODO remove
976
+ */
977
+ async _catchMfaRequiredError(callback) {
978
+ try {
979
+ return await callback();
980
+ } catch (e) {
981
+ if (e instanceof KnownErrors.MultiFactorAuthenticationRequired) {
982
+ return await this._experimentalMfa(e, this._getSession());
983
+ }
984
+ throw e;
985
+ }
986
+ }
894
987
  async signInWithCredential(options) {
895
988
  this._ensurePersistentTokenStore();
896
989
  const session = this._getSession();
897
990
  let result;
898
991
  try {
899
- result = await this._interface.signInWithCredential(options.email, options.password, session);
992
+ result = await this._catchMfaRequiredError(async () => {
993
+ return await this._interface.signInWithCredential(options.email, options.password, session);
994
+ });
900
995
  } catch (e) {
901
- if (options.__experimental_mfa && e instanceof KnownErrors.MultiFactorAuthenticationRequired) {
902
- const otp = prompt("Please enter the six-digit TOTP code from your authenticator app.");
903
- try {
904
- if (!otp) {
905
- throw new KnownErrors.InvalidTotpCode();
906
- }
907
- result = await this._interface.totpMfa(
908
- e.details?.attempt_code ?? throwErr("attempt code missing"),
909
- otp,
910
- session
911
- );
912
- } catch (e2) {
913
- if (e2 instanceof KnownErrors.InvalidTotpCode) {
914
- return e2;
915
- }
916
- throw e2;
917
- }
918
- } else {
919
- throw e;
996
+ if (e instanceof KnownErrors.InvalidTotpCode) {
997
+ return e;
920
998
  }
999
+ throw e;
921
1000
  }
922
1001
  if (!(result instanceof KnownError)) {
923
1002
  await this._signInToAccountWithTokens(result);
@@ -943,7 +1022,17 @@ var _StackClientAppImpl = class __StackClientAppImpl {
943
1022
  }
944
1023
  async signInWithMagicLink(code) {
945
1024
  this._ensurePersistentTokenStore();
946
- const result = await this._interface.signInWithMagicLink(code);
1025
+ let result;
1026
+ try {
1027
+ result = await this._catchMfaRequiredError(async () => {
1028
+ return await this._interface.signInWithMagicLink(code);
1029
+ });
1030
+ } catch (e) {
1031
+ if (e instanceof KnownErrors.InvalidTotpCode) {
1032
+ return e;
1033
+ }
1034
+ throw e;
1035
+ }
947
1036
  if (result instanceof KnownError) {
948
1037
  return result;
949
1038
  }
@@ -956,10 +1045,21 @@ var _StackClientAppImpl = class __StackClientAppImpl {
956
1045
  }
957
1046
  async callOAuthCallback() {
958
1047
  this._ensurePersistentTokenStore();
959
- const result = await callOAuthCallback(this._interface, this.urls.oauthCallback);
1048
+ let result;
1049
+ try {
1050
+ result = await this._catchMfaRequiredError(async () => {
1051
+ return await callOAuthCallback(this._interface, this.urls.oauthCallback);
1052
+ });
1053
+ } catch (e) {
1054
+ if (e instanceof KnownErrors.InvalidTotpCode) {
1055
+ alert("Invalid TOTP code. Please try signing in again.");
1056
+ }
1057
+ throw e;
1058
+ }
960
1059
  if (result) {
1060
+ console.log("OAuth callback result", result);
961
1061
  await this._signInToAccountWithTokens(result);
962
- if (result.afterCallbackRedirectUrl) {
1062
+ if ("afterCallbackRedirectUrl" in result && result.afterCallbackRedirectUrl) {
963
1063
  await _redirectTo(result.afterCallbackRedirectUrl, { replace: true });
964
1064
  return true;
965
1065
  } else if (result.newUser) {
@@ -1113,9 +1213,6 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1113
1213
  this._serverTeamsCache = createCache(async ([userId]) => {
1114
1214
  return await this._interface.listServerTeams({ userId });
1115
1215
  });
1116
- this._serverTeamUsersCache = createCache(async ([teamId]) => {
1117
- return await this._interface.listServerTeamUsers(teamId);
1118
- });
1119
1216
  this._serverTeamUserPermissionsCache = createCache(async ([teamId, userId, recursive]) => {
1120
1217
  return await this._interface.listServerTeamPermissions({ teamId, userId, recursive }, null);
1121
1218
  });
@@ -1145,12 +1242,33 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1145
1242
  });
1146
1243
  }
1147
1244
  );
1245
+ this._serverTeamMemberProfilesCache = createCache(
1246
+ async ([teamId]) => {
1247
+ return await this._interface.listServerTeamMemberProfiles({ teamId });
1248
+ }
1249
+ );
1250
+ this._serverUserTeamProfileCache = createCache(
1251
+ async ([teamId, userId]) => {
1252
+ return await this._interface.getServerTeamMemberProfile({ teamId, userId });
1253
+ }
1254
+ );
1148
1255
  }
1149
1256
  async _updateServerUser(userId, update) {
1150
1257
  const result = await this._interface.updateServerUser(userId, serverUserUpdateOptionsToCrud(update));
1151
1258
  await this._refreshUsers();
1152
1259
  return result;
1153
1260
  }
1261
+ _serverEditableTeamProfileFromCrud(crud) {
1262
+ const app = this;
1263
+ const clientProfile = this._editableTeamProfileFromCrud(crud);
1264
+ return {
1265
+ ...clientProfile,
1266
+ async update(update) {
1267
+ await clientProfile.update(update);
1268
+ await app._serverUserTeamProfileCache.refresh([crud.team_id, crud.user_id]);
1269
+ }
1270
+ };
1271
+ }
1154
1272
  _serverUserFromCrud(crud) {
1155
1273
  const app = this;
1156
1274
  async function getConnectedAccount(id, options) {
@@ -1229,6 +1347,9 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1229
1347
  await app._serverTeamsCache.refresh([void 0]);
1230
1348
  return app._serverTeamFromCrud(team);
1231
1349
  },
1350
+ leaveTeam: async (team) => {
1351
+ await app._interface.leaveServerTeam({ teamId: team.id, userId: crud.id });
1352
+ },
1232
1353
  async listPermissions(scope, options) {
1233
1354
  const recursive = options?.recursive ?? true;
1234
1355
  const permissions = await app._serverTeamUserPermissionsCache.getOrWait([scope.id, crud.id, recursive], "write-only");
@@ -1258,6 +1379,23 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1258
1379
  },
1259
1380
  async updatePassword(options) {
1260
1381
  return await app._checkFeatureSupport("updatePassword() on ServerUser", {});
1382
+ },
1383
+ async getTeamProfile(team) {
1384
+ const result = await app._serverUserTeamProfileCache.getOrWait([team.id, crud.id], "write-only");
1385
+ return app._serverEditableTeamProfileFromCrud(result);
1386
+ },
1387
+ useTeamProfile(team) {
1388
+ const result = useAsyncCache(app._serverUserTeamProfileCache, [team.id, crud.id], "user.useTeamProfile()");
1389
+ return useMemo(() => app._serverEditableTeamProfileFromCrud(result), [result]);
1390
+ }
1391
+ };
1392
+ }
1393
+ _serverTeamUserFromCrud(crud) {
1394
+ return {
1395
+ ...this._serverUserFromCrud(crud.user),
1396
+ teamProfile: {
1397
+ displayName: crud.display_name,
1398
+ profileImageUrl: crud.profile_image_url
1261
1399
  }
1262
1400
  };
1263
1401
  }
@@ -1278,9 +1416,6 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1278
1416
  displayName: crud.display_name,
1279
1417
  profileImageUrl: crud.profile_image_url,
1280
1418
  createdAt: new Date(crud.created_at_millis),
1281
- async listUsers() {
1282
- return (await app._interface.listServerTeamUsers(crud.id)).map((u) => app._serverUserFromCrud(u));
1283
- },
1284
1419
  async update(update) {
1285
1420
  await app._interface.updateServerTeam(crud.id, serverTeamUpdateOptionsToCrud(update));
1286
1421
  await app._serverTeamsCache.refresh([void 0]);
@@ -1289,23 +1424,27 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1289
1424
  await app._interface.deleteServerTeam(crud.id);
1290
1425
  await app._serverTeamsCache.refresh([void 0]);
1291
1426
  },
1427
+ async listUsers() {
1428
+ const result = await app._serverTeamMemberProfilesCache.getOrWait([crud.id], "write-only");
1429
+ return result.map((u) => app._serverTeamUserFromCrud(u));
1430
+ },
1292
1431
  useUsers() {
1293
- const result = useAsyncCache(app._serverTeamUsersCache, [crud.id], "team.useUsers()");
1294
- return useMemo(() => result.map((u) => app._serverUserFromCrud(u)), [result]);
1432
+ const result = useAsyncCache(app._serverTeamMemberProfilesCache, [crud.id], "team.useUsers()");
1433
+ return useMemo(() => result.map((u) => app._serverTeamUserFromCrud(u)), [result]);
1295
1434
  },
1296
1435
  async addUser(userId) {
1297
1436
  await app._interface.addServerUserToTeam({
1298
1437
  teamId: crud.id,
1299
1438
  userId
1300
1439
  });
1301
- await app._serverTeamUsersCache.refresh([crud.id]);
1440
+ await app._serverTeamMemberProfilesCache.refresh([crud.id]);
1302
1441
  },
1303
1442
  async removeUser(userId) {
1304
1443
  await app._interface.removeServerUserFromTeam({
1305
1444
  teamId: crud.id,
1306
1445
  userId
1307
1446
  });
1308
- await app._serverTeamUsersCache.refresh([crud.id]);
1447
+ await app._serverTeamMemberProfilesCache.refresh([crud.id]);
1309
1448
  },
1310
1449
  async inviteUser(options) {
1311
1450
  return await app._interface.sendTeamInvitation({
@@ -1502,6 +1641,7 @@ var _StackAdminAppImpl = class extends _StackServerAppImpl {
1502
1641
  signUpEnabled: data.config.sign_up_enabled,
1503
1642
  credentialEnabled: data.config.credential_enabled,
1504
1643
  magicLinkEnabled: data.config.magic_link_enabled,
1644
+ clientTeamCreationEnabled: data.config.client_team_creation_enabled,
1505
1645
  allowLocalhost: data.config.allow_localhost,
1506
1646
  oauthProviders: data.config.oauth_providers.map((p) => p.type === "shared" ? {
1507
1647
  id: p.id,
@@ -1538,6 +1678,9 @@ var _StackAdminAppImpl = class extends _StackServerAppImpl {
1538
1678
  await app._interface.updateProject(adminProjectUpdateOptionsToCrud(update));
1539
1679
  await onRefresh();
1540
1680
  },
1681
+ async delete() {
1682
+ await app._interface.deleteProject();
1683
+ },
1541
1684
  async getProductionModeErrors() {
1542
1685
  return getProductionModeErrors(data);
1543
1686
  },
@@ -1742,6 +1885,7 @@ function adminProjectUpdateOptionsToCrud(options) {
1742
1885
  magic_link_enabled: options.config?.magicLinkEnabled,
1743
1886
  allow_localhost: options.config?.allowLocalhost,
1744
1887
  create_team_on_sign_up: options.config?.createTeamOnSignUp,
1888
+ client_team_creation_enabled: options.config?.clientTeamCreationEnabled,
1745
1889
  team_creator_default_permissions: options.config?.teamCreatorDefaultPermissions,
1746
1890
  team_member_default_permissions: options.config?.teamMemberDefaultPermissions
1747
1891
  }