@stackframe/js 2.8.54 → 2.8.58

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 (46) hide show
  1. package/dist/esm/lib/cookie.js +50 -15
  2. package/dist/esm/lib/cookie.js.map +1 -1
  3. package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js +235 -0
  4. package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
  5. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js +81 -25
  6. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
  7. package/dist/esm/lib/stack-app/apps/implementations/common.js +2 -1
  8. package/dist/esm/lib/stack-app/apps/implementations/common.js.map +1 -1
  9. package/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js +31 -23
  10. package/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js.map +1 -1
  11. package/dist/esm/lib/stack-app/apps/interfaces/admin-app.js.map +1 -1
  12. package/dist/esm/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
  13. package/dist/esm/lib/stack-app/apps/interfaces/server-app.js.map +1 -1
  14. package/dist/esm/lib/stack-app/common.js.map +1 -1
  15. package/dist/esm/lib/stack-app/index.js.map +1 -1
  16. package/dist/esm/lib/stack-app/projects/index.js +4 -0
  17. package/dist/esm/lib/stack-app/projects/index.js.map +1 -1
  18. package/dist/esm/lib/stack-app/teams/index.js.map +1 -1
  19. package/dist/esm/lib/stack-app/users/index.js +13 -12
  20. package/dist/esm/lib/stack-app/users/index.js.map +1 -1
  21. package/dist/index.d.mts +249 -16
  22. package/dist/index.d.ts +249 -16
  23. package/dist/lib/cookie.js +50 -15
  24. package/dist/lib/cookie.js.map +1 -1
  25. package/dist/lib/stack-app/apps/implementations/admin-app-impl.js +235 -0
  26. package/dist/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
  27. package/dist/lib/stack-app/apps/implementations/client-app-impl.js +79 -23
  28. package/dist/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
  29. package/dist/lib/stack-app/apps/implementations/common.js +2 -1
  30. package/dist/lib/stack-app/apps/implementations/common.js.map +1 -1
  31. package/dist/lib/stack-app/apps/implementations/server-app-impl.js +29 -21
  32. package/dist/lib/stack-app/apps/implementations/server-app-impl.js.map +1 -1
  33. package/dist/lib/stack-app/apps/interfaces/admin-app.js.map +1 -1
  34. package/dist/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
  35. package/dist/lib/stack-app/apps/interfaces/server-app.js.map +1 -1
  36. package/dist/lib/stack-app/common.js.map +1 -1
  37. package/dist/lib/stack-app/email/index.js.map +1 -1
  38. package/dist/lib/stack-app/index.js.map +1 -1
  39. package/dist/lib/stack-app/project-configs/index.js.map +1 -1
  40. package/dist/lib/stack-app/projects/index.js +4 -0
  41. package/dist/lib/stack-app/projects/index.js.map +1 -1
  42. package/dist/lib/stack-app/teams/index.js.map +1 -1
  43. package/dist/lib/stack-app/users/index.js +15 -14
  44. package/dist/lib/stack-app/users/index.js.map +1 -1
  45. package/package.json +3 -2
  46. package/CHANGELOG.md +0 -2052
@@ -39,6 +39,7 @@ var import_sessions = require("@stackframe/stack-shared/dist/sessions");
39
39
  var import_bytes = require("@stackframe/stack-shared/dist/utils/bytes");
40
40
  var import_env = require("@stackframe/stack-shared/dist/utils/env");
41
41
  var import_errors = require("@stackframe/stack-shared/dist/utils/errors");
42
+ var import_json = require("@stackframe/stack-shared/dist/utils/json");
42
43
  var import_maps = require("@stackframe/stack-shared/dist/utils/maps");
43
44
  var import_objects = require("@stackframe/stack-shared/dist/utils/objects");
44
45
  var import_promises = require("@stackframe/stack-shared/dist/utils/promises");
@@ -58,7 +59,6 @@ var import_projects = require("../../projects/index.js");
58
59
  var import_teams = require("../../teams/index.js");
59
60
  var import_users = require("../../users/index.js");
60
61
  var import_common2 = require("./common.js");
61
- var import_json = require("@stackframe/stack-shared/dist/utils/json");
62
62
  var isReactServer = false;
63
63
  var process = globalThis.process ?? { env: {} };
64
64
  var allClientApps = /* @__PURE__ */ new Map();
@@ -483,9 +483,10 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
483
483
  return;
484
484
  }
485
485
  const domain = await this._trustedParentDomainCache.getOrWait([hostname], "read-write");
