@stackframe/stack 2.5.11 → 2.5.13

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 (44) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/components/message-cards/message-card.js +3 -3
  3. package/dist/components/message-cards/message-card.js.map +1 -1
  4. package/dist/components/message-cards/predefined-message-card.js +3 -3
  5. package/dist/components/message-cards/predefined-message-card.js.map +1 -1
  6. package/dist/components-page/auth-page.d.mts +2 -1
  7. package/dist/components-page/auth-page.d.ts +2 -1
  8. package/dist/components-page/auth-page.js +7 -4
  9. package/dist/components-page/auth-page.js.map +1 -1
  10. package/dist/components-page/oauth-callback.js +3 -1
  11. package/dist/components-page/oauth-callback.js.map +1 -1
  12. package/dist/components-page/stack-handler.js +3 -4
  13. package/dist/components-page/stack-handler.js.map +1 -1
  14. package/dist/esm/components/message-cards/message-card.js +3 -3
  15. package/dist/esm/components/message-cards/message-card.js.map +1 -1
  16. package/dist/esm/components/message-cards/predefined-message-card.js +3 -3
  17. package/dist/esm/components/message-cards/predefined-message-card.js.map +1 -1
  18. package/dist/esm/components-page/auth-page.js +7 -4
  19. package/dist/esm/components-page/auth-page.js.map +1 -1
  20. package/dist/esm/components-page/oauth-callback.js +3 -1
  21. package/dist/esm/components-page/oauth-callback.js.map +1 -1
  22. package/dist/esm/components-page/stack-handler.js +3 -4
  23. package/dist/esm/components-page/stack-handler.js.map +1 -1
  24. package/dist/esm/generated/global-css.js +1 -1
  25. package/dist/esm/generated/global-css.js.map +1 -1
  26. package/dist/esm/lib/auth.js +3 -1
  27. package/dist/esm/lib/auth.js.map +1 -1
  28. package/dist/esm/lib/stack-app.js +138 -93
  29. package/dist/esm/lib/stack-app.js.map +1 -1
  30. package/dist/esm/utils/browser-script.js +41 -13
  31. package/dist/esm/utils/browser-script.js.map +1 -1
  32. package/dist/generated/global-css.d.mts +1 -1
  33. package/dist/generated/global-css.d.ts +1 -1
  34. package/dist/generated/global-css.js +1 -1
  35. package/dist/generated/global-css.js.map +1 -1
  36. package/dist/lib/auth.js +2 -0
  37. package/dist/lib/auth.js.map +1 -1
  38. package/dist/lib/stack-app.d.mts +1 -0
  39. package/dist/lib/stack-app.d.ts +1 -0
  40. package/dist/lib/stack-app.js +138 -93
  41. package/dist/lib/stack-app.js.map +1 -1
  42. package/dist/utils/browser-script.js +41 -13
  43. package/dist/utils/browser-script.js.map +1 -1
  44. package/package.json +4 -4
@@ -62,7 +62,7 @@ var import_url = require("../utils/url");
62
62
  var import_auth = require("./auth");
63
63
  var import_cookie = require("./cookie");
64
64
  var NextNavigation = (0, import_compile_time.scrambleDuringCompileTime)(NextNavigationUnscrambled);
65
- var clientVersion = "js @stackframe/stack@2.5.11";
65
+ var clientVersion = "js @stackframe/stack@2.5.13";
66
66
  function getUrls(partial) {
67
67
  const handler = partial.handler ?? "/handler";
68
68
  const home = partial.home ?? "/";
@@ -189,12 +189,10 @@ var _StackClientAppImpl = class __StackClientAppImpl {
189
189
  return await this._interface.listCurrentUserTeams(session);
190
190
  });
