@stackframe/stack 2.5.2 → 2.5.3
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.
- package/CHANGELOG.md +10 -0
- package/dist/esm/lib/stack-app.js +125 -129
- package/dist/esm/lib/stack-app.js.map +1 -1
- package/dist/lib/stack-app.js +125 -129
- package/dist/lib/stack-app.js.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -22,7 +22,7 @@ import * as cookie from "cookie";
|
|
|
22
22
|
import { InternalSession } from "@stackframe/stack-shared/dist/sessions";
|
|
23
23
|
import { mergeScopeStrings } from "@stackframe/stack-shared/dist/utils/strings";
|
|
24
24
|
var NextNavigation = scrambleDuringCompileTime(NextNavigationUnscrambled);
|
|
25
|
-
var clientVersion = "js @stackframe/stack@2.5.
|
|
25
|
+
var clientVersion = "js @stackframe/stack@2.5.3";
|
|
26
26
|
function permissionDefinitionScopeToType(scope) {
|
|
27
27
|
return { "any-team": "team", "specific-team": "team", "global": "global" }[scope.type];
|
|
28
28
|
}
|
|
@@ -128,6 +128,97 @@ var numberOfAppsCreated = 0;
|
|
|
128
128
|
var _StackClientAppImpl = class __StackClientAppImpl {
|
|
129
129
|
constructor(_options) {
|
|
130
130
|
this._options = _options;
|
|
131
|
+
this._uniqueIdentifier = void 0;
|
|
132
|
+
this.__DEMO_ENABLE_SLIGHT_FETCH_DELAY = false;
|
|
133
|
+
this._currentUserCache = createCacheBySession(async (session) => {
|
|
134
|
+
if (this.__DEMO_ENABLE_SLIGHT_FETCH_DELAY) {
|
|
135
|
+
await wait(2e3);
|
|
136
|
+
}
|
|
137
|
+
const user = await this._interface.getClientUserByToken(session);
|
|
138
|
+
return Result.or(user, null);
|
|
139
|
+
});
|
|
140
|
+
this._currentProjectCache = createCache(async () => {
|
|
141
|
+
return Result.orThrow(await this._interface.getClientProject());
|
|
142
|
+
});
|
|
143
|
+
this._ownedProjectsCache = createCacheBySession(async (session) => {
|
|
144
|
+
return await this._interface.listProjects(session);
|
|
145
|
+
});
|
|
146
|
+
this._currentUserPermissionsCache = createCacheBySession(async (session, [teamId, type, direct]) => {
|
|
147
|
+
return await this._interface.listClientUserTeamPermissions({ teamId, type, direct }, session);
|
|
148
|
+
});
|
|
149
|
+
this._currentUserTeamsCache = createCacheBySession(async (session) => {
|
|
150
|
+
return await this._interface.listClientUserTeams(session);
|
|
151
|
+
});
|
|
152
|
+
this._currentUserOAuthConnectionAccessTokensCache = createCacheBySession(
|
|
153
|
+
async (session, [accountId, scope]) => {
|
|
154
|
+
try {
|
|
155
|
+
return await this._interface.getAccessToken(accountId, scope || "", session);
|
|
156
|
+
} catch (err) {
|
|
157
|
+
if (!(err instanceof KnownErrors.OAuthConnectionDoesNotHaveRequiredScope || err instanceof KnownErrors.OAuthConnectionNotConnectedToUser)) {
|
|
158
|
+
throw err;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
this._currentUserOAuthConnectionCache = createCacheBySession(
|
|
165
|
+
async (session, [connectionId, scope, redirect]) => {
|
|
166
|
+
const user = await this._currentUserCache.getOrWait([session], "write-only");
|
|
167
|
+
let hasConnection = true;
|
|
168
|
+
if (!user || !user.oauthProviders.find((p) => p === connectionId)) {
|
|
169
|
+
hasConnection = false;
|
|
170
|
+
}
|
|
171
|
+
const token = await this._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
|
|
172
|
+
if (!token) {
|
|
173
|
+
hasConnection = false;
|
|
174
|
+
}
|
|
175
|
+
if (!hasConnection && redirect) {
|
|
176
|
+
await addNewOAuthProviderOrScope(
|
|
177
|
+
this._interface,
|
|
178
|
+
{
|
|
179
|
+
provider: connectionId,
|
|
180
|
+
redirectUrl: this.urls.oauthCallback,
|
|
181
|
+
errorRedirectUrl: this.urls.error,
|
|
182
|
+
providerScope: mergeScopeStrings(scope || "", (this._oauthScopesOnSignIn[connectionId] ?? []).join(" "))
|
|
183
|
+
},
|
|
184
|
+
session
|
|
185
|
+
);
|
|
186
|
+
return await neverResolve();
|
|
187
|
+
} else if (!hasConnection) {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
const app = this;
|
|
191
|
+
return {
|
|
192
|
+
id: connectionId,
|
|
193
|
+
async getAccessToken() {
|
|
194
|
+
const result = await app._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
|
|
195
|
+
if (!result) {
|
|
196
|
+
throw new StackAssertionError("No access token available");
|
|
197
|
+
}
|
|
198
|
+
return result;
|
|
199
|
+
},
|
|
200
|
+
useAccessToken() {
|
|
201
|
+
const result = useAsyncCache(app._currentUserOAuthConnectionAccessTokensCache, [session, connectionId, scope || ""], "oauthAccount.useAccessToken()");
|
|
202
|
+
if (!result) {
|
|
203
|
+
throw new StackAssertionError("No access token available");
|
|
204
|
+
}
|
|
205
|
+
return result;
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
);
|
|
210
|
+
this._memoryTokenStore = createEmptyTokenStore();
|
|
211
|
+
this._requestTokenStores = /* @__PURE__ */ new WeakMap();
|
|
212
|
+
this._storedCookieTokenStore = null;
|
|
213
|
+
/**
|
|
214
|
+
* A map from token stores and session keys to sessions.
|
|
215
|
+
*
|
|
216
|
+
* This isn't just a map from session keys to sessions for two reasons:
|
|
217
|
+
*
|
|
218
|
+
* - So we can garbage-collect Session objects when the token store is garbage-collected
|
|
219
|
+
* - So different token stores are separated and don't leak information between each other, eg. if the same user sends two requests to the same server they should get a different session object
|
|
220
|
+
*/
|
|
221
|
+
this._sessionsByTokenStoreAndSessionKey = /* @__PURE__ */ new WeakMap();
|
|
131
222
|
if ("interface" in _options) {
|
|
132
223
|
this._interface = _options.interface;
|
|
133
224
|
} else {
|
|
@@ -150,89 +241,6 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
150
241
|
(process.env.NODE_ENV === "development" ? console.log : console.warn)(`You have created more than 10 Stack apps (${numberOfAppsCreated}). This is usually a sign of a memory leak, but can sometimes be caused by hot reload of your tech stack. In production, make sure to minimize the number of Stack apps per page (usually, one per project).`);
|
|
151
242
|
}
|
|
152
243
|
}
|
|
153
|
-
_uniqueIdentifier = void 0;
|
|
154
|
-
_interface;
|
|
155
|
-
_tokenStoreInit;
|
|
156
|
-
_urlOptions;
|
|
157
|
-
_oauthScopesOnSignIn;
|
|
158
|
-
__DEMO_ENABLE_SLIGHT_FETCH_DELAY = false;
|
|
159
|
-
_currentUserCache = createCacheBySession(async (session) => {
|
|
160
|
-
if (this.__DEMO_ENABLE_SLIGHT_FETCH_DELAY) {
|
|
161
|
-
await wait(2e3);
|
|
162
|
-
}
|
|
163
|
-
const user = await this._interface.getClientUserByToken(session);
|
|
164
|
-
return Result.or(user, null);
|
|
165
|
-
});
|
|
166
|
-
_currentProjectCache = createCache(async () => {
|
|
167
|
-
return Result.orThrow(await this._interface.getClientProject());
|
|
168
|
-
});
|
|
169
|
-
_ownedProjectsCache = createCacheBySession(async (session) => {
|
|
170
|
-
return await this._interface.listProjects(session);
|
|
171
|
-
});
|
|
172
|
-
_currentUserPermissionsCache = createCacheBySession(async (session, [teamId, type, direct]) => {
|
|
173
|
-
return await this._interface.listClientUserTeamPermissions({ teamId, type, direct }, session);
|
|
174
|
-
});
|
|
175
|
-
_currentUserTeamsCache = createCacheBySession(async (session) => {
|
|
176
|
-
return await this._interface.listClientUserTeams(session);
|
|
177
|
-
});
|
|
178
|
-
_currentUserOAuthConnectionAccessTokensCache = createCacheBySession(
|
|
179
|
-
async (session, [accountId, scope]) => {
|
|
180
|
-
try {
|
|
181
|
-
return await this._interface.getAccessToken(accountId, scope || "", session);
|
|
182
|
-
} catch (err) {
|
|
183
|
-
if (!(err instanceof KnownErrors.OAuthConnectionDoesNotHaveRequiredScope || err instanceof KnownErrors.OAuthConnectionNotConnectedToUser)) {
|
|
184
|
-
throw err;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
return null;
|
|
188
|
-
}
|
|
189
|
-
);
|
|
190
|
-
_currentUserOAuthConnectionCache = createCacheBySession(
|
|
191
|
-
async (session, [connectionId, scope, redirect]) => {
|
|
192
|
-
const user = await this._currentUserCache.getOrWait([session], "write-only");
|
|
193
|
-
let hasConnection = true;
|
|
194
|
-
if (!user || !user.oauthProviders.find((p) => p === connectionId)) {
|
|
195
|
-
hasConnection = false;
|
|
196
|
-
}
|
|
197
|
-
const token = await this._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
|
|
198
|
-
if (!token) {
|
|
199
|
-
hasConnection = false;
|
|
200
|
-
}
|
|
201
|
-
if (!hasConnection && redirect) {
|
|
202
|
-
await addNewOAuthProviderOrScope(
|
|
203
|
-
this._interface,
|
|
204
|
-
{
|
|
205
|
-
provider: connectionId,
|
|
206
|
-
redirectUrl: this.urls.oauthCallback,
|
|
207
|
-
errorRedirectUrl: this.urls.error,
|
|
208
|
-
providerScope: mergeScopeStrings(scope || "", (this._oauthScopesOnSignIn[connectionId] ?? []).join(" "))
|
|
209
|
-
},
|
|
210
|
-
session
|
|
211
|
-
);
|
|
212
|
-
return await neverResolve();
|
|
213
|
-
} else if (!hasConnection) {
|
|
214
|
-
return null;
|
|
215
|
-
}
|
|
216
|
-
const app = this;
|
|
217
|
-
return {
|
|
218
|
-
id: connectionId,
|
|
219
|
-
async getAccessToken() {
|
|
220
|
-
const result = await app._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
|
|
221
|
-
if (!result) {
|
|
222
|
-
throw new StackAssertionError("No access token available");
|
|
223
|
-
}
|
|
224
|
-
return result;
|
|
225
|
-
},
|
|
226
|
-
useAccessToken() {
|
|
227
|
-
const result = useAsyncCache(app._currentUserOAuthConnectionAccessTokensCache, [session, connectionId, scope || ""], "oauthAccount.useAccessToken()");
|
|
228
|
-
if (!result) {
|
|
229
|
-
throw new StackAssertionError("No access token available");
|
|
230
|
-
}
|
|
231
|
-
return result;
|
|
232
|
-
}
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
);
|
|
236
244
|
_initUniqueIdentifier() {
|
|
237
245
|
if (!this._uniqueIdentifier) {
|
|
238
246
|
throw new StackAssertionError("Unique identifier not initialized");
|
|
@@ -260,9 +268,6 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
260
268
|
runAsynchronously(this._checkFeatureSupport(featureName, options));
|
|
261
269
|
throw new StackAssertionError(`${featureName} is not currently supported. Please reach out to Stack support for more information.`);
|
|
262
270
|
}
|
|
263
|
-
_memoryTokenStore = createEmptyTokenStore();
|
|
264
|
-
_requestTokenStores = /* @__PURE__ */ new WeakMap();
|
|
265
|
-
_storedCookieTokenStore = null;
|
|
266
271
|
get _refreshTokenCookieName() {
|
|
267
272
|
return `stack-refresh-${this.projectId}`;
|
|
268
273
|
}
|
|
@@ -390,15 +395,6 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
390
395
|
}
|
|
391
396
|
}
|
|
392
397
|
}
|
|
393
|
-
/**
|
|
394
|
-
* A map from token stores and session keys to sessions.
|
|
395
|
-
*
|
|
396
|
-
* This isn't just a map from session keys to sessions for two reasons:
|
|
397
|
-
*
|
|
398
|
-
* - So we can garbage-collect Session objects when the token store is garbage-collected
|
|
399
|
-
* - So different token stores are separated and don't leak information between each other, eg. if the same user sends two requests to the same server they should get a different session object
|
|
400
|
-
*/
|
|
401
|
-
_sessionsByTokenStoreAndSessionKey = /* @__PURE__ */ new WeakMap();
|
|
402
398
|
_getSessionFromTokenStore(tokenStore) {
|
|
403
399
|
const tokenObj = tokenStore.get();
|
|
404
400
|
const sessionKey = InternalSession.calculateSessionKey(tokenObj);
|
|
@@ -1003,33 +999,6 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
1003
999
|
}
|
|
1004
1000
|
};
|
|
1005
1001
|
var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
1006
|
-
// TODO override the client user cache to use the server user cache, so we save some requests
|
|
1007
|
-
_currentServerUserCache = createCacheBySession(async (session) => {
|
|
1008
|
-
const user = await this._interface.getServerUserByToken(session);
|
|
1009
|
-
return Result.or(user, null);
|
|
1010
|
-
});
|
|
1011
|
-
_serverUsersCache = createCache(async () => {
|
|
1012
|
-
return await this._interface.listServerUsers();
|
|
1013
|
-
});
|
|
1014
|
-
_serverUserCache = createCache(async ([userId]) => {
|
|
1015
|
-
const user = await this._interface.getServerUserById(userId);
|
|
1016
|
-
return Result.or(user, null);
|
|
1017
|
-
});
|
|
1018
|
-
_serverTeamsCache = createCache(async () => {
|
|
1019
|
-
return await this._interface.listServerTeams();
|
|
1020
|
-
});
|
|
1021
|
-
_serverTeamMembersCache = createCache(async ([teamId]) => {
|
|
1022
|
-
return await this._interface.listServerTeamMembers(teamId);
|
|
1023
|
-
});
|
|
1024
|
-
_serverTeamPermissionDefinitionsCache = createCache(async () => {
|
|
1025
|
-
return await this._interface.listPermissionDefinitions();
|
|
1026
|
-
});
|
|
1027
|
-
_serverTeamUserPermissionsCache = createCache(async ([teamId, userId, type, direct]) => {
|
|
1028
|
-
return await this._interface.listServerTeamMemberPermissions({ teamId, userId, type, direct });
|
|
1029
|
-
});
|
|
1030
|
-
_serverEmailTemplatesCache = createCache(async () => {
|
|
1031
|
-
return await this._interface.listEmailTemplates();
|
|
1032
|
-
});
|
|
1033
1002
|
constructor(options) {
|
|
1034
1003
|
super("interface" in options ? {
|
|
1035
1004
|
interface: options.interface,
|
|
@@ -1048,6 +1017,33 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
1048
1017
|
urls: options.urls ?? {},
|
|
1049
1018
|
oauthScopesOnSignIn: options.oauthScopesOnSignIn ?? {}
|
|
1050
1019
|
});
|
|
1020
|
+
// TODO override the client user cache to use the server user cache, so we save some requests
|
|
1021
|
+
this._currentServerUserCache = createCacheBySession(async (session) => {
|
|
1022
|
+
const user = await this._interface.getServerUserByToken(session);
|
|
1023
|
+
return Result.or(user, null);
|
|
1024
|
+
});
|
|
1025
|
+
this._serverUsersCache = createCache(async () => {
|
|
1026
|
+
return await this._interface.listServerUsers();
|
|
1027
|
+
});
|
|
1028
|
+
this._serverUserCache = createCache(async ([userId]) => {
|
|
1029
|
+
const user = await this._interface.getServerUserById(userId);
|
|
1030
|
+
return Result.or(user, null);
|
|
1031
|
+
});
|
|
1032
|
+
this._serverTeamsCache = createCache(async () => {
|
|
1033
|
+
return await this._interface.listServerTeams();
|
|
1034
|
+
});
|
|
1035
|
+
this._serverTeamMembersCache = createCache(async ([teamId]) => {
|
|
1036
|
+
return await this._interface.listServerTeamMembers(teamId);
|
|
1037
|
+
});
|
|
1038
|
+
this._serverTeamPermissionDefinitionsCache = createCache(async () => {
|
|
1039
|
+
return await this._interface.listPermissionDefinitions();
|
|
1040
|
+
});
|
|
1041
|
+
this._serverTeamUserPermissionsCache = createCache(async ([teamId, userId, type, direct]) => {
|
|
1042
|
+
return await this._interface.listServerTeamMemberPermissions({ teamId, userId, type, direct });
|
|
1043
|
+
});
|
|
1044
|
+
this._serverEmailTemplatesCache = createCache(async () => {
|
|
1045
|
+
return await this._interface.listEmailTemplates();
|
|
1046
|
+
});
|
|
1051
1047
|
}
|
|
1052
1048
|
_createBaseUser(json) {
|
|
1053
1049
|
return {
|
|
@@ -1374,12 +1370,6 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
1374
1370
|
}
|
|
1375
1371
|
};
|
|
1376
1372
|
var _StackAdminAppImpl = class extends _StackServerAppImpl {
|
|
1377
|
-
_adminProjectCache = createCache(async () => {
|
|
1378
|
-
return await this._interface.getProject();
|
|
1379
|
-
});
|
|
1380
|
-
_apiKeySetsCache = createCache(async () => {
|
|
1381
|
-
return await this._interface.listApiKeySets();
|
|
1382
|
-
});
|
|
1383
1373
|
constructor(options) {
|
|
1384
1374
|
super({
|
|
1385
1375
|
interface: new StackAdminInterface({
|
|
@@ -1398,6 +1388,12 @@ var _StackAdminAppImpl = class extends _StackServerAppImpl {
|
|
|
1398
1388
|
urls: options.urls,
|
|
1399
1389
|
oauthScopesOnSignIn: options.oauthScopesOnSignIn
|
|
1400
1390
|
});
|
|
1391
|
+
this._adminProjectCache = createCache(async () => {
|
|
1392
|
+
return await this._interface.getProject();
|
|
1393
|
+
});
|
|
1394
|
+
this._apiKeySetsCache = createCache(async () => {
|
|
1395
|
+
return await this._interface.listApiKeySets();
|
|
1396
|
+
});
|
|
1401
1397
|
}
|
|
1402
1398
|
_createApiKeySetBaseFromJson(data) {
|
|
1403
1399
|
const app = this;
|