486
+ const cookieOptions = { maxAge: 60 * 60 * 24 * 365, noOpIfServerComponent: true };
486
487
  const setCookie = async (targetDomain, value2) => {
487
488
  const name = this._getCustomRefreshCookieName(targetDomain);
488
- const options = { maxAge: 60 * 60 * 24 * 365, domain: targetDomain, noOpIfServerComponent: true };
489
+ const options = { ...cookieOptions, domain: targetDomain };
489
490
  if (context === "browser") {
490
491
  (0, import_cookie.setOrDeleteCookieClient)(name, value2, options);
491
492
  } else {
@@ -498,7 +499,7 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
498
499
  const value = refreshToken && updatedAt ? this._formatRefreshCookieValue(refreshToken, updatedAt) : null;
499
500
  await setCookie(domain.data, value);
500
501
  const isSecure = await (0, import_cookie.isSecure)();
501
- await (0, import_cookie.setOrDeleteCookie)(this._getRefreshTokenDefaultCookieNameForSecure(isSecure), null);
502
+ await (0, import_cookie.setOrDeleteCookie)(this._getRefreshTokenDefaultCookieNameForSecure(isSecure), null, cookieOptions);
502
503
  });
503
504
  }
504
505
  async _getTrustedParentDomain(currentDomain) {
@@ -550,7 +551,7 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
550
551
  );
551
552
  (0, import_cookie.setOrDeleteCookieClient)(defaultName, refreshCookieValue, { maxAge: 60 * 60 * 24 * 365, secure });
552
553
  (0, import_cookie.setOrDeleteCookieClient)(this._accessTokenCookieName, accessTokenPayload, { maxAge: 60 * 60 * 24 });
553
- cookieNamesToDelete.forEach((name) => (0, import_cookie.deleteCookieClient)(name));
554
+ cookieNamesToDelete.forEach((name) => (0, import_cookie.deleteCookieClient)(name, {}));
554
555
  this._queueCustomRefreshCookieUpdate(refreshToken, updatedAt, "browser");
555
556
  hasSucceededInWriting = true;