191
191
  this._currentUserOAuthConnectionAccessTokensCache = createCacheBySession(
192
- async (session, [accountId, scope]) => {
192
+ async (session, [providerId, scope]) => {
193
193
  try {
194
- const result = await this._interface.createProviderAccessToken(accountId, scope || "", session);
195
- return {
196
- accessToken: result.access_token
197
- };
194
+ const result = await this._interface.createProviderAccessToken(providerId, scope || "", session);
195
+ return { accessToken: result.access_token };
198
196
  } catch (err) {
199
197
  if (!(err instanceof import_stack_shared.KnownErrors.OAuthConnectionDoesNotHaveRequiredScope || err instanceof import_stack_shared.KnownErrors.OAuthConnectionNotConnectedToUser)) {
200
198
  throw err;
@@ -204,49 +202,16 @@ var _StackClientAppImpl = class __StackClientAppImpl {
204
202
  }
205
203
  );
206
204
  this._currentUserOAuthConnectionCache = createCacheBySession(
207
- async (session, [connectionId, scope, redirect]) => {
208
- const user = await this._currentUserCache.getOrWait([session], "write-only");
209
- let hasConnection = true;
210
- if (!user || !user.oauth_providers.find((p) => p.id === connectionId)) {
211
- hasConnection = false;
212
- }
213
- const token = await this._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
214
- if (!token) {
215
- hasConnection = false;
216
- }
217
- if (!hasConnection && redirect) {
218
- await (0, import_auth.addNewOAuthProviderOrScope)(
219
- this._interface,
220
- {
221
- provider: connectionId,
222
- redirectUrl: this.urls.oauthCallback,
223
- errorRedirectUrl: this.urls.error,
224
- providerScope: (0, import_strings.mergeScopeStrings)(scope || "", (this._oauthScopesOnSignIn[connectionId] ?? []).join(" "))
225
- },
226
- session
227
- );
228
- return await (0, import_promises.neverResolve)();
229
- } else if (!hasConnection) {
230
- return null;
231
- }
232
- const app = this;
233
- return {
234
- id: connectionId,
235
- async getAccessToken() {
236
- const result = await app._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
237
- if (!result) {
238
- throw new import_errors.StackAssertionError("No access token available");
239
- }
240
- return result;
241
- },
242
- useAccessToken() {
243
- const result = useAsyncCache(app._currentUserOAuthConnectionAccessTokensCache, [session, connectionId, scope || ""], "oauthAccount.useAccessToken()");
244
- if (!result) {
245
- throw new import_errors.StackAssertionError("No access token available");
246
- }
247
- return result;
248
- }
249
- };
205
+ async (session, [providerId, scope, redirect]) => {
206
+ return await this._getUserOAuthConnectionCacheFn({
207
+ getUser: async () => await this._currentUserCache.getOrWait([session], "write-only"),
208
+ getOrWaitOAuthToken: async () => await this._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, providerId, scope || ""], "write-only"),
209
+ useOAuthToken: () => useAsyncCache(this._currentUserOAuthConnectionAccessTokensCache, [session, providerId, scope || ""], "useOAuthToken"),
210
+ providerId,
211
+ scope,
212
+ redirect,
213
+ session
214
+ });
250
215
  }
251
216
  );
252
217
  this._memoryTokenStore = createEmptyTokenStore();
@@ -285,6 +250,53 @@ var _StackClientAppImpl = class __StackClientAppImpl {
285
250
  }
286
251
  }
287
252
  }
253
+ async _getUserOAuthConnectionCacheFn(options) {
254
+ const user = await options.getUser();
255
+ let hasConnection = true;
256
+ if (!user || !user.oauth_providers.find((p) => p.id === options.providerId)) {
257
+ hasConnection = false;
258
+ }
259
+ const token = await options.getOrWaitOAuthToken();
260
+ if (!token) {
261
+ hasConnection = false;
262
+ }
263
+ if (!hasConnection && options.redirect) {
264
+ if (!options.session) {
265
+ throw new Error("No session found. You might be calling getConnectedAccount with redirect without having a user session.");
266
+ }
267
+ await (0, import_auth.addNewOAuthProviderOrScope)(
268
+ this._interface,
269
+ {
270
+ provider: options.providerId,
271
+ redirectUrl: this.urls.oauthCallback,
272
+ errorRedirectUrl: this.urls.error,
273
+ providerScope: (0, import_strings.mergeScopeStrings)(options.scope || "", (this._oauthScopesOnSignIn[options.providerId] ?? []).join(" "))
274
+ },
275
+ options.session
276
+ );
277
+ return await (0, import_promises.neverResolve)();
278
+ } else if (!hasConnection) {
279
+ return null;
280
+ }
281
+ const app = this;
282
+ return {
283
+ id: options.providerId,
284
+ async getAccessToken() {
285
+ const result = await options.getOrWaitOAuthToken();
286
+ if (!result) {
287
+ throw new import_errors.StackAssertionError("No access token available");
288
+ }
289
+ return result;
290
+ },
291
+ useAccessToken() {
292
+ const result = options.useOAuthToken();
293
+ if (!result) {
294
+ throw new import_errors.StackAssertionError("No access token available");
295
+ }
296
+ return result;
297
+ }
298
+ };
299
+ }
288
300
  _initUniqueIdentifier() {
289
301
  if (!this._uniqueIdentifier) {
290
302
  throw new import_errors.StackAssertionError("Unique identifier not initialized");
@@ -711,31 +723,33 @@ var _StackClientAppImpl = class __StackClientAppImpl {
711
723
  if (!url) {
712
724
  throw new Error(`No URL for handler name ${handlerName}`);
713
725
  }
714
- if (handlerName === "afterSignIn" || handlerName === "afterSignUp") {
715
- if (import_stack_sc.isReactServer || typeof window === "undefined") {
716
- try {
717
- await this._checkFeatureSupport("rsc-handler-" + handlerName, {});
718
- } catch (e) {
719
- }
720
- } else {
721
- const queryParams = new URLSearchParams(window.location.search);
722
- url = queryParams.get("after_auth_return_to") || url;
723
- }
724
- } else if (handlerName === "signIn" || handlerName === "signUp") {
725
- if (import_stack_sc.isReactServer || typeof window === "undefined") {
726
- try {
727
- await this._checkFeatureSupport("rsc-handler-" + handlerName, {});
728
- } catch (e) {
726
+ if (!options?.noRedirectBack) {
727
+ if (handlerName === "afterSignIn" || handlerName === "afterSignUp") {
728
+ if (import_stack_sc.isReactServer || typeof window === "undefined") {
729
+ try {
730
+ await this._checkFeatureSupport("rsc-handler-" + handlerName, {});
731
+ } catch (e) {
732
+ }
733
+ } else {
734
+ const queryParams = new URLSearchParams(window.location.search);
735
+ url = queryParams.get("after_auth_return_to") || url;
729
736
  }
730
- } else {
731
- const currentUrl = new URL(window.location.href);
732
- const nextUrl = new URL(url, currentUrl);
733
- if (currentUrl.searchParams.has("after_auth_return_to")) {
734
- nextUrl.searchParams.set("after_auth_return_to", currentUrl.searchParams.get("after_auth_return_to"));
735
- } else if (currentUrl.protocol === nextUrl.protocol && currentUrl.host === nextUrl.host) {
736
- nextUrl.searchParams.set("after_auth_return_to", (0, import_urls.getRelativePart)(currentUrl));
737
+ } else if (handlerName === "signIn" || handlerName === "signUp") {
738
+ if (import_stack_sc.isReactServer || typeof window === "undefined") {
739
+ try {
740
+ await this._checkFeatureSupport("rsc-handler-" + handlerName, {});
741
+ } catch (e) {
742
+ }
743
+ } else {
744
+ const currentUrl = new URL(window.location.href);
745
+ const nextUrl = new URL(url, currentUrl);
746
+ if (currentUrl.searchParams.has("after_auth_return_to")) {
747
+ nextUrl.searchParams.set("after_auth_return_to", currentUrl.searchParams.get("after_auth_return_to"));
748
+ } else if (currentUrl.protocol === nextUrl.protocol && currentUrl.host === nextUrl.host) {
749
+ nextUrl.searchParams.set("after_auth_return_to", (0, import_urls.getRelativePart)(currentUrl));
750
+ }
751
+ url = (0, import_urls.getRelativePart)(nextUrl);
737
752
  }
738
- url = (0, import_urls.getRelativePart)(nextUrl);
739
753
  }
740
754
  }
741
755
  await this._redirectIfTrusted(url, options);
@@ -1058,11 +1072,8 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1058
1072
  const user = await this._interface.getServerUserById(userId);
1059
1073
  return import_results.Result.or(user, null);
1060
1074
  });
1061
- this._serverTeamsCache = createCache(async () => {
1062
- return await this._interface.listServerTeams();
1063
- });
1064
- this._serverCurrentUserTeamsCache = createCacheBySession(async (session) => {
1065
- return await this._interface.listServerCurrentUserTeams(session);
1075
+ this._serverTeamsCache = createCache(async ([userId]) => {
1076
+ return await this._interface.listServerTeams({ userId });
1066
1077
  });
1067
1078
  this._serverTeamUsersCache = createCache(async ([teamId]) => {
1068
1079
  return await this._interface.listServerTeamUsers(teamId);
@@ -1070,6 +1081,32 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1070
1081
  this._serverTeamUserPermissionsCache = createCache(async ([teamId, userId, recursive]) => {
1071
1082
  return await this._interface.listServerTeamMemberPermissions({ teamId, userId, recursive });
1072
1083
  });
1084
+ this._serverUserOAuthConnectionAccessTokensCache = createCache(
1085
+ async ([userId, providerId, scope]) => {
1086
+ try {
1087
+ const result = await this._interface.createServerProviderAccessToken(userId, providerId, scope || "");
1088
+ return { accessToken: result.access_token };
1089
+ } catch (err) {
1090
+ if (!(err instanceof import_stack_shared.KnownErrors.OAuthConnectionDoesNotHaveRequiredScope || err instanceof import_stack_shared.KnownErrors.OAuthConnectionNotConnectedToUser)) {
1091
+ throw err;
1092
+ }
1093
+ }
1094
+ return null;
1095
+ }
1096
+ );
1097
+ this._serverUserOAuthConnectionCache = createCache(
1098
+ async ([userId, providerId, scope, redirect]) => {
1099
+ return await this._getUserOAuthConnectionCacheFn({
1100
+ getUser: async () => await this._serverUserCache.getOrWait([userId], "write-only"),
1101
+ getOrWaitOAuthToken: async () => await this._serverUserOAuthConnectionAccessTokensCache.getOrWait([userId, providerId, scope || ""], "write-only"),
1102
+ useOAuthToken: () => useAsyncCache(this._serverUserOAuthConnectionAccessTokensCache, [userId, providerId, scope || ""], "user.useConnectedAccount()"),
1103
+ providerId,
1104
+ scope,
1105
+ redirect,
1106
+ session: null
1107
+ });
1108
+ }
1109
+ );
1073
1110
  }
1074
1111
  async _updateServerUser(userId, update) {
1075
1112
  const result = await this._interface.updateServerUser(userId, serverUserUpdateOptionsToCrud(update));
@@ -1078,6 +1115,14 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1078
1115
  }
1079
1116
  _serverUserFromCrud(crud) {
1080
1117
  const app = this;
1118
+ async function getConnectedAccount(id, options) {
1119
+ const scopeString = options?.scopes?.join(" ");
1120
+ return await app._serverUserOAuthConnectionCache.getOrWait([crud.id, id, scopeString || "", options?.or === "redirect"], "write-only");
1121
+ }
1122
+ function useConnectedAccount(id, options) {
1123
+ const scopeString = options?.scopes?.join(" ");
1124
+ return useAsyncCache(app._serverUserOAuthConnectionCache, [crud.id, id, scopeString || "", options?.or === "redirect"], "user.useConnectedAccount()");
1125
+ }
1081
1126
  return {
1082
1127
  ...super._createBaseUser(crud),
1083
1128
  serverMetadata: crud.server_metadata,
@@ -1121,29 +1166,29 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1121
1166
  async setSelectedTeam(team) {
1122
1167
  return await this.update({ selectedTeamId: team?.id ?? null });
1123
1168
  },
1124
- getConnectedAccount: async () => {
1125
- return await app._checkFeatureSupport("getConnectedAccount() on ServerUser", {});
1126
- },
1127
- useConnectedAccount: () => {
1128
- return app._useCheckFeatureSupport("useConnectedAccount() on ServerUser", {});
1129
- },
1169
+ getConnectedAccount,
1170
+ useConnectedAccount,
1130
1171
  async getTeam(teamId) {
1131
1172
  const teams = await this.listTeams();
1132
1173
  return teams.find((t) => t.id === teamId) ?? null;
1133
1174
  },
1134
1175
  useTeam(teamId) {
1135
- return app._useCheckFeatureSupport("useTeam() on ServerUser", {});
1176
+ const teams = this.useTeams();
1177
+ return (0, import_react2.useMemo)(() => {
1178
+ return teams.find((t) => t.id === teamId) ?? null;
1179
+ }, [teams, teamId]);
1136
1180
  },
1137
1181
  async listTeams() {
1138
- const crud2 = await app._serverCurrentUserTeamsCache.getOrWait([app._getSession()], "write-only");
1139
- return crud2.map((t) => app._serverTeamFromCrud(t));
1182
+ const teams = await app._serverTeamsCache.getOrWait([crud.id], "write-only");
1183
+ return teams.map((t) => app._serverTeamFromCrud(t));
1140
1184
  },
1141
1185
  useTeams() {
1142
- return app._useCheckFeatureSupport("useTeams() on ServerUser", {});
1186
+ const teams = useAsyncCache(app._serverTeamsCache, [crud.id], "user.useTeams()");
1187
+ return (0, import_react2.useMemo)(() => teams.map((t) => app._serverTeamFromCrud(t)), [teams]);
1143
1188
  },
1144
1189
  createTeam: async (data) => {
1145
1190
  const team = await app._interface.createServerTeam(serverTeamCreateOptionsToCrud(data), app._getSession());
1146
- await app._serverTeamsCache.refresh([]);
1191
+ await app._serverTeamsCache.refresh([void 0]);
1147
1192
  return app._serverTeamFromCrud(team);
1148
1193
  },
1149
1194
  async listPermissions(scope, options) {
@@ -1200,11 +1245,11 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1200
1245
  },
1201
1246
  async update(update) {
1202
1247
  await app._interface.updateServerTeam(crud.id, serverTeamUpdateOptionsToCrud(update));
1203
- await app._serverTeamsCache.refresh([]);
1248
+ await app._serverTeamsCache.refresh([void 0]);
1204
1249
  },
1205
1250
  async delete() {
1206
1251
  await app._interface.deleteServerTeam(crud.id);
1207
- await app._serverTeamsCache.refresh([]);
1252
+ await app._serverTeamsCache.refresh([void 0]);
1208
1253
  },
1209
1254
  useUsers() {
1210
1255
  const result = useAsyncCache(app._serverTeamUsersCache, [crud.id], "team.useUsers()");
@@ -1307,16 +1352,16 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1307
1352
  };
1308
1353
  }
1309
1354
  async listTeams() {
1310
- const teams = await this._serverTeamsCache.getOrWait([], "write-only");
1355
+ const teams = await this._serverTeamsCache.getOrWait([void 0], "write-only");
1311
1356
  return teams.map((t) => this._serverTeamFromCrud(t));
1312
1357
  }
1313
1358
  async createTeam(data) {
1314
1359
  const team = await this._interface.createServerTeam(serverTeamCreateOptionsToCrud(data));
1315
- await this._serverTeamsCache.refresh([]);
1360
+ await this._serverTeamsCache.refresh([void 0]);
1316
1361
  return this._serverTeamFromCrud(team);
1317
1362
  }
1318
1363
  useTeams() {
1319
- const teams = useAsyncCache(this._serverTeamsCache, [], "useServerTeams()");
1364
+ const teams = useAsyncCache(this._serverTeamsCache, [void 0], "useServerTeams()");
1320
1365
  return (0, import_react2.useMemo)(() => {
1321
1366
  return teams.map((t) => this._serverTeamFromCrud(t));
1322
1367
  }, [teams]);