@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
@@ -23,7 +23,7 @@ import { constructRedirectUrl } from "../utils/url";
23
23
  import { addNewOAuthProviderOrScope, callOAuthCallback, signInWithOAuth } from "./auth";
24
24
  import { deleteCookie, getCookie, setOrDeleteCookie } from "./cookie";
25
25
  var NextNavigation = scrambleDuringCompileTime(NextNavigationUnscrambled);
26
- var clientVersion = "js @stackframe/stack@2.5.11";
26
+ var clientVersion = "js @stackframe/stack@2.5.13";
27
27
  function getUrls(partial) {
28
28
  const handler = partial.handler ?? "/handler";
29
29
  const home = partial.home ?? "/";
@@ -150,12 +150,10 @@ var _StackClientAppImpl = class __StackClientAppImpl {
150
150
  return await this._interface.listCurrentUserTeams(session);
151
151
  });
152
152
  this._currentUserOAuthConnectionAccessTokensCache = createCacheBySession(
153
- async (session, [accountId, scope]) => {
153
+ async (session, [providerId, scope]) => {
154
154
  try {
155
- const result = await this._interface.createProviderAccessToken(accountId, scope || "", session);
156
- return {
157
- accessToken: result.access_token
158
- };
155
+ const result = await this._interface.createProviderAccessToken(providerId, scope || "", session);
156
+ return { accessToken: result.access_token };
159
157
  } catch (err) {
160
158
  if (!(err instanceof KnownErrors.OAuthConnectionDoesNotHaveRequiredScope || err instanceof KnownErrors.OAuthConnectionNotConnectedToUser)) {
161
159
  throw err;
@@ -165,49 +163,16 @@ var _StackClientAppImpl = class __StackClientAppImpl {
165
163
  }
166
164
  );
167
165
  this._currentUserOAuthConnectionCache = createCacheBySession(
168
- async (session, [connectionId, scope, redirect]) => {
169
- const user = await this._currentUserCache.getOrWait([session], "write-only");
170
- let hasConnection = true;
171
- if (!user || !user.oauth_providers.find((p) => p.id === connectionId)) {
172
- hasConnection = false;
173
- }
174
- const token = await this._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
175
- if (!token) {
176
- hasConnection = false;
177
- }
178
- if (!hasConnection && redirect) {
179
- await addNewOAuthProviderOrScope(
180
- this._interface,
181
- {
182
- provider: connectionId,
183
- redirectUrl: this.urls.oauthCallback,
184
- errorRedirectUrl: this.urls.error,
185
- providerScope: mergeScopeStrings(scope || "", (this._oauthScopesOnSignIn[connectionId] ?? []).join(" "))
186
- },
187
- session
188
- );
189
- return await neverResolve();
190
- } else if (!hasConnection) {
191
- return null;
192
- }
193
- const app = this;
194
- return {
195
- id: connectionId,
196
- async getAccessToken() {
197
- const result = await app._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
198
- if (!result) {
199
- throw new StackAssertionError("No access token available");
200
- }
201
- return result;
202
- },
203
- useAccessToken() {
204
- const result = useAsyncCache(app._currentUserOAuthConnectionAccessTokensCache, [session, connectionId, scope || ""], "oauthAccount.useAccessToken()");
205
- if (!result) {
206
- throw new StackAssertionError("No access token available");
207
- }
208
- return result;
209
- }
210
- };
166
+ async (session, [providerId, scope, redirect]) => {
167
+ return await this._getUserOAuthConnectionCacheFn({
168
+ getUser: async () => await this._currentUserCache.getOrWait([session], "write-only"),
169
+ getOrWaitOAuthToken: async () => await this._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, providerId, scope || ""], "write-only"),
170
+ useOAuthToken: () => useAsyncCache(this._currentUserOAuthConnectionAccessTokensCache, [session, providerId, scope || ""], "useOAuthToken"),
171
+ providerId,
172
+ scope,
173
+ redirect,
174
+ session
175
+ });
211
176
  }
212
177
  );
213
178
  this._memoryTokenStore = createEmptyTokenStore();
@@ -246,6 +211,53 @@ var _StackClientAppImpl = class __StackClientAppImpl {
246
211
  }
247
212
  }
248
213
  }
214
+ async _getUserOAuthConnectionCacheFn(options) {
215
+ const user = await options.getUser();
216
+ let hasConnection = true;
217
+ if (!user || !user.oauth_providers.find((p) => p.id === options.providerId)) {
218
+ hasConnection = false;
219
+ }
220
+ const token = await options.getOrWaitOAuthToken();
221
+ if (!token) {
222
+ hasConnection = false;
223
+ }
224
+ if (!hasConnection && options.redirect) {
225
+ if (!options.session) {
226
+ throw new Error("No session found. You might be calling getConnectedAccount with redirect without having a user session.");
227
+ }
228
+ await addNewOAuthProviderOrScope(
229
+ this._interface,
230
+ {
231
+ provider: options.providerId,
232
+ redirectUrl: this.urls.oauthCallback,
233
+ errorRedirectUrl: this.urls.error,
234
+ providerScope: mergeScopeStrings(options.scope || "", (this._oauthScopesOnSignIn[options.providerId] ?? []).join(" "))
235
+ },
236
+ options.session
237
+ );
238
+ return await neverResolve();
239
+ } else if (!hasConnection) {
240
+ return null;
241
+ }
242
+ const app = this;
243
+ return {
244
+ id: options.providerId,
245
+ async getAccessToken() {
246
+ const result = await options.getOrWaitOAuthToken();
247
+ if (!result) {
248
+ throw new StackAssertionError("No access token available");
249
+ }
250
+ return result;
251
+ },
252
+ useAccessToken() {
253
+ const result = options.useOAuthToken();
254
+ if (!result) {
255
+ throw new StackAssertionError("No access token available");
256
+ }
257
+ return result;
258
+ }
259
+ };
260
+ }
249
261
  _initUniqueIdentifier() {
250
262
  if (!this._uniqueIdentifier) {
251
263
  throw new StackAssertionError("Unique identifier not initialized");
@@ -672,31 +684,33 @@ var _StackClientAppImpl = class __StackClientAppImpl {
672
684
  if (!url) {
673
685
  throw new Error(`No URL for handler name ${handlerName}`);
674
686
  }
675
- if (handlerName === "afterSignIn" || handlerName === "afterSignUp") {
676
- if (isReactServer || typeof window === "undefined") {
677
- try {
678
- await this._checkFeatureSupport("rsc-handler-" + handlerName, {});
679
- } catch (e) {
680
- }
681
- } else {
682
- const queryParams = new URLSearchParams(window.location.search);
683
- url = queryParams.get("after_auth_return_to") || url;
684
- }
685
- } else if (handlerName === "signIn" || handlerName === "signUp") {
686
- if (isReactServer || typeof window === "undefined") {
687
- try {
688
- await this._checkFeatureSupport("rsc-handler-" + handlerName, {});
689
- } catch (e) {
687
+ if (!options?.noRedirectBack) {
688
+ if (handlerName === "afterSignIn" || handlerName === "afterSignUp") {
689
+ if (isReactServer || typeof window === "undefined") {
690
+ try {
691
+ await this._checkFeatureSupport("rsc-handler-" + handlerName, {});
692
+ } catch (e) {
693
+ }
694
+ } else {
695
+ const queryParams = new URLSearchParams(window.location.search);
696
+ url = queryParams.get("after_auth_return_to") || url;
690
697
  }
691
- } else {
692
- const currentUrl = new URL(window.location.href);
693
- const nextUrl = new URL(url, currentUrl);
694
- if (currentUrl.searchParams.has("after_auth_return_to")) {
695
- nextUrl.searchParams.set("after_auth_return_to", currentUrl.searchParams.get("after_auth_return_to"));
696
- } else if (currentUrl.protocol === nextUrl.protocol && currentUrl.host === nextUrl.host) {
697
- nextUrl.searchParams.set("after_auth_return_to", getRelativePart(currentUrl));
698
+ } else if (handlerName === "signIn" || handlerName === "signUp") {
699
+ if (isReactServer || typeof window === "undefined") {
700
+ try {
701
+ await this._checkFeatureSupport("rsc-handler-" + handlerName, {});
702
+ } catch (e) {
703
+ }
704
+ } else {
705
+ const currentUrl = new URL(window.location.href);
706
+ const nextUrl = new URL(url, currentUrl);
707
+ if (currentUrl.searchParams.has("after_auth_return_to")) {
708
+ nextUrl.searchParams.set("after_auth_return_to", currentUrl.searchParams.get("after_auth_return_to"));
709
+ } else if (currentUrl.protocol === nextUrl.protocol && currentUrl.host === nextUrl.host) {
710
+ nextUrl.searchParams.set("after_auth_return_to", getRelativePart(currentUrl));
711
+ }
712
+ url = getRelativePart(nextUrl);
698
713
  }
699
- url = getRelativePart(nextUrl);
700
714
  }
701
715
  }
702
716
  await this._redirectIfTrusted(url, options);
@@ -1019,11 +1033,8 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1019
1033
  const user = await this._interface.getServerUserById(userId);
1020
1034
  return Result.or(user, null);
1021
1035
  });
1022
- this._serverTeamsCache = createCache(async () => {
1023
- return await this._interface.listServerTeams();
1024
- });
1025
- this._serverCurrentUserTeamsCache = createCacheBySession(async (session) => {
1026
- return await this._interface.listServerCurrentUserTeams(session);
1036
+ this._serverTeamsCache = createCache(async ([userId]) => {
1037
+ return await this._interface.listServerTeams({ userId });
1027
1038
  });
1028
1039
  this._serverTeamUsersCache = createCache(async ([teamId]) => {
1029
1040
  return await this._interface.listServerTeamUsers(teamId);
@@ -1031,6 +1042,32 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1031
1042
  this._serverTeamUserPermissionsCache = createCache(async ([teamId, userId, recursive]) => {
1032
1043
  return await this._interface.listServerTeamMemberPermissions({ teamId, userId, recursive });
1033
1044
  });
1045
+ this._serverUserOAuthConnectionAccessTokensCache = createCache(
1046
+ async ([userId, providerId, scope]) => {
1047
+ try {
1048
+ const result = await this._interface.createServerProviderAccessToken(userId, providerId, scope || "");
1049
+ return { accessToken: result.access_token };
1050
+ } catch (err) {
1051
+ if (!(err instanceof KnownErrors.OAuthConnectionDoesNotHaveRequiredScope || err instanceof KnownErrors.OAuthConnectionNotConnectedToUser)) {
1052
+ throw err;
1053
+ }
1054
+ }
1055
+ return null;
1056
+ }
1057
+ );
1058
+ this._serverUserOAuthConnectionCache = createCache(
1059
+ async ([userId, providerId, scope, redirect]) => {
1060
+ return await this._getUserOAuthConnectionCacheFn({
1061
+ getUser: async () => await this._serverUserCache.getOrWait([userId], "write-only"),
1062
+ getOrWaitOAuthToken: async () => await this._serverUserOAuthConnectionAccessTokensCache.getOrWait([userId, providerId, scope || ""], "write-only"),
1063
+ useOAuthToken: () => useAsyncCache(this._serverUserOAuthConnectionAccessTokensCache, [userId, providerId, scope || ""], "user.useConnectedAccount()"),
1064
+ providerId,
1065
+ scope,
1066
+ redirect,
1067
+ session: null
1068
+ });
1069
+ }
1070
+ );
1034
1071
  }
1035
1072
  async _updateServerUser(userId, update) {
1036
1073
  const result = await this._interface.updateServerUser(userId, serverUserUpdateOptionsToCrud(update));
@@ -1039,6 +1076,14 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1039
1076
  }
1040
1077
  _serverUserFromCrud(crud) {
1041
1078
  const app = this;
1079
+ async function getConnectedAccount(id, options) {
1080
+ const scopeString = options?.scopes?.join(" ");
1081
+ return await app._serverUserOAuthConnectionCache.getOrWait([crud.id, id, scopeString || "", options?.or === "redirect"], "write-only");
1082
+ }
1083
+ function useConnectedAccount(id, options) {
1084
+ const scopeString = options?.scopes?.join(" ");
1085
+ return useAsyncCache(app._serverUserOAuthConnectionCache, [crud.id, id, scopeString || "", options?.or === "redirect"], "user.useConnectedAccount()");
1086
+ }
1042
1087
  return {
1043
1088
  ...super._createBaseUser(crud),
1044
1089
  serverMetadata: crud.server_metadata,
@@ -1082,29 +1127,29 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1082
1127
  async setSelectedTeam(team) {
1083
1128
  return await this.update({ selectedTeamId: team?.id ?? null });
1084
1129
  },
1085
- getConnectedAccount: async () => {
1086
- return await app._checkFeatureSupport("getConnectedAccount() on ServerUser", {});
1087
- },
1088
- useConnectedAccount: () => {
1089
- return app._useCheckFeatureSupport("useConnectedAccount() on ServerUser", {});
1090
- },
1130
+ getConnectedAccount,
1131
+ useConnectedAccount,
1091
1132
  async getTeam(teamId) {
1092
1133
  const teams = await this.listTeams();
1093
1134
  return teams.find((t) => t.id === teamId) ?? null;
1094
1135
  },
1095
1136
  useTeam(teamId) {
1096
- return app._useCheckFeatureSupport("useTeam() on ServerUser", {});
1137
+ const teams = this.useTeams();
1138
+ return useMemo(() => {
1139
+ return teams.find((t) => t.id === teamId) ?? null;
1140
+ }, [teams, teamId]);
1097
1141
  },
1098
1142
  async listTeams() {
1099
- const crud2 = await app._serverCurrentUserTeamsCache.getOrWait([app._getSession()], "write-only");
1100
- return crud2.map((t) => app._serverTeamFromCrud(t));
1143
+ const teams = await app._serverTeamsCache.getOrWait([crud.id], "write-only");
1144
+ return teams.map((t) => app._serverTeamFromCrud(t));
1101
1145
  },
1102
1146
  useTeams() {
1103
- return app._useCheckFeatureSupport("useTeams() on ServerUser", {});
1147
+ const teams = useAsyncCache(app._serverTeamsCache, [crud.id], "user.useTeams()");
1148
+ return useMemo(() => teams.map((t) => app._serverTeamFromCrud(t)), [teams]);
1104
1149
  },
1105
1150
  createTeam: async (data) => {
1106
1151
  const team = await app._interface.createServerTeam(serverTeamCreateOptionsToCrud(data), app._getSession());
1107
- await app._serverTeamsCache.refresh([]);
1152
+ await app._serverTeamsCache.refresh([void 0]);
1108
1153
  return app._serverTeamFromCrud(team);
1109
1154
  },
1110
1155
  async listPermissions(scope, options) {
@@ -1161,11 +1206,11 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1161
1206
  },
1162
1207
  async update(update) {
1163
1208
  await app._interface.updateServerTeam(crud.id, serverTeamUpdateOptionsToCrud(update));
1164
- await app._serverTeamsCache.refresh([]);
1209
+ await app._serverTeamsCache.refresh([void 0]);
1165
1210
  },
1166
1211
  async delete() {
1167
1212
  await app._interface.deleteServerTeam(crud.id);
1168
- await app._serverTeamsCache.refresh([]);
1213
+ await app._serverTeamsCache.refresh([void 0]);
1169
1214
  },
1170
1215
  useUsers() {
1171
1216
  const result = useAsyncCache(app._serverTeamUsersCache, [crud.id], "team.useUsers()");
@@ -1268,16 +1313,16 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1268
1313
  };
1269
1314
  }
1270
1315
  async listTeams() {
1271
- const teams = await this._serverTeamsCache.getOrWait([], "write-only");
1316
+ const teams = await this._serverTeamsCache.getOrWait([void 0], "write-only");
1272
1317
  return teams.map((t) => this._serverTeamFromCrud(t));
1273
1318
  }
1274
1319
  async createTeam(data) {
1275
1320
  const team = await this._interface.createServerTeam(serverTeamCreateOptionsToCrud(data));
1276
- await this._serverTeamsCache.refresh([]);
1321
+ await this._serverTeamsCache.refresh([void 0]);
1277
1322
  return this._serverTeamFromCrud(team);
1278
1323
  }
1279
1324
  useTeams() {
1280
- const teams = useAsyncCache(this._serverTeamsCache, [], "useServerTeams()");
1325
+ const teams = useAsyncCache(this._serverTeamsCache, [void 0], "useServerTeams()");
1281
1326
  return useMemo(() => {
1282
1327
  return teams.map((t) => this._serverTeamFromCrud(t));
1283
1328
  }, [teams]);