556
557
  } catch (e) {
@@ -594,7 +595,7 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
594
595
  if (cookieNamesToDelete.length > 0) {
595
596
  await Promise.all(
596
597
  cookieNamesToDelete.map(
597
- (name) => (0, import_cookie.setOrDeleteCookie)(name, null, { noOpIfServerComponent: true })
598
+ (name) => (0, import_cookie.deleteCookie)(name, { noOpIfServerComponent: true })
598
599
  )
599
600
  );
600
601
  }
@@ -930,13 +931,21 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
930
931
  _internalSession: session,
931
932
  currentSession: {
932
933
  async getTokens() {
933
- const tokens = await session.getOrFetchLikelyValidTokens(2e4);
934
+ const tokens = await session.getOrFetchLikelyValidTokens(2e4, 75e3);
934
935
  return {
935
936
  accessToken: tokens?.accessToken.token ?? null,
936
937
  refreshToken: tokens?.refreshToken?.token ?? null
937
938
  };
938
939
  }
939
940
  },
941
+ async getAccessToken() {
942
+ const tokens = await this.currentSession.getTokens();
943
+ return tokens.accessToken;
944
+ },
945
+ async getRefreshToken() {
946
+ const tokens = await this.currentSession.getTokens();
947
+ return tokens.refreshToken;
948
+ },
940
949
  async getAuthHeaders() {
941
950
  return {
942
951
  "x-stack-auth": JSON.stringify(await this.getAuthJson())
@@ -986,6 +995,8 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
986
995
  passkeyAuthEnabled: crud.passkey_auth_enabled,
987
996
  isMultiFactorRequired: crud.requires_totp_mfa,
988
997
  isAnonymous: crud.is_anonymous,
998
+ isRestricted: crud.is_restricted,
999
+ restrictedReason: crud.restricted_reason,
989
1000
  toClientJson() {
990
1001
  return crud;
991
1002
  }
@@ -1012,7 +1023,7 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
1012
1023
  return this.update({ clientMetadata: metadata });
1013
1024
  },
1014
1025
  async setSelectedTeam(team) {
1015
- await this.update({ selectedTeamId: team?.id ?? null });
1026
+ await this.update({ selectedTeamId: typeof team === "string" ? team : team?.id ?? null });
1016
1027
  },
1017
1028
  getConnectedAccount,
1018
1029
  async getTeam(teamId) {
@@ -1217,16 +1228,33 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
1217
1228
  const response = import_results.Result.orThrow(await this._customProductsCache.getOrWait([session, options.customCustomerId, options.cursor ?? null, options.limit ?? null], "write-only"));
1218
1229
  return this._customerProductsFromResponse(response);
1219
1230
  }
1231
+ async cancelSubscription(options) {
1232
+ const session = await this._getSession();
1233
+ const user = await this.getUser();
1234
+ if (!user) {
1235
+ throw new import_stack_shared.KnownErrors.UserAuthenticationRequired();
1236
+ }
1237
+ const customerType = "teamId" in options ? "team" : "user";
1238
+ const customerId = "teamId" in options ? options.teamId : user.id;
1239
+ await this._interface.cancelSubscription({
1240
+ customer_type: customerType,
1241
+ customer_id: customerId,
1242
+ product_id: options.productId
1243
+ }, session);
1244
+ if (customerType === "user") {
1245
+ await this._userProductsCache.invalidateWhere(([cachedSession, userId]) => cachedSession === session && userId === customerId);
1246
+ } else {
1247
+ await this._teamProductsCache.invalidateWhere(([cachedSession, teamId]) => cachedSession === session && teamId === customerId);
1248
+ }
1249
+ }
1220
1250
  _currentUserFromCrud(crud, session) {
1221
- const currentUser = {
1251
+ const currentUser = (0, import_users.withUserDestructureGuard)({
1222
1252
  ...this._createBaseUser(crud),
1223
1253
  ...this._createAuth(session),
1224
1254
  ...this._createUserExtraFromCurrent(crud, session),
1225
1255
  ...this._isInternalProject() ? this._createInternalUserExtra(session) : {},
1226
1256
  ...this._createCustomer(crud.id, "user", session)
1227
- };
1228
- (0, import_users.attachUserDestructureGuard)(currentUser);
1229
- Object.freeze(currentUser);
1257
+ });
1230
1258
  return currentUser;
1231
1259
  }
1232
1260
  _clientSessionFromCrud(crud) {
@@ -1299,7 +1327,7 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
1299
1327
  const queryParams = new URLSearchParams(window.location.search);
1300
1328
  url = queryParams.get("after_auth_return_to") || url;
1301
1329
  }
1302
- } else if (handlerName === "signIn" || handlerName === "signUp") {
1330
+ } else if (handlerName === "signIn" || handlerName === "signUp" || handlerName === "onboarding") {
1303
1331
  if (isReactServer || typeof window === "undefined") {
1304
1332
  } else {
1305
1333
  const currentUrl = new URL(window.location.href);
@@ -1348,6 +1376,9 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
1348
1376
  async redirectToAfterSignUp(options) {
1349
1377
  return await this._redirectToHandler("afterSignUp", options);
1350
1378
  }
1379
+ async redirectToOnboarding(options) {
1380
+ return await this._redirectToHandler("onboarding", options);
1381
+ }
1351
1382
  async redirectToAfterSignOut(options) {
1352
1383
  return await this._redirectToHandler("afterSignOut", options);
1353
1384
  }
@@ -1413,16 +1444,22 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
1413
1444
  return result;
1414
1445
  }
1415
1446
  async getUser(options) {
1447
+ if (options?.or === "anonymous" && options.includeRestricted === false) {
1448
+ throw new Error("Cannot use { or: 'anonymous' } with { includeRestricted: false }. Anonymous users implicitly include restricted users.");
1449
+ }
1416
1450
  this._ensurePersistentTokenStore(options?.tokenStore);
1417
1451
  const session = await this._getSession(options?.tokenStore);
1418
1452
  let crud = import_results.Result.orThrow(await this._currentUserCache.getOrWait([session], "write-only"));
1419
- if (crud?.is_anonymous && options?.or !== "anonymous" && options?.or !== "anonymous-if-exists[deprecated]") {
1420
- crud = null;
1421
- }
1422
- if (crud === null) {
1453
+ const includeAnonymous = options?.or === "anonymous" || options?.or === "anonymous-if-exists[deprecated]";
1454
+ const includeRestricted = options?.includeRestricted === true || includeAnonymous;
1455
+ if (crud === null || crud.is_anonymous && !includeAnonymous || crud.is_restricted && !includeRestricted) {
1423
1456
  switch (options?.or) {
1424
1457
  case "redirect": {
1425
- await this.redirectToSignIn({ replace: true });
1458
+ if (!crud?.is_anonymous && crud?.is_restricted) {
1459
+ await this.redirectToOnboarding({ replace: true });
1460
+ } else {
1461
+ await this.redirectToSignIn({ replace: true });
1462
+ }
1426
1463
  break;
1427
1464
  }
1428
1465
  case "throw": {
@@ -1430,7 +1467,7 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
1430
1467
  }
1431
1468
  case "anonymous": {
1432
1469
  const tokens = await this._signUpAnonymously();
1433
- return await this.getUser({ tokenStore: tokens, or: "anonymous-if-exists[deprecated]" }) ?? (0, import_errors.throwErr)("Something went wrong while signing up anonymously");
1470
+ return await this.getUser({ tokenStore: tokens, or: "anonymous-if-exists[deprecated]", includeRestricted: true }) ?? (0, import_errors.throwErr)("Something went wrong while signing up anonymously");
1434
1471
  }
1435
1472
  case void 0:
1436
1473
  case "anonymous-if-exists[deprecated]":
@@ -1442,7 +1479,7 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
1442
1479
  return crud && this._currentUserFromCrud(crud, session);
1443
1480
  }
1444
1481
  _getTokenPartialUserFromSession(session, options) {
1445
- const accessToken = session.getAccessTokenIfNotExpiredYet(0);
1482
+ const accessToken = session.getAccessTokenIfNotExpiredYet(0, null);
1446
1483
  if (!accessToken) {
1447
1484
  return null;
1448
1485
  }
@@ -1455,7 +1492,9 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
1455
1492
  primaryEmail: accessToken.payload.email,
1456
1493
  displayName: accessToken.payload.name,
1457
1494
  primaryEmailVerified: accessToken.payload.email_verified,
1458
- isAnonymous
1495
+ isAnonymous,
1496
+ isRestricted: accessToken.payload.is_restricted,
1497
+ restrictedReason: accessToken.payload.restricted_reason
1459
1498
  };
1460
1499
  }
1461
1500
  async _getPartialUserFromConvex(ctx) {
@@ -1468,7 +1507,9 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
1468
1507
  displayName: auth.name ?? null,
1469
1508
  primaryEmail: auth.email ?? null,
1470
1509
  primaryEmailVerified: auth.email_verified,
1471
- isAnonymous: auth.is_anonymous
1510
+ isAnonymous: auth.is_anonymous,
1511
+ isRestricted: auth.is_restricted,
1512
+ restrictedReason: auth.restricted_reason ?? null
1472
1513
  };
1473
1514
  }
1474
1515
  async getPartialUser(options) {
@@ -1490,7 +1531,7 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
1490
1531
  return async (args) => {
1491
1532
  const session = await this._getSession(options.tokenStore ?? this._tokenStoreInit);
1492
1533
  if (!args.forceRefreshToken) {
1493
- const tokens2 = await session.getOrFetchLikelyValidTokens(2e4);
1534
+ const tokens2 = await session.getOrFetchLikelyValidTokens(2e4, 75e3);
1494
1535
  return tokens2?.accessToken.token ?? null;
1495
1536
  }
1496
1537
  const tokens = await session.fetchNewTokens();
@@ -1499,7 +1540,7 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
1499
1540
  }
1500
1541
  async getConvexHttpClientAuth(options) {
1501
1542
  const session = await this._getSession(options.tokenStore);
1502
- const tokens = await session.getOrFetchLikelyValidTokens(2e4);
1543
+ const tokens = await session.getOrFetchLikelyValidTokens(2e4, 75e3);
1503
1544
  return tokens?.accessToken.token ?? "";
1504
1545
  }
1505
1546
  async _updateClientUser(update, session) {
@@ -1846,6 +1887,20 @@ ${url}`);
1846
1887
  await user.signOut({ redirectUrl: options?.redirectUrl });
1847
1888
  }
1848
1889
  }
1890
+ async getAccessToken(options) {
1891
+ const user = await this.getUser({ tokenStore: options?.tokenStore ?? void 0 });
1892
+ if (user) {
1893
+ return await user.getAccessToken();
1894
+ }
1895
+ return null;
1896
+ }
1897
+ async getRefreshToken(options) {
1898
+ const user = await this.getUser({ tokenStore: options?.tokenStore ?? void 0 });
1899
+ if (user) {
1900
+ return await user.getRefreshToken();
1901
+ }
1902
+ return null;
1903
+ }
1849
1904
  async getAuthHeaders(options) {
1850
1905
  return {
1851
1906
  "x-stack-auth": JSON.stringify(await this.getAuthJson(options))
@@ -1882,6 +1937,7 @@ ${url}`);
1882
1937
  }
1883
1938
  async _refreshUser(session) {
1884
1939
  await this._refreshSession(session);
1940
+ session.suggestAccessTokenExpired();
1885
1941
  }
1886
1942
  async _refreshSession(session) {
1887
1943
  await this._currentUserCache.refresh([session]);