@stackframe/stack 2.5.2 → 2.5.4
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 +20 -0
- package/dist/components/credential-sign-in-form.js +4 -14
- package/dist/components/credential-sign-in-form.js.map +1 -1
- package/dist/components/credential-sign-up-form.js +18 -20
- package/dist/components/credential-sign-up-form.js.map +1 -1
- package/dist/components/elements/maybe-full-page.js.map +1 -1
- package/dist/components/elements/ssr-layout-effect.d.mts +1 -0
- package/dist/components/elements/ssr-layout-effect.d.ts +1 -0
- package/dist/components/elements/ssr-layout-effect.js +8 -1
- package/dist/components/elements/ssr-layout-effect.js.map +1 -1
- package/dist/components/elements/user-avatar.d.mts +5 -3
- package/dist/components/elements/user-avatar.d.ts +5 -3
- package/dist/components/elements/user-avatar.js.map +1 -1
- package/dist/components/forgot-password-form.js +3 -13
- package/dist/components/forgot-password-form.js.map +1 -1
- package/dist/components/magic-link-sign-in-form.js +3 -13
- package/dist/components/magic-link-sign-in-form.js.map +1 -1
- package/dist/components/message-cards/known-error-message-card.js.map +1 -1
- package/dist/components/message-cards/message-card.js.map +1 -1
- package/dist/components/message-cards/predefined-message-card.js.map +1 -1
- package/dist/components/oauth-button-group.d.mts +7 -2
- package/dist/components/oauth-button-group.d.ts +7 -2
- package/dist/components/oauth-button-group.js +1 -1
- package/dist/components/oauth-button-group.js.map +1 -1
- package/dist/components/oauth-button.js +28 -26
- package/dist/components/oauth-button.js.map +1 -1
- package/dist/components/password-reset-form.js +4 -3
- package/dist/components/password-reset-form.js.map +1 -1
- package/dist/components/selected-team-switcher.d.mts +5 -3
- package/dist/components/selected-team-switcher.d.ts +5 -3
- package/dist/components/selected-team-switcher.js +12 -1
- package/dist/components/selected-team-switcher.js.map +1 -1
- package/dist/components/user-button.js.map +1 -1
- package/dist/components-page/account-settings.js +42 -7
- package/dist/components-page/account-settings.js.map +1 -1
- package/dist/components-page/auth-page.d.mts +9 -2
- package/dist/components-page/auth-page.d.ts +9 -2
- package/dist/components-page/auth-page.js +3 -3
- package/dist/components-page/auth-page.js.map +1 -1
- package/dist/components-page/email-verification.js +12 -2
- package/dist/components-page/email-verification.js.map +1 -1
- package/dist/components-page/error-page.js.map +1 -1
- package/dist/components-page/magic-link-callback.js +13 -3
- package/dist/components-page/magic-link-callback.js.map +1 -1
- package/dist/components-page/password-reset.js +2 -2
- package/dist/components-page/password-reset.js.map +1 -1
- package/dist/components-page/sign-out.js +12 -2
- package/dist/components-page/sign-out.js.map +1 -1
- package/dist/components-page/stack-handler.d.mts +5 -3
- package/dist/components-page/stack-handler.d.ts +5 -3
- package/dist/components-page/stack-handler.js +27 -10
- package/dist/components-page/stack-handler.js.map +1 -1
- package/dist/esm/components/credential-sign-in-form.js +4 -4
- package/dist/esm/components/credential-sign-in-form.js.map +1 -1
- package/dist/esm/components/credential-sign-up-form.js +18 -20
- package/dist/esm/components/credential-sign-up-form.js.map +1 -1
- package/dist/esm/components/elements/maybe-full-page.js.map +1 -1
- package/dist/esm/components/elements/ssr-layout-effect.js +8 -1
- package/dist/esm/components/elements/ssr-layout-effect.js.map +1 -1
- package/dist/esm/components/elements/user-avatar.js.map +1 -1
- package/dist/esm/components/forgot-password-form.js +3 -3
- package/dist/esm/components/forgot-password-form.js.map +1 -1
- package/dist/esm/components/magic-link-sign-in-form.js +3 -3
- package/dist/esm/components/magic-link-sign-in-form.js.map +1 -1
- package/dist/esm/components/message-cards/known-error-message-card.js.map +1 -1
- package/dist/esm/components/message-cards/message-card.js.map +1 -1
- package/dist/esm/components/message-cards/predefined-message-card.js.map +1 -1
- package/dist/esm/components/oauth-button-group.js +1 -1
- package/dist/esm/components/oauth-button-group.js.map +1 -1
- package/dist/esm/components/oauth-button.js +29 -27
- package/dist/esm/components/oauth-button.js.map +1 -1
- package/dist/esm/components/password-reset-form.js +4 -3
- package/dist/esm/components/password-reset-form.js.map +1 -1
- package/dist/esm/components/selected-team-switcher.js +2 -1
- package/dist/esm/components/selected-team-switcher.js.map +1 -1
- package/dist/esm/components/user-button.js.map +1 -1
- package/dist/esm/components-page/account-settings.js +42 -7
- package/dist/esm/components-page/account-settings.js.map +1 -1
- package/dist/esm/components-page/auth-page.js +3 -3
- package/dist/esm/components-page/auth-page.js.map +1 -1
- package/dist/esm/components-page/email-verification.js +2 -2
- package/dist/esm/components-page/email-verification.js.map +1 -1
- package/dist/esm/components-page/error-page.js.map +1 -1
- package/dist/esm/components-page/magic-link-callback.js +3 -3
- package/dist/esm/components-page/magic-link-callback.js.map +1 -1
- package/dist/esm/components-page/password-reset.js +2 -2
- package/dist/esm/components-page/password-reset.js.map +1 -1
- package/dist/esm/components-page/sign-out.js +2 -2
- package/dist/esm/components-page/sign-out.js.map +1 -1
- package/dist/esm/components-page/stack-handler.js +27 -10
- package/dist/esm/components-page/stack-handler.js.map +1 -1
- package/dist/esm/index.js +1 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/auth.js.map +1 -1
- package/dist/esm/lib/cookie.js +6 -1
- package/dist/esm/lib/cookie.js.map +1 -1
- package/dist/esm/lib/hooks.js.map +1 -1
- package/dist/esm/lib/stack-app.js +581 -456
- package/dist/esm/lib/stack-app.js.map +1 -1
- package/dist/esm/providers/stack-provider-client.js +3 -4
- package/dist/esm/providers/stack-provider-client.js.map +1 -1
- package/dist/esm/providers/theme-provider.js +16 -7
- package/dist/esm/providers/theme-provider.js.map +1 -1
- package/dist/esm/utils/browser-script.js +2 -2
- package/dist/esm/utils/browser-script.js.map +1 -1
- package/dist/esm/utils/email.js +2 -2
- package/dist/esm/utils/email.js.map +1 -1
- package/dist/index.d.mts +6 -4
- package/dist/index.d.ts +6 -4
- package/dist/index.js +4 -8
- package/dist/index.js.map +1 -1
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/cookie.js +6 -1
- package/dist/lib/cookie.js.map +1 -1
- package/dist/lib/hooks.d.mts +5 -3
- package/dist/lib/hooks.d.ts +5 -3
- package/dist/lib/hooks.js.map +1 -1
- package/dist/lib/stack-app.d.mts +219 -114
- package/dist/lib/stack-app.d.ts +219 -114
- package/dist/lib/stack-app.js +603 -476
- package/dist/lib/stack-app.js.map +1 -1
- package/dist/providers/stack-provider-client.d.mts +8 -6
- package/dist/providers/stack-provider-client.d.ts +8 -6
- package/dist/providers/stack-provider-client.js +4 -5
- package/dist/providers/stack-provider-client.js.map +1 -1
- package/dist/providers/stack-provider.d.mts +5 -3
- package/dist/providers/stack-provider.d.ts +5 -3
- package/dist/providers/theme-provider.d.mts +2 -1
- package/dist/providers/theme-provider.d.ts +2 -1
- package/dist/providers/theme-provider.js +15 -6
- package/dist/providers/theme-provider.js.map +1 -1
- package/dist/utils/browser-script.d.mts +3 -1
- package/dist/utils/browser-script.d.ts +3 -1
- package/dist/utils/browser-script.js +2 -2
- package/dist/utils/browser-script.js.map +1 -1
- package/dist/utils/email.js +2 -12
- package/dist/utils/email.js.map +1 -1
- package/package.json +4 -5
- package/dist/esm/providers/styled-components-registry.js +0 -25
- package/dist/esm/providers/styled-components-registry.js.map +0 -1
- package/dist/providers/styled-components-registry.d.mts +0 -8
- package/dist/providers/styled-components-registry.d.ts +0 -8
- package/dist/providers/styled-components-registry.js +0 -45
- package/dist/providers/styled-components-registry.js.map +0 -1
|
@@ -1,31 +1,28 @@
|
|
|
1
1
|
// src/lib/stack-app.ts
|
|
2
|
-
import
|
|
2
|
+
import { isReactServer } from "@stackframe/stack-sc";
|
|
3
3
|
import { KnownError, KnownErrors, StackAdminInterface, StackClientInterface, StackServerInterface } from "@stackframe/stack-shared";
|
|
4
|
-
import {
|
|
4
|
+
import { getProductionModeErrors } from "@stackframe/stack-shared/dist/helpers/production-mode";
|
|
5
|
+
import { InternalSession } from "@stackframe/stack-shared/dist/sessions";
|
|
6
|
+
import { AsyncCache } from "@stackframe/stack-shared/dist/utils/caches";
|
|
7
|
+
import { scrambleDuringCompileTime } from "@stackframe/stack-shared/dist/utils/compile-time";
|
|
8
|
+
import { isBrowserLike } from "@stackframe/stack-shared/dist/utils/env";
|
|
5
9
|
import { StackAssertionError, throwErr } from "@stackframe/stack-shared/dist/utils/errors";
|
|
6
|
-
import {
|
|
10
|
+
import { DependenciesMap } from "@stackframe/stack-shared/dist/utils/maps";
|
|
11
|
+
import { deepPlainEquals, filterUndefined, omit } from "@stackframe/stack-shared/dist/utils/objects";
|
|
12
|
+
import { neverResolve, runAsynchronously, wait } from "@stackframe/stack-shared/dist/utils/promises";
|
|
13
|
+
import { suspend, suspendIfSsr } from "@stackframe/stack-shared/dist/utils/react";
|
|
7
14
|
import { Result } from "@stackframe/stack-shared/dist/utils/results";
|
|
8
|
-
import { suspendIfSsr } from "@stackframe/stack-shared/dist/utils/react";
|
|
9
15
|
import { Store } from "@stackframe/stack-shared/dist/utils/stores";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
16
|
+
import { mergeScopeStrings } from "@stackframe/stack-shared/dist/utils/strings";
|
|
17
|
+
import { generateUuid } from "@stackframe/stack-shared/dist/utils/uuids";
|
|
18
|
+
import * as cookie from "cookie";
|
|
13
19
|
import * as NextNavigationUnscrambled from "next/navigation";
|
|
20
|
+
import React, { useCallback, useMemo } from "react";
|
|
14
21
|
import { constructRedirectUrl } from "../utils/url";
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import { AsyncCache } from "@stackframe/stack-shared/dist/utils/caches";
|
|
18
|
-
import { suspend } from "@stackframe/stack-shared/dist/utils/react";
|
|
19
|
-
import { scrambleDuringCompileTime } from "@stackframe/stack-shared/dist/utils/compile-time";
|
|
20
|
-
import { isReactServer } from "@stackframe/stack-sc";
|
|
21
|
-
import * as cookie from "cookie";
|
|
22
|
-
import { InternalSession } from "@stackframe/stack-shared/dist/sessions";
|
|
23
|
-
import { mergeScopeStrings } from "@stackframe/stack-shared/dist/utils/strings";
|
|
22
|
+
import { addNewOAuthProviderOrScope, callOAuthCallback, signInWithOAuth } from "./auth";
|
|
23
|
+
import { deleteCookie, getCookie, setOrDeleteCookie } from "./cookie";
|
|
24
24
|
var NextNavigation = scrambleDuringCompileTime(NextNavigationUnscrambled);
|
|
25
|
-
var clientVersion = "js @stackframe/stack@2.5.
|
|
26
|
-
function permissionDefinitionScopeToType(scope) {
|
|
27
|
-
return { "any-team": "team", "specific-team": "team", "global": "global" }[scope.type];
|
|
28
|
-
}
|
|
25
|
+
var clientVersion = "js @stackframe/stack@2.5.4";
|
|
29
26
|
function getUrls(partial) {
|
|
30
27
|
const handler = partial.handler ?? "/handler";
|
|
31
28
|
return {
|
|
@@ -74,7 +71,7 @@ function getDefaultSuperSecretAdminKey() {
|
|
|
74
71
|
function getDefaultBaseUrl() {
|
|
75
72
|
return process.env.NEXT_PUBLIC_STACK_URL || defaultBaseUrl;
|
|
76
73
|
}
|
|
77
|
-
var defaultBaseUrl = "https://
|
|
74
|
+
var defaultBaseUrl = "https://api.stack-auth.com";
|
|
78
75
|
function createEmptyTokenStore() {
|
|
79
76
|
return new Store({
|
|
80
77
|
refreshToken: null,
|
|
@@ -103,7 +100,7 @@ function useAsyncCache(cache, dependencies, caller) {
|
|
|
103
100
|
getSnapshot,
|
|
104
101
|
() => throwErr(new Error("getServerSnapshot should never be called in useAsyncCache because we restrict to CSR earlier"))
|
|
105
102
|
);
|
|
106
|
-
return use(promise);
|
|
103
|
+
return React.use(promise);
|
|
107
104
|
}
|
|
108
105
|
var stackAppInternalsSymbol = Symbol.for("StackAppInternals");
|
|
109
106
|
var allClientApps = /* @__PURE__ */ new Map();
|
|
@@ -128,6 +125,97 @@ var numberOfAppsCreated = 0;
|
|
|
128
125
|
var _StackClientAppImpl = class __StackClientAppImpl {
|
|
129
126
|
constructor(_options) {
|
|
130
127
|
this._options = _options;
|
|
128
|
+
this._uniqueIdentifier = void 0;
|
|
129
|
+
this.__DEMO_ENABLE_SLIGHT_FETCH_DELAY = false;
|
|
130
|
+
this._ownedAdminApps = new DependenciesMap();
|
|
131
|
+
this._currentUserCache = createCacheBySession(async (session) => {
|
|
132
|
+
if (this.__DEMO_ENABLE_SLIGHT_FETCH_DELAY) {
|
|
133
|
+
await wait(2e3);
|
|
134
|
+
}
|
|
135
|
+
return await this._interface.getClientUserByToken(session);
|
|
136
|
+
});
|
|
137
|
+
this._currentProjectCache = createCache(async () => {
|
|
138
|
+
return Result.orThrow(await this._interface.getClientProject());
|
|
139
|
+
});
|
|
140
|
+
this._ownedProjectsCache = createCacheBySession(async (session) => {
|
|
141
|
+
return await this._interface.listProjects(session);
|
|
142
|
+
});
|
|
143
|
+
this._currentUserPermissionsCache = createCacheBySession(async (session, [teamId, recursive]) => {
|
|
144
|
+
return await this._interface.listCurrentUserTeamPermissions({ teamId, recursive }, session);
|
|
145
|
+
});
|
|
146
|
+
this._currentUserTeamsCache = createCacheBySession(async (session) => {
|
|
147
|
+
return await this._interface.listCurrentUserTeams(session);
|
|
148
|
+
});
|
|
149
|
+
this._currentUserOAuthConnectionAccessTokensCache = createCacheBySession(
|
|
150
|
+
async (session, [accountId, scope]) => {
|
|
151
|
+
try {
|
|
152
|
+
return await this._interface.getAccessToken(accountId, scope || "", session);
|
|
153
|
+
} catch (err) {
|
|
154
|
+
if (!(err instanceof KnownErrors.OAuthConnectionDoesNotHaveRequiredScope || err instanceof KnownErrors.OAuthConnectionNotConnectedToUser)) {
|
|
155
|
+
throw err;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
);
|
|
161
|
+
this._currentUserOAuthConnectionCache = createCacheBySession(
|
|
162
|
+
async (session, [connectionId, scope, redirect]) => {
|
|
163
|
+
const user = await this._currentUserCache.getOrWait([session], "write-only");
|
|
164
|
+
let hasConnection = true;
|
|
165
|
+
if (!user || !user.oauth_providers.find((p) => p.id === connectionId)) {
|
|
166
|
+
hasConnection = false;
|
|
167
|
+
}
|
|
168
|
+
const token = await this._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
|
|
169
|
+
if (!token) {
|
|
170
|
+
hasConnection = false;
|
|
171
|
+
}
|
|
172
|
+
if (!hasConnection && redirect) {
|
|
173
|
+
await addNewOAuthProviderOrScope(
|
|
174
|
+
this._interface,
|
|
175
|
+
{
|
|
176
|
+
provider: connectionId,
|
|
177
|
+
redirectUrl: this.urls.oauthCallback,
|
|
178
|
+
errorRedirectUrl: this.urls.error,
|
|
179
|
+
providerScope: mergeScopeStrings(scope || "", (this._oauthScopesOnSignIn[connectionId] ?? []).join(" "))
|
|
180
|
+
},
|
|
181
|
+
session
|
|
182
|
+
);
|
|
183
|
+
return await neverResolve();
|
|
184
|
+
} else if (!hasConnection) {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
const app = this;
|
|
188
|
+
return {
|
|
189
|
+
id: connectionId,
|
|
190
|
+
async getAccessToken() {
|
|
191
|
+
const result = await app._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
|
|
192
|
+
if (!result) {
|
|
193
|
+
throw new StackAssertionError("No access token available");
|
|
194
|
+
}
|
|
195
|
+
return result;
|
|
196
|
+
},
|
|
197
|
+
useAccessToken() {
|
|
198
|
+
const result = useAsyncCache(app._currentUserOAuthConnectionAccessTokensCache, [session, connectionId, scope || ""], "oauthAccount.useAccessToken()");
|
|
199
|
+
if (!result) {
|
|
200
|
+
throw new StackAssertionError("No access token available");
|
|
201
|
+
}
|
|
202
|
+
return result;
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
);
|
|
207
|
+
this._memoryTokenStore = createEmptyTokenStore();
|
|
208
|
+
this._requestTokenStores = /* @__PURE__ */ new WeakMap();
|
|
209
|
+
this._storedCookieTokenStore = null;
|
|
210
|
+
/**
|
|
211
|
+
* A map from token stores and session keys to sessions.
|
|
212
|
+
*
|
|
213
|
+
* This isn't just a map from session keys to sessions for two reasons:
|
|
214
|
+
*
|
|
215
|
+
* - So we can garbage-collect Session objects when the token store is garbage-collected
|
|
216
|
+
* - 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
|
|
217
|
+
*/
|
|
218
|
+
this._sessionsByTokenStoreAndSessionKey = /* @__PURE__ */ new WeakMap();
|
|
131
219
|
if ("interface" in _options) {
|
|
132
220
|
this._interface = _options.interface;
|
|
133
221
|
} else {
|
|
@@ -145,94 +233,13 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
145
233
|
this._uniqueIdentifier = _options.uniqueIdentifier;
|
|
146
234
|
this._initUniqueIdentifier();
|
|
147
235
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
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;
|
|
236
|
+
if (!_options.noAutomaticPrefetch) {
|
|
237
|
+
numberOfAppsCreated++;
|
|
238
|
+
if (numberOfAppsCreated > 10) {
|
|
239
|
+
(process.env.NODE_ENV === "development" ? console.log : console.warn)(`You have created more than 10 Stack apps with automatic pre-fetch enabled (${numberOfAppsCreated}). This is usually a sign of a memory leak, but can sometimes be caused by hot reload of your tech stack. If you are getting this error and it is not caused by hot reload, make sure to minimize the number of Stack apps per page (usually, one per project). (If it is caused by hot reload and does not occur in production, you can safely ignore it.)`);
|
|
196
240
|
}
|
|
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
241
|
}
|
|
235
|
-
|
|
242
|
+
}
|
|
236
243
|
_initUniqueIdentifier() {
|
|
237
244
|
if (!this._uniqueIdentifier) {
|
|
238
245
|
throw new StackAssertionError("Unique identifier not initialized");
|
|
@@ -244,7 +251,8 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
244
251
|
}
|
|
245
252
|
/**
|
|
246
253
|
* Cloudflare workers does not allow use of randomness on the global scope (on which the Stack app is probably
|
|
247
|
-
* initialized). For that reason, we generate the unique identifier lazily when it is first needed
|
|
254
|
+
* initialized). For that reason, we generate the unique identifier lazily when it is first needed instead of in the
|
|
255
|
+
* constructor.
|
|
248
256
|
*/
|
|
249
257
|
_getUniqueIdentifier() {
|
|
250
258
|
if (!this._uniqueIdentifier) {
|
|
@@ -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);
|
|
@@ -461,38 +457,28 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
461
457
|
throw new Error("Cannot call this function on a Stack app with a project ID other than 'internal'.");
|
|
462
458
|
}
|
|
463
459
|
}
|
|
464
|
-
|
|
465
|
-
const type = permissionDefinitionScopeToType(json.scope);
|
|
466
|
-
if (type === "team") {
|
|
467
|
-
return {
|
|
468
|
-
id: json.id,
|
|
469
|
-
type,
|
|
470
|
-
teamId: json.scope.teamId
|
|
471
|
-
};
|
|
472
|
-
} else {
|
|
473
|
-
return {
|
|
474
|
-
id: json.id,
|
|
475
|
-
type
|
|
476
|
-
};
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
_teamFromJson(json) {
|
|
460
|
+
_clientProjectFromCrud(crud) {
|
|
480
461
|
return {
|
|
481
|
-
id:
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
462
|
+
id: crud.id,
|
|
463
|
+
config: {
|
|
464
|
+
credentialEnabled: crud.config.credential_enabled,
|
|
465
|
+
magicLinkEnabled: crud.config.magic_link_enabled,
|
|
466
|
+
oauthProviders: crud.config.oauth_providers.map((p) => ({
|
|
467
|
+
id: p.id
|
|
468
|
+
}))
|
|
487
469
|
}
|
|
488
470
|
};
|
|
489
471
|
}
|
|
490
|
-
|
|
491
|
-
|
|
472
|
+
_clientTeamPermissionFromCrud(crud) {
|
|
473
|
+
return {
|
|
474
|
+
id: crud.id
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
_clientTeamFromCrud(crud) {
|
|
492
478
|
return {
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
479
|
+
id: crud.id,
|
|
480
|
+
displayName: crud.display_name,
|
|
481
|
+
profileImageUrl: crud.profile_image_url
|
|
496
482
|
};
|
|
497
483
|
}
|
|
498
484
|
_createAuth(session) {
|
|
@@ -522,41 +508,29 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
522
508
|
}
|
|
523
509
|
};
|
|
524
510
|
}
|
|
525
|
-
_createBaseUser(
|
|
511
|
+
_createBaseUser(crud) {
|
|
512
|
+
if (!crud) {
|
|
513
|
+
throw new StackAssertionError("User not found");
|
|
514
|
+
}
|
|
526
515
|
return {
|
|
527
|
-
projectId:
|
|
528
|
-
id:
|
|
529
|
-
displayName:
|
|
530
|
-
primaryEmail:
|
|
531
|
-
primaryEmailVerified:
|
|
532
|
-
profileImageUrl:
|
|
533
|
-
signedUpAt: new Date(
|
|
534
|
-
clientMetadata:
|
|
535
|
-
hasPassword:
|
|
536
|
-
|
|
537
|
-
oauthProviders:
|
|
538
|
-
selectedTeam:
|
|
516
|
+
projectId: crud.project_id,
|
|
517
|
+
id: crud.id,
|
|
518
|
+
displayName: crud.display_name,
|
|
519
|
+
primaryEmail: crud.primary_email,
|
|
520
|
+
primaryEmailVerified: crud.primary_email_verified,
|
|
521
|
+
profileImageUrl: crud.profile_image_url,
|
|
522
|
+
signedUpAt: new Date(crud.signed_up_at_millis),
|
|
523
|
+
clientMetadata: crud.client_metadata,
|
|
524
|
+
hasPassword: crud.has_password,
|
|
525
|
+
emailAuthEnabled: crud.auth_with_email,
|
|
526
|
+
oauthProviders: crud.oauth_providers,
|
|
527
|
+
selectedTeam: crud.selected_team && this._clientTeamFromCrud(crud.selected_team),
|
|
539
528
|
toClientJson() {
|
|
540
|
-
return
|
|
541
|
-
"projectId",
|
|
542
|
-
"id",
|
|
543
|
-
"displayName",
|
|
544
|
-
"primaryEmail",
|
|
545
|
-
"primaryEmailVerified",
|
|
546
|
-
"profileImageUrl",
|
|
547
|
-
"signedUpAtMillis",
|
|
548
|
-
"clientMetadata",
|
|
549
|
-
"hasPassword",
|
|
550
|
-
"authMethod",
|
|
551
|
-
"authWithEmail",
|
|
552
|
-
"selectedTeamId",
|
|
553
|
-
"selectedTeam",
|
|
554
|
-
"oauthProviders"
|
|
555
|
-
]);
|
|
529
|
+
return crud;
|
|
556
530
|
}
|
|
557
531
|
};
|
|
558
532
|
}
|
|
559
|
-
|
|
533
|
+
_createCurrentUserExtra(crud, session) {
|
|
560
534
|
const app = this;
|
|
561
535
|
async function getConnectedAccount(id, options) {
|
|
562
536
|
const scopeString = options?.scopes?.join(" ");
|
|
@@ -590,24 +564,26 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
590
564
|
},
|
|
591
565
|
async listTeams() {
|
|
592
566
|
const teams = await app._currentUserTeamsCache.getOrWait([session], "write-only");
|
|
593
|
-
return teams.map((
|
|
567
|
+
return teams.map((crud2) => app._clientTeamFromCrud(crud2));
|
|
594
568
|
},
|
|
595
569
|
useTeams() {
|
|
596
570
|
const teams = useAsyncCache(app._currentUserTeamsCache, [session], "user.useTeams()");
|
|
597
|
-
return useMemo(() => teams.map((
|
|
571
|
+
return useMemo(() => teams.map((crud2) => app._clientTeamFromCrud(crud2)), [teams]);
|
|
598
572
|
},
|
|
599
573
|
async createTeam(data) {
|
|
600
|
-
const
|
|
574
|
+
const crud2 = await app._interface.createTeamForCurrentUser(teamCreateOptionsToCrud(data), session);
|
|
601
575
|
await app._currentUserTeamsCache.refresh([session]);
|
|
602
|
-
return app.
|
|
576
|
+
return app._clientTeamFromCrud(crud2);
|
|
603
577
|
},
|
|
604
578
|
async listPermissions(scope, options) {
|
|
605
|
-
const
|
|
606
|
-
|
|
579
|
+
const recursive = options?.recursive ?? true;
|
|
580
|
+
const permissions = await app._currentUserPermissionsCache.getOrWait([session, scope.id, recursive], "write-only");
|
|
581
|
+
return permissions.map((crud2) => app._clientTeamPermissionFromCrud(crud2));
|
|
607
582
|
},
|
|
608
583
|
usePermissions(scope, options) {
|
|
609
|
-
const
|
|
610
|
-
|
|
584
|
+
const recursive = options?.recursive ?? true;
|
|
585
|
+
const permissions = useAsyncCache(app._currentUserPermissionsCache, [session, scope.id, recursive], "user.usePermissions()");
|
|
586
|
+
return useMemo(() => permissions.map((crud2) => app._clientTeamPermissionFromCrud(crud2)), [permissions]);
|
|
611
587
|
},
|
|
612
588
|
usePermission(scope, permissionId) {
|
|
613
589
|
const permissions = this.usePermissions(scope);
|
|
@@ -621,7 +597,7 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
621
597
|
return await this.getPermission(scope, permissionId) !== null;
|
|
622
598
|
},
|
|
623
599
|
update(update) {
|
|
624
|
-
return app.
|
|
600
|
+
return app._updateClientUser(update, session);
|
|
625
601
|
},
|
|
626
602
|
sendVerificationEmail() {
|
|
627
603
|
return app._sendVerificationEmail(session);
|
|
@@ -646,58 +622,27 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
646
622
|
}
|
|
647
623
|
};
|
|
648
624
|
}
|
|
649
|
-
|
|
625
|
+
_currentUserFromCrud(crud, session) {
|
|
650
626
|
const currentUser = {
|
|
651
|
-
...this._createBaseUser(
|
|
627
|
+
...this._createBaseUser(crud),
|
|
652
628
|
...this._createAuth(session),
|
|
653
|
-
...this.
|
|
629
|
+
...this._createCurrentUserExtra(crud, session),
|
|
654
630
|
...this._isInternalProject() ? this._createInternalUserExtra(session) : {}
|
|
655
631
|
};
|
|
656
632
|
Object.freeze(currentUser);
|
|
657
633
|
return currentUser;
|
|
658
634
|
}
|
|
659
|
-
|
|
660
|
-
if (
|
|
661
|
-
|
|
635
|
+
_getOwnedAdminApp(forProjectId, session) {
|
|
636
|
+
if (!this._ownedAdminApps.has([session, forProjectId])) {
|
|
637
|
+
this._ownedAdminApps.set([session, forProjectId], new _StackAdminAppImpl({
|
|
638
|
+
baseUrl: this._interface.options.baseUrl,
|
|
639
|
+
projectId: forProjectId,
|
|
640
|
+
tokenStore: null,
|
|
641
|
+
projectOwnerSession: session,
|
|
642
|
+
noAutomaticPrefetch: true
|
|
643
|
+
}));
|
|
662
644
|
}
|
|
663
|
-
return
|
|
664
|
-
id: data.id,
|
|
665
|
-
displayName: data.displayName,
|
|
666
|
-
description: data.description,
|
|
667
|
-
createdAt: new Date(data.createdAtMillis),
|
|
668
|
-
userCount: data.userCount,
|
|
669
|
-
isProductionMode: data.isProductionMode,
|
|
670
|
-
evaluatedConfig: {
|
|
671
|
-
id: data.evaluatedConfig.id,
|
|
672
|
-
credentialEnabled: data.evaluatedConfig.credentialEnabled,
|
|
673
|
-
magicLinkEnabled: data.evaluatedConfig.magicLinkEnabled,
|
|
674
|
-
allowLocalhost: data.evaluatedConfig.allowLocalhost,
|
|
675
|
-
oauthProviders: data.evaluatedConfig.oauthProviders,
|
|
676
|
-
emailConfig: data.evaluatedConfig.emailConfig,
|
|
677
|
-
domains: data.evaluatedConfig.domains,
|
|
678
|
-
createTeamOnSignUp: data.evaluatedConfig.createTeamOnSignUp,
|
|
679
|
-
teamCreatorDefaultPermissions: data.evaluatedConfig.teamCreatorDefaultPermissions,
|
|
680
|
-
teamMemberDefaultPermissions: data.evaluatedConfig.teamMemberDefaultPermissions
|
|
681
|
-
},
|
|
682
|
-
async update(update) {
|
|
683
|
-
await adminInterface.updateProject(update);
|
|
684
|
-
await onRefresh();
|
|
685
|
-
},
|
|
686
|
-
toJson() {
|
|
687
|
-
return data;
|
|
688
|
-
},
|
|
689
|
-
getProductionModeErrors() {
|
|
690
|
-
return getProductionModeErrors(this.toJson());
|
|
691
|
-
}
|
|
692
|
-
};
|
|
693
|
-
}
|
|
694
|
-
_createAdminInterface(forProjectId, session) {
|
|
695
|
-
return new StackAdminInterface({
|
|
696
|
-
baseUrl: this._interface.options.baseUrl,
|
|
697
|
-
projectId: forProjectId,
|
|
698
|
-
clientVersion,
|
|
699
|
-
projectOwnerSession: session
|
|
700
|
-
});
|
|
645
|
+
return this._ownedAdminApps.get([session, forProjectId]);
|
|
701
646
|
}
|
|
702
647
|
get projectId() {
|
|
703
648
|
return this._interface.projectId;
|
|
@@ -777,8 +722,8 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
777
722
|
async getUser(options) {
|
|
778
723
|
this._ensurePersistentTokenStore(options?.tokenStore);
|
|
779
724
|
const session = this._getSession(options?.tokenStore);
|
|
780
|
-
const
|
|
781
|
-
if (
|
|
725
|
+
const crud = await this._currentUserCache.getOrWait([session], "write-only");
|
|
726
|
+
if (crud === null) {
|
|
782
727
|
switch (options?.or) {
|
|
783
728
|
case "redirect": {
|
|
784
729
|
await this.redirectToSignIn();
|
|
@@ -792,14 +737,14 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
792
737
|
}
|
|
793
738
|
}
|
|
794
739
|
}
|
|
795
|
-
return
|
|
740
|
+
return crud && this._currentUserFromCrud(crud, session);
|
|
796
741
|
}
|
|
797
742
|
useUser(options) {
|
|
798
743
|
this._ensurePersistentTokenStore(options?.tokenStore);
|
|
799
744
|
const router = NextNavigation.useRouter();
|
|
800
745
|
const session = this._useSession(options?.tokenStore);
|
|
801
|
-
const
|
|
802
|
-
if (
|
|
746
|
+
const crud = useAsyncCache(this._currentUserCache, [session], "useUser()");
|
|
747
|
+
if (crud === null) {
|
|
803
748
|
switch (options?.or) {
|
|
804
749
|
case "redirect": {
|
|
805
750
|
setTimeout(() => router.replace(this.urls.signIn), 0);
|
|
@@ -815,11 +760,11 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
815
760
|
}
|
|
816
761
|
}
|
|
817
762
|
return useMemo(() => {
|
|
818
|
-
return
|
|
819
|
-
}, [
|
|
763
|
+
return crud && this._currentUserFromCrud(crud, session);
|
|
764
|
+
}, [crud, session, options?.or]);
|
|
820
765
|
}
|
|
821
|
-
async
|
|
822
|
-
const res = await this._interface.
|
|
766
|
+
async _updateClientUser(update, session) {
|
|
767
|
+
const res = await this._interface.updateClientUser(userUpdateOptionsToCrud(update), session);
|
|
823
768
|
await this._refreshUser(session);
|
|
824
769
|
return res;
|
|
825
770
|
}
|
|
@@ -863,8 +808,7 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
863
808
|
}
|
|
864
809
|
async signInWithMagicLink(code) {
|
|
865
810
|
this._ensurePersistentTokenStore();
|
|
866
|
-
const
|
|
867
|
-
const result = await this._interface.signInWithMagicLink(code, session);
|
|
811
|
+
const result = await this._interface.signInWithMagicLink(code);
|
|
868
812
|
if (result instanceof KnownError) {
|
|
869
813
|
return result;
|
|
870
814
|
}
|
|
@@ -911,35 +855,34 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
911
855
|
}
|
|
912
856
|
}
|
|
913
857
|
async getProject() {
|
|
914
|
-
|
|
858
|
+
const crud = await this._currentProjectCache.getOrWait([], "write-only");
|
|
859
|
+
return this._clientProjectFromCrud(crud);
|
|
915
860
|
}
|
|
916
861
|
useProject() {
|
|
917
|
-
|
|
862
|
+
const crud = useAsyncCache(this._currentProjectCache, [], "useProject()");
|
|
863
|
+
return useMemo(() => this._clientProjectFromCrud(crud), [crud]);
|
|
918
864
|
}
|
|
919
865
|
async _listOwnedProjects(session) {
|
|
920
866
|
this._ensureInternalProject();
|
|
921
|
-
const
|
|
922
|
-
return
|
|
867
|
+
const crud = await this._ownedProjectsCache.getOrWait([session], "write-only");
|
|
868
|
+
return crud.map((j) => this._getOwnedAdminApp(j.id, session)._adminOwnedProjectFromCrud(
|
|
923
869
|
j,
|
|
924
|
-
this._createAdminInterface(j.id, session),
|
|
925
870
|
() => this._refreshOwnedProjects(session)
|
|
926
871
|
));
|
|
927
872
|
}
|
|
928
873
|
_useOwnedProjects(session) {
|
|
929
874
|
this._ensureInternalProject();
|
|
930
|
-
const
|
|
931
|
-
return useMemo(() =>
|
|
875
|
+
const projects = useAsyncCache(this._ownedProjectsCache, [session], "useOwnedProjects()");
|
|
876
|
+
return useMemo(() => projects.map((j) => this._getOwnedAdminApp(j.id, session)._adminOwnedProjectFromCrud(
|
|
932
877
|
j,
|
|
933
|
-
this._createAdminInterface(j.id, session),
|
|
934
878
|
() => this._refreshOwnedProjects(session)
|
|
935
|
-
)), [
|
|
879
|
+
)), [projects]);
|
|
936
880
|
}
|
|
937
881
|
async _createProject(session, newProject) {
|
|
938
882
|
this._ensureInternalProject();
|
|
939
|
-
const
|
|
940
|
-
const res = this.
|
|
941
|
-
|
|
942
|
-
this._createAdminInterface(json.id, session),
|
|
883
|
+
const crud = await this._interface.createProject(adminProjectCreateOptionsToCrud(newProject), session);
|
|
884
|
+
const res = this._getOwnedAdminApp(crud.id, session)._adminOwnedProjectFromCrud(
|
|
885
|
+
crud,
|
|
943
886
|
() => this._refreshOwnedProjects(session)
|
|
944
887
|
);
|
|
945
888
|
await this._refreshOwnedProjects(session);
|
|
@@ -1003,33 +946,6 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
1003
946
|
}
|
|
1004
947
|
};
|
|
1005
948
|
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
949
|
constructor(options) {
|
|
1034
950
|
super("interface" in options ? {
|
|
1035
951
|
interface: options.interface,
|
|
@@ -1048,24 +964,46 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
1048
964
|
urls: options.urls ?? {},
|
|
1049
965
|
oauthScopesOnSignIn: options.oauthScopesOnSignIn ?? {}
|
|
1050
966
|
});
|
|
967
|
+
// TODO override the client user cache to use the server user cache, so we save some requests
|
|
968
|
+
this._currentServerUserCache = createCacheBySession(async (session) => {
|
|
969
|
+
return await this._interface.getServerUserByToken(session);
|
|
970
|
+
});
|
|
971
|
+
this._serverUsersCache = createCache(async () => {
|
|
972
|
+
return await this._interface.listServerUsers();
|
|
973
|
+
});
|
|
974
|
+
this._serverUserCache = createCache(async ([userId]) => {
|
|
975
|
+
const user = await this._interface.getServerUserById(userId);
|
|
976
|
+
return Result.or(user, null);
|
|
977
|
+
});
|
|
978
|
+
this._serverTeamsCache = createCache(async () => {
|
|
979
|
+
return await this._interface.listServerTeams();
|
|
980
|
+
});
|
|
981
|
+
this._serverCurrentUserTeamsCache = createCacheBySession(async (session) => {
|
|
982
|
+
return await this._interface.listServerCurrentUserTeams(session);
|
|
983
|
+
});
|
|
984
|
+
this._serverTeamUsersCache = createCache(async ([teamId]) => {
|
|
985
|
+
return await this._interface.listServerTeamUsers(teamId);
|
|
986
|
+
});
|
|
987
|
+
this._serverTeamUserPermissionsCache = createCache(async ([teamId, userId, recursive]) => {
|
|
988
|
+
return await this._interface.listServerTeamMemberPermissions({ teamId, userId, recursive });
|
|
989
|
+
});
|
|
1051
990
|
}
|
|
1052
|
-
_createBaseUser(
|
|
991
|
+
_createBaseUser(crud) {
|
|
992
|
+
if (!crud) {
|
|
993
|
+
throw new StackAssertionError("User not found");
|
|
994
|
+
}
|
|
1053
995
|
return {
|
|
1054
|
-
...super._createBaseUser(
|
|
1055
|
-
..."
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
return {
|
|
1059
|
-
...this.toClientJson(),
|
|
1060
|
-
...pick(json, [
|
|
1061
|
-
"serverMetadata"
|
|
1062
|
-
])
|
|
1063
|
-
};
|
|
1064
|
-
}
|
|
996
|
+
...super._createBaseUser(crud),
|
|
997
|
+
..."server_metadata" in crud ? {
|
|
998
|
+
// server user
|
|
999
|
+
serverMetadata: crud.server_metadata
|
|
1065
1000
|
} : {}
|
|
1066
1001
|
};
|
|
1067
1002
|
}
|
|
1068
|
-
|
|
1003
|
+
_createCurrentUserExtra(crud) {
|
|
1004
|
+
if (!crud) {
|
|
1005
|
+
throw new StackAssertionError("User not found");
|
|
1006
|
+
}
|
|
1069
1007
|
const app = this;
|
|
1070
1008
|
return {
|
|
1071
1009
|
async setDisplayName(displayName) {
|
|
@@ -1081,7 +1019,7 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
1081
1019
|
return await this.update({ selectedTeamId: team?.id ?? null });
|
|
1082
1020
|
},
|
|
1083
1021
|
async setPrimaryEmail(email, options) {
|
|
1084
|
-
return await this.update({ primaryEmail: email });
|
|
1022
|
+
return await this.update({ primaryEmail: email, primaryEmailVerified: options?.verified });
|
|
1085
1023
|
},
|
|
1086
1024
|
getConnectedAccount: async () => {
|
|
1087
1025
|
return await app._checkFeatureSupport("getConnectedAccount() on ServerUser", {});
|
|
@@ -1094,31 +1032,29 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
1094
1032
|
return teams.find((t) => t.id === teamId) ?? null;
|
|
1095
1033
|
},
|
|
1096
1034
|
useTeam(teamId) {
|
|
1097
|
-
|
|
1098
|
-
return useMemo(() => {
|
|
1099
|
-
return teams.find((t) => t.id === teamId) ?? null;
|
|
1100
|
-
}, [teams, teamId]);
|
|
1035
|
+
return app._useCheckFeatureSupport("useTeam() on ServerUser", {});
|
|
1101
1036
|
},
|
|
1102
1037
|
async listTeams() {
|
|
1103
|
-
const
|
|
1104
|
-
|
|
1105
|
-
return withMembers.filter(([_, members]) => members.find((m) => m.userId === json.id)).map(([t]) => t);
|
|
1038
|
+
const crud2 = await app._serverCurrentUserTeamsCache.getOrWait([app._getSession()], "write-only");
|
|
1039
|
+
return crud2.map((t) => app._serverTeamFromCrud(t));
|
|
1106
1040
|
},
|
|
1107
1041
|
useTeams() {
|
|
1108
1042
|
return app._useCheckFeatureSupport("useTeams() on ServerUser", {});
|
|
1109
1043
|
},
|
|
1110
1044
|
createTeam: async (data) => {
|
|
1111
|
-
const team = await app._interface.
|
|
1045
|
+
const team = await app._interface.createServerTeam(serverTeamCreateOptionsToCrud(data), app._getSession());
|
|
1112
1046
|
await app._serverTeamsCache.refresh([]);
|
|
1113
|
-
return app.
|
|
1047
|
+
return app._serverTeamFromCrud(team);
|
|
1114
1048
|
},
|
|
1115
1049
|
async listPermissions(scope, options) {
|
|
1116
|
-
const
|
|
1117
|
-
|
|
1050
|
+
const recursive = options?.recursive ?? true;
|
|
1051
|
+
const permissions = await app._serverTeamUserPermissionsCache.getOrWait([scope.id, crud.id, recursive], "write-only");
|
|
1052
|
+
return permissions.map((crud2) => app._serverPermissionFromCrud(crud2));
|
|
1118
1053
|
},
|
|
1119
1054
|
usePermissions(scope, options) {
|
|
1120
|
-
const
|
|
1121
|
-
|
|
1055
|
+
const recursive = options?.recursive ?? true;
|
|
1056
|
+
const permissions = useAsyncCache(app._serverTeamUserPermissionsCache, [scope.id, crud.id, recursive], "user.usePermissions()");
|
|
1057
|
+
return useMemo(() => permissions.map((crud2) => app._serverPermissionFromCrud(crud2)), [permissions]);
|
|
1122
1058
|
},
|
|
1123
1059
|
async getPermission(scope, permissionId) {
|
|
1124
1060
|
const permissions = await this.listPermissions(scope);
|
|
@@ -1132,26 +1068,25 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
1132
1068
|
return await this.getPermission(scope, permissionId) !== null;
|
|
1133
1069
|
},
|
|
1134
1070
|
async grantPermission(scope, permissionId) {
|
|
1135
|
-
await app._interface.grantServerTeamUserPermission(scope.id,
|
|
1136
|
-
for (const
|
|
1137
|
-
await app._serverTeamUserPermissionsCache.refresh([scope.id,
|
|
1071
|
+
await app._interface.grantServerTeamUserPermission(scope.id, crud.id, permissionId);
|
|
1072
|
+
for (const recursive of [true, false]) {
|
|
1073
|
+
await app._serverTeamUserPermissionsCache.refresh([scope.id, crud.id, recursive]);
|
|
1138
1074
|
}
|
|
1139
1075
|
},
|
|
1140
1076
|
async revokePermission(scope, permissionId) {
|
|
1141
|
-
await app._interface.revokeServerTeamUserPermission(scope.id,
|
|
1142
|
-
for (const
|
|
1143
|
-
await app._serverTeamUserPermissionsCache.refresh([scope.id,
|
|
1077
|
+
await app._interface.revokeServerTeamUserPermission(scope.id, crud.id, permissionId);
|
|
1078
|
+
for (const recursive of [true, false]) {
|
|
1079
|
+
await app._serverTeamUserPermissionsCache.refresh([scope.id, crud.id, recursive]);
|
|
1144
1080
|
}
|
|
1145
1081
|
},
|
|
1146
1082
|
async delete() {
|
|
1147
|
-
const res = await app._interface.deleteServerServerUser(
|
|
1083
|
+
const res = await app._interface.deleteServerServerUser(crud.id);
|
|
1148
1084
|
await app._refreshUsers();
|
|
1149
1085
|
return res;
|
|
1150
1086
|
},
|
|
1151
1087
|
async update(update) {
|
|
1152
|
-
const res = await app._interface.
|
|
1088
|
+
const res = await app._interface.updateServerUser(crud.id, serverUserUpdateOptionsToCrud(update));
|
|
1153
1089
|
await app._refreshUsers();
|
|
1154
|
-
return res;
|
|
1155
1090
|
},
|
|
1156
1091
|
async sendVerificationEmail() {
|
|
1157
1092
|
return await app._checkFeatureSupport("sendVerificationEmail() on ServerUser", {});
|
|
@@ -1161,76 +1096,65 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
1161
1096
|
}
|
|
1162
1097
|
};
|
|
1163
1098
|
}
|
|
1164
|
-
|
|
1099
|
+
_serverUserFromCrud(crud) {
|
|
1165
1100
|
return {
|
|
1166
|
-
...this._createBaseUser(
|
|
1167
|
-
...this.
|
|
1101
|
+
...this._createBaseUser(crud),
|
|
1102
|
+
...this._createCurrentUserExtra(crud)
|
|
1168
1103
|
};
|
|
1169
1104
|
}
|
|
1170
|
-
|
|
1105
|
+
_currentUserFromCrud(crud, session) {
|
|
1171
1106
|
const app = this;
|
|
1172
1107
|
const currentUser = {
|
|
1173
|
-
...this.
|
|
1108
|
+
...this._serverUserFromCrud(crud),
|
|
1174
1109
|
...this._createAuth(session),
|
|
1175
1110
|
...this._isInternalProject() ? this._createInternalUserExtra(session) : {}
|
|
1176
1111
|
};
|
|
1177
1112
|
Object.freeze(currentUser);
|
|
1178
1113
|
return currentUser;
|
|
1179
1114
|
}
|
|
1180
|
-
|
|
1181
|
-
if (json === null) return null;
|
|
1182
|
-
const app = this;
|
|
1183
|
-
return {
|
|
1184
|
-
...app._teamMemberFromJson(json),
|
|
1185
|
-
user: app._createUser(json.user)
|
|
1186
|
-
};
|
|
1187
|
-
}
|
|
1188
|
-
_serverTeamFromJson(json) {
|
|
1115
|
+
_serverTeamFromCrud(crud) {
|
|
1189
1116
|
const app = this;
|
|
1190
1117
|
return {
|
|
1191
|
-
id:
|
|
1192
|
-
displayName:
|
|
1193
|
-
profileImageUrl:
|
|
1194
|
-
createdAt: new Date(
|
|
1195
|
-
async
|
|
1196
|
-
return (await app._interface.
|
|
1118
|
+
id: crud.id,
|
|
1119
|
+
displayName: crud.display_name,
|
|
1120
|
+
profileImageUrl: crud.profile_image_url,
|
|
1121
|
+
createdAt: new Date(crud.created_at_millis),
|
|
1122
|
+
async listUsers() {
|
|
1123
|
+
return (await app._interface.listServerTeamUsers(crud.id)).map((u) => app._serverUserFromCrud(u));
|
|
1197
1124
|
},
|
|
1198
1125
|
async update(update) {
|
|
1199
|
-
await app._interface.updateServerTeam(
|
|
1126
|
+
await app._interface.updateServerTeam(crud.id, serverTeamUpdateOptionsToCrud(update));
|
|
1200
1127
|
await app._serverTeamsCache.refresh([]);
|
|
1201
1128
|
},
|
|
1202
1129
|
async delete() {
|
|
1203
|
-
await app._interface.deleteServerTeam(
|
|
1130
|
+
await app._interface.deleteServerTeam(crud.id);
|
|
1204
1131
|
await app._serverTeamsCache.refresh([]);
|
|
1205
1132
|
},
|
|
1206
|
-
|
|
1207
|
-
const result = useAsyncCache(app.
|
|
1208
|
-
return useMemo(() => result.map((u) => app.
|
|
1133
|
+
useUsers() {
|
|
1134
|
+
const result = useAsyncCache(app._serverTeamUsersCache, [crud.id], "team.useUsers()");
|
|
1135
|
+
return useMemo(() => result.map((u) => app._serverUserFromCrud(u)), [result]);
|
|
1209
1136
|
},
|
|
1210
1137
|
async addUser(userId) {
|
|
1211
1138
|
await app._interface.addServerUserToTeam({
|
|
1212
|
-
teamId:
|
|
1139
|
+
teamId: crud.id,
|
|
1213
1140
|
userId
|
|
1214
1141
|
});
|
|
1215
|
-
await app.
|
|
1142
|
+
await app._serverTeamUsersCache.refresh([crud.id]);
|
|
1216
1143
|
},
|
|
1217
1144
|
async removeUser(userId) {
|
|
1218
1145
|
await app._interface.removeServerUserFromTeam({
|
|
1219
|
-
teamId:
|
|
1146
|
+
teamId: crud.id,
|
|
1220
1147
|
userId
|
|
1221
1148
|
});
|
|
1222
|
-
await app.
|
|
1223
|
-
},
|
|
1224
|
-
toJson() {
|
|
1225
|
-
return json;
|
|
1149
|
+
await app._serverTeamUsersCache.refresh([crud.id]);
|
|
1226
1150
|
}
|
|
1227
1151
|
};
|
|
1228
1152
|
}
|
|
1229
1153
|
async getUser(options) {
|
|
1230
1154
|
this._ensurePersistentTokenStore(options?.tokenStore);
|
|
1231
1155
|
const session = this._getSession(options?.tokenStore);
|
|
1232
|
-
const
|
|
1233
|
-
if (
|
|
1156
|
+
const crud = await this._currentServerUserCache.getOrWait([session], "write-only");
|
|
1157
|
+
if (crud === null) {
|
|
1234
1158
|
switch (options?.or) {
|
|
1235
1159
|
case "redirect": {
|
|
1236
1160
|
await this.redirectToSignIn();
|
|
@@ -1244,22 +1168,22 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
1244
1168
|
}
|
|
1245
1169
|
}
|
|
1246
1170
|
}
|
|
1247
|
-
return
|
|
1171
|
+
return crud && this._currentUserFromCrud(crud, session);
|
|
1248
1172
|
}
|
|
1249
1173
|
async getServerUser() {
|
|
1250
1174
|
console.warn("stackServerApp.getServerUser is deprecated; use stackServerApp.getUser instead");
|
|
1251
1175
|
return await this.getUser();
|
|
1252
1176
|
}
|
|
1253
1177
|
async getServerUserById(userId) {
|
|
1254
|
-
const
|
|
1255
|
-
return
|
|
1178
|
+
const crud = await this._serverUserCache.getOrWait([userId], "write-only");
|
|
1179
|
+
return crud && this._serverUserFromCrud(crud);
|
|
1256
1180
|
}
|
|
1257
1181
|
useUser(options) {
|
|
1258
1182
|
this._ensurePersistentTokenStore(options?.tokenStore);
|
|
1259
1183
|
const router = NextNavigation.useRouter();
|
|
1260
1184
|
const session = this._getSession(options?.tokenStore);
|
|
1261
|
-
const
|
|
1262
|
-
if (
|
|
1185
|
+
const crud = useAsyncCache(this._currentServerUserCache, [session], "useUser()");
|
|
1186
|
+
if (crud === null) {
|
|
1263
1187
|
switch (options?.or) {
|
|
1264
1188
|
case "redirect": {
|
|
1265
1189
|
setTimeout(() => router.replace(this.urls.signIn), 0);
|
|
@@ -1275,65 +1199,50 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
1275
1199
|
}
|
|
1276
1200
|
}
|
|
1277
1201
|
return useMemo(() => {
|
|
1278
|
-
return
|
|
1279
|
-
}, [
|
|
1202
|
+
return crud && this._currentUserFromCrud(crud, session);
|
|
1203
|
+
}, [crud, session, options?.or]);
|
|
1280
1204
|
}
|
|
1281
1205
|
useUserById(userId) {
|
|
1282
|
-
const
|
|
1206
|
+
const crud = useAsyncCache(this._serverUserCache, [userId], "useUserById()");
|
|
1283
1207
|
return useMemo(() => {
|
|
1284
|
-
return
|
|
1285
|
-
}, [
|
|
1208
|
+
return crud && this._serverUserFromCrud(crud);
|
|
1209
|
+
}, [crud]);
|
|
1286
1210
|
}
|
|
1287
1211
|
async listUsers() {
|
|
1288
|
-
const
|
|
1289
|
-
return
|
|
1212
|
+
const crud = await this._serverUsersCache.getOrWait([], "write-only");
|
|
1213
|
+
return crud.map((j) => this._serverUserFromCrud(j));
|
|
1290
1214
|
}
|
|
1291
1215
|
useUsers() {
|
|
1292
|
-
const
|
|
1216
|
+
const crud = useAsyncCache(this._serverUsersCache, [], "useServerUsers()");
|
|
1293
1217
|
return useMemo(() => {
|
|
1294
|
-
return
|
|
1295
|
-
}, [
|
|
1296
|
-
}
|
|
1297
|
-
async listPermissionDefinitions() {
|
|
1298
|
-
return await this._serverTeamPermissionDefinitionsCache.getOrWait([], "write-only");
|
|
1218
|
+
return crud.map((j) => this._serverUserFromCrud(j));
|
|
1219
|
+
}, [crud]);
|
|
1299
1220
|
}
|
|
1300
|
-
|
|
1301
|
-
return useAsyncCache(this._serverTeamPermissionDefinitionsCache, [], "usePermissions()");
|
|
1302
|
-
}
|
|
1303
|
-
_serverPermissionFromJson(json) {
|
|
1221
|
+
_serverPermissionFromCrud(crud) {
|
|
1304
1222
|
return {
|
|
1305
|
-
|
|
1306
|
-
__databaseUniqueId: json.__databaseUniqueId,
|
|
1307
|
-
description: json.description,
|
|
1308
|
-
containPermissionIds: json.containPermissionIds
|
|
1223
|
+
id: crud.id
|
|
1309
1224
|
};
|
|
1310
1225
|
}
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
await this._interface.updatePermissionDefinition(permissionId, data);
|
|
1318
|
-
await this._serverTeamPermissionDefinitionsCache.refresh([]);
|
|
1319
|
-
}
|
|
1320
|
-
async deletePermissionDefinition(permissionId) {
|
|
1321
|
-
await this._interface.deletePermissionDefinition(permissionId);
|
|
1322
|
-
await this._serverTeamPermissionDefinitionsCache.refresh([]);
|
|
1226
|
+
_serverTeamPermissionDefinitionFromCrud(crud) {
|
|
1227
|
+
return {
|
|
1228
|
+
id: crud.id,
|
|
1229
|
+
description: crud.description,
|
|
1230
|
+
containedPermissionIds: crud.contained_permission_ids
|
|
1231
|
+
};
|
|
1323
1232
|
}
|
|
1324
1233
|
async listTeams() {
|
|
1325
1234
|
const teams = await this._serverTeamsCache.getOrWait([], "write-only");
|
|
1326
|
-
return teams.map((t) => this.
|
|
1235
|
+
return teams.map((t) => this._serverTeamFromCrud(t));
|
|
1327
1236
|
}
|
|
1328
1237
|
async createTeam(data) {
|
|
1329
|
-
const team = await this._interface.createServerTeam(data);
|
|
1238
|
+
const team = await this._interface.createServerTeam(serverTeamCreateOptionsToCrud(data));
|
|
1330
1239
|
await this._serverTeamsCache.refresh([]);
|
|
1331
|
-
return this.
|
|
1240
|
+
return this._serverTeamFromCrud(team);
|
|
1332
1241
|
}
|
|
1333
1242
|
useTeams() {
|
|
1334
1243
|
const teams = useAsyncCache(this._serverTeamsCache, [], "useServerTeams()");
|
|
1335
1244
|
return useMemo(() => {
|
|
1336
|
-
return teams.map((t) => this.
|
|
1245
|
+
return teams.map((t) => this._serverTeamFromCrud(t));
|
|
1337
1246
|
}, [teams]);
|
|
1338
1247
|
}
|
|
1339
1248
|
async getTeam(teamId) {
|
|
@@ -1358,28 +1267,8 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
1358
1267
|
this._serverUsersCache.refresh([])
|
|
1359
1268
|
]);
|
|
1360
1269
|
}
|
|
1361
|
-
useEmailTemplates() {
|
|
1362
|
-
return useAsyncCache(this._serverEmailTemplatesCache, [], "useEmailTemplates()");
|
|
1363
|
-
}
|
|
1364
|
-
async listEmailTemplates() {
|
|
1365
|
-
return await this._serverEmailTemplatesCache.getOrWait([], "write-only");
|
|
1366
|
-
}
|
|
1367
|
-
async updateEmailTemplate(type, data) {
|
|
1368
|
-
await this._interface.updateEmailTemplate(type, data);
|
|
1369
|
-
await this._serverEmailTemplatesCache.refresh([]);
|
|
1370
|
-
}
|
|
1371
|
-
async resetEmailTemplate(type) {
|
|
1372
|
-
await this._interface.resetEmailTemplate(type);
|
|
1373
|
-
await this._serverEmailTemplatesCache.refresh([]);
|
|
1374
|
-
}
|
|
1375
1270
|
};
|
|
1376
1271
|
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
1272
|
constructor(options) {
|
|
1384
1273
|
super({
|
|
1385
1274
|
interface: new StackAdminInterface({
|
|
@@ -1398,15 +1287,117 @@ var _StackAdminAppImpl = class extends _StackServerAppImpl {
|
|
|
1398
1287
|
urls: options.urls,
|
|
1399
1288
|
oauthScopesOnSignIn: options.oauthScopesOnSignIn
|
|
1400
1289
|
});
|
|
1290
|
+
this._adminProjectCache = createCache(async () => {
|
|
1291
|
+
return await this._interface.getProject();
|
|
1292
|
+
});
|
|
1293
|
+
this._apiKeysCache = createCache(async () => {
|
|
1294
|
+
return await this._interface.listApiKeys();
|
|
1295
|
+
});
|
|
1296
|
+
this._adminEmailTemplatesCache = createCache(async () => {
|
|
1297
|
+
return await this._interface.listEmailTemplates();
|
|
1298
|
+
});
|
|
1299
|
+
this._adminTeamPermissionDefinitionsCache = createCache(async () => {
|
|
1300
|
+
return await this._interface.listPermissionDefinitions();
|
|
1301
|
+
});
|
|
1401
1302
|
}
|
|
1402
|
-
|
|
1303
|
+
_adminOwnedProjectFromCrud(data, onRefresh) {
|
|
1304
|
+
if (this._tokenStoreInit !== null) {
|
|
1305
|
+
throw new StackAssertionError("Owned apps must always have tokenStore === null \u2014 did you not create this project with app._createOwnedApp()?");
|
|
1306
|
+
;
|
|
1307
|
+
}
|
|
1308
|
+
return {
|
|
1309
|
+
...this._adminProjectFromCrud(data, onRefresh),
|
|
1310
|
+
app: this
|
|
1311
|
+
};
|
|
1312
|
+
}
|
|
1313
|
+
_adminProjectFromCrud(data, onRefresh) {
|
|
1314
|
+
if (data.id !== this.projectId) {
|
|
1315
|
+
throw new StackAssertionError(`The project ID of the provided project JSON (${data.id}) does not match the project ID of the app (${this.projectId})!`);
|
|
1316
|
+
}
|
|
1403
1317
|
const app = this;
|
|
1404
1318
|
return {
|
|
1405
1319
|
id: data.id,
|
|
1320
|
+
displayName: data.display_name,
|
|
1406
1321
|
description: data.description,
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1322
|
+
createdAt: new Date(data.created_at_millis),
|
|
1323
|
+
userCount: data.user_count,
|
|
1324
|
+
isProductionMode: data.is_production_mode,
|
|
1325
|
+
config: {
|
|
1326
|
+
id: data.config.id,
|
|
1327
|
+
credentialEnabled: data.config.credential_enabled,
|
|
1328
|
+
magicLinkEnabled: data.config.magic_link_enabled,
|
|
1329
|
+
allowLocalhost: data.config.allow_localhost,
|
|
1330
|
+
oauthProviders: data.config.oauth_providers.map((p) => p.type === "shared" ? {
|
|
1331
|
+
id: p.id,
|
|
1332
|
+
enabled: p.enabled,
|
|
1333
|
+
type: "shared"
|
|
1334
|
+
} : {
|
|
1335
|
+
id: p.id,
|
|
1336
|
+
enabled: p.enabled,
|
|
1337
|
+
type: "standard",
|
|
1338
|
+
clientId: p.client_id ?? throwErr("Client ID is missing"),
|
|
1339
|
+
clientSecret: p.client_secret ?? throwErr("Client secret is missing")
|
|
1340
|
+
}),
|
|
1341
|
+
emailConfig: data.config.email_config.type === "shared" ? {
|
|
1342
|
+
type: "shared"
|
|
1343
|
+
} : {
|
|
1344
|
+
type: "standard",
|
|
1345
|
+
host: data.config.email_config.host ?? throwErr("Email host is missing"),
|
|
1346
|
+
port: data.config.email_config.port ?? throwErr("Email port is missing"),
|
|
1347
|
+
username: data.config.email_config.username ?? throwErr("Email username is missing"),
|
|
1348
|
+
password: data.config.email_config.password ?? throwErr("Email password is missing"),
|
|
1349
|
+
senderName: data.config.email_config.sender_name ?? throwErr("Email sender name is missing"),
|
|
1350
|
+
senderEmail: data.config.email_config.sender_email ?? throwErr("Email sender email is missing")
|
|
1351
|
+
},
|
|
1352
|
+
domains: data.config.domains.map((d) => ({
|
|
1353
|
+
domain: d.domain,
|
|
1354
|
+
handlerPath: d.handler_path
|
|
1355
|
+
})),
|
|
1356
|
+
createTeamOnSignUp: data.config.create_team_on_sign_up,
|
|
1357
|
+
teamCreatorDefaultPermissions: data.config.team_creator_default_permissions,
|
|
1358
|
+
teamMemberDefaultPermissions: data.config.team_member_default_permissions
|
|
1359
|
+
},
|
|
1360
|
+
async update(update) {
|
|
1361
|
+
await app._interface.updateProject(adminProjectUpdateOptionsToCrud(update));
|
|
1362
|
+
await onRefresh();
|
|
1363
|
+
},
|
|
1364
|
+
async getProductionModeErrors() {
|
|
1365
|
+
return getProductionModeErrors(data);
|
|
1366
|
+
},
|
|
1367
|
+
useProductionModeErrors() {
|
|
1368
|
+
return getProductionModeErrors(data);
|
|
1369
|
+
}
|
|
1370
|
+
};
|
|
1371
|
+
}
|
|
1372
|
+
_adminEmailTemplateFromCrud(data) {
|
|
1373
|
+
return {
|
|
1374
|
+
type: data.type,
|
|
1375
|
+
subject: data.subject,
|
|
1376
|
+
content: data.content,
|
|
1377
|
+
isDefault: data.is_default
|
|
1378
|
+
};
|
|
1379
|
+
}
|
|
1380
|
+
async getProject() {
|
|
1381
|
+
return this._adminProjectFromCrud(
|
|
1382
|
+
await this._adminProjectCache.getOrWait([], "write-only"),
|
|
1383
|
+
() => this._refreshProject()
|
|
1384
|
+
);
|
|
1385
|
+
}
|
|
1386
|
+
useProject() {
|
|
1387
|
+
const crud = useAsyncCache(this._adminProjectCache, [], "useProjectAdmin()");
|
|
1388
|
+
return useMemo(() => this._adminProjectFromCrud(
|
|
1389
|
+
crud,
|
|
1390
|
+
() => this._refreshProject()
|
|
1391
|
+
), [crud]);
|
|
1392
|
+
}
|
|
1393
|
+
_createApiKeyBaseFromCrud(data) {
|
|
1394
|
+
const app = this;
|
|
1395
|
+
return {
|
|
1396
|
+
id: data.id,
|
|
1397
|
+
description: data.description,
|
|
1398
|
+
expiresAt: new Date(data.expires_at_millis),
|
|
1399
|
+
manuallyRevokedAt: data.manually_revoked_at_millis ? new Date(data.manually_revoked_at_millis) : null,
|
|
1400
|
+
createdAt: new Date(data.created_at_millis),
|
|
1410
1401
|
isValid() {
|
|
1411
1402
|
return this.whyInvalid() === null;
|
|
1412
1403
|
},
|
|
@@ -1416,57 +1407,83 @@ var _StackAdminAppImpl = class extends _StackServerAppImpl {
|
|
|
1416
1407
|
return null;
|
|
1417
1408
|
},
|
|
1418
1409
|
async revoke() {
|
|
1419
|
-
const res = await app._interface.
|
|
1420
|
-
await app.
|
|
1410
|
+
const res = await app._interface.revokeApiKeyById(data.id);
|
|
1411
|
+
await app._refreshApiKeys();
|
|
1421
1412
|
return res;
|
|
1422
1413
|
}
|
|
1423
1414
|
};
|
|
1424
1415
|
}
|
|
1425
|
-
|
|
1416
|
+
_createApiKeyFromCrud(data) {
|
|
1426
1417
|
return {
|
|
1427
|
-
...this.
|
|
1428
|
-
publishableClientKey: data.
|
|
1429
|
-
secretServerKey: data.
|
|
1430
|
-
superSecretAdminKey: data.
|
|
1418
|
+
...this._createApiKeyBaseFromCrud(data),
|
|
1419
|
+
publishableClientKey: data.publishable_client_key ? { lastFour: data.publishable_client_key.last_four } : null,
|
|
1420
|
+
secretServerKey: data.secret_server_key ? { lastFour: data.secret_server_key.last_four } : null,
|
|
1421
|
+
superSecretAdminKey: data.super_secret_admin_key ? { lastFour: data.super_secret_admin_key.last_four } : null
|
|
1431
1422
|
};
|
|
1432
1423
|
}
|
|
1433
|
-
|
|
1424
|
+
_createApiKeyFirstViewFromCrud(data) {
|
|
1434
1425
|
return {
|
|
1435
|
-
...this.
|
|
1436
|
-
publishableClientKey: data.
|
|
1437
|
-
secretServerKey: data.
|
|
1438
|
-
superSecretAdminKey: data.
|
|
1426
|
+
...this._createApiKeyBaseFromCrud(data),
|
|
1427
|
+
publishableClientKey: data.publishable_client_key,
|
|
1428
|
+
secretServerKey: data.secret_server_key,
|
|
1429
|
+
superSecretAdminKey: data.super_secret_admin_key
|
|
1439
1430
|
};
|
|
1440
1431
|
}
|
|
1441
|
-
async
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
this._interface,
|
|
1445
|
-
() => this._refreshProject()
|
|
1446
|
-
);
|
|
1432
|
+
async listApiKeys() {
|
|
1433
|
+
const crud = await this._apiKeysCache.getOrWait([], "write-only");
|
|
1434
|
+
return crud.map((j) => this._createApiKeyFromCrud(j));
|
|
1447
1435
|
}
|
|
1448
|
-
|
|
1449
|
-
const
|
|
1450
|
-
return useMemo(() =>
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
() => this._refreshProject()
|
|
1454
|
-
), [json]);
|
|
1436
|
+
useApiKeys() {
|
|
1437
|
+
const crud = useAsyncCache(this._apiKeysCache, [], "useApiKeys()");
|
|
1438
|
+
return useMemo(() => {
|
|
1439
|
+
return crud.map((j) => this._createApiKeyFromCrud(j));
|
|
1440
|
+
}, [crud]);
|
|
1455
1441
|
}
|
|
1456
|
-
async
|
|
1457
|
-
const
|
|
1458
|
-
|
|
1442
|
+
async createApiKey(options) {
|
|
1443
|
+
const crud = await this._interface.createApiKey(apiKeyCreateOptionsToCrud(options));
|
|
1444
|
+
await this._refreshApiKeys();
|
|
1445
|
+
return this._createApiKeyFirstViewFromCrud(crud);
|
|
1459
1446
|
}
|
|
1460
|
-
|
|
1461
|
-
const
|
|
1447
|
+
useEmailTemplates() {
|
|
1448
|
+
const crud = useAsyncCache(this._adminEmailTemplatesCache, [], "useEmailTemplates()");
|
|
1462
1449
|
return useMemo(() => {
|
|
1463
|
-
return
|
|
1464
|
-
}, [
|
|
1450
|
+
return crud.map((j) => this._adminEmailTemplateFromCrud(j));
|
|
1451
|
+
}, [crud]);
|
|
1465
1452
|
}
|
|
1466
|
-
async
|
|
1467
|
-
const
|
|
1468
|
-
|
|
1469
|
-
|
|
1453
|
+
async listEmailTemplates() {
|
|
1454
|
+
const crud = await this._adminEmailTemplatesCache.getOrWait([], "write-only");
|
|
1455
|
+
return crud.map((j) => this._adminEmailTemplateFromCrud(j));
|
|
1456
|
+
}
|
|
1457
|
+
async updateEmailTemplate(type, data) {
|
|
1458
|
+
await this._interface.updateEmailTemplate(type, adminEmailTemplateUpdateOptionsToCrud(data));
|
|
1459
|
+
await this._adminEmailTemplatesCache.refresh([]);
|
|
1460
|
+
}
|
|
1461
|
+
async resetEmailTemplate(type) {
|
|
1462
|
+
await this._interface.resetEmailTemplate(type);
|
|
1463
|
+
await this._adminEmailTemplatesCache.refresh([]);
|
|
1464
|
+
}
|
|
1465
|
+
async createTeamPermissionDefinition(data) {
|
|
1466
|
+
const crud = await this._interface.createPermissionDefinition(serverTeamPermissionDefinitionCreateOptionsToCrud(data));
|
|
1467
|
+
await this._adminTeamPermissionDefinitionsCache.refresh([]);
|
|
1468
|
+
return this._serverTeamPermissionDefinitionFromCrud(crud);
|
|
1469
|
+
}
|
|
1470
|
+
async updateTeamPermissionDefinition(permissionId, data) {
|
|
1471
|
+
await this._interface.updatePermissionDefinition(permissionId, data);
|
|
1472
|
+
await this._adminTeamPermissionDefinitionsCache.refresh([]);
|
|
1473
|
+
}
|
|
1474
|
+
async deleteTeamPermissionDefinition(permissionId) {
|
|
1475
|
+
await this._interface.deletePermissionDefinition(permissionId);
|
|
1476
|
+
await this._adminTeamPermissionDefinitionsCache.refresh([]);
|
|
1477
|
+
}
|
|
1478
|
+
async listTeamPermissionDefinitions() {
|
|
1479
|
+
const crud = await this._adminTeamPermissionDefinitionsCache.getOrWait([], "write-only");
|
|
1480
|
+
return crud.map((p) => this._serverTeamPermissionDefinitionFromCrud(p));
|
|
1481
|
+
}
|
|
1482
|
+
useTeamPermissionDefinitions() {
|
|
1483
|
+
const crud = useAsyncCache(this._adminTeamPermissionDefinitionsCache, [], "usePermissions()");
|
|
1484
|
+
return useMemo(() => {
|
|
1485
|
+
return crud.map((p) => this._serverTeamPermissionDefinitionFromCrud(p));
|
|
1486
|
+
}, [crud]);
|
|
1470
1487
|
}
|
|
1471
1488
|
async _refreshProject() {
|
|
1472
1489
|
await Promise.all([
|
|
@@ -1474,17 +1491,125 @@ var _StackAdminAppImpl = class extends _StackServerAppImpl {
|
|
|
1474
1491
|
this._adminProjectCache.refresh([])
|
|
1475
1492
|
]);
|
|
1476
1493
|
}
|
|
1477
|
-
async
|
|
1478
|
-
await this.
|
|
1494
|
+
async _refreshApiKeys() {
|
|
1495
|
+
await this._apiKeysCache.refresh([]);
|
|
1479
1496
|
}
|
|
1480
1497
|
};
|
|
1498
|
+
function userUpdateOptionsToCrud(options) {
|
|
1499
|
+
return {
|
|
1500
|
+
display_name: options.displayName,
|
|
1501
|
+
client_metadata: options.clientMetadata,
|
|
1502
|
+
selected_team_id: options.selectedTeamId
|
|
1503
|
+
};
|
|
1504
|
+
}
|
|
1505
|
+
function serverUserUpdateOptionsToCrud(options) {
|
|
1506
|
+
return {
|
|
1507
|
+
display_name: options.displayName,
|
|
1508
|
+
client_metadata: options.clientMetadata,
|
|
1509
|
+
selected_team_id: options.selectedTeamId,
|
|
1510
|
+
primary_email: options.primaryEmail,
|
|
1511
|
+
primary_email_verified: options.primaryEmailVerified,
|
|
1512
|
+
server_metadata: options.serverMetadata
|
|
1513
|
+
};
|
|
1514
|
+
}
|
|
1515
|
+
function adminProjectUpdateOptionsToCrud(options) {
|
|
1516
|
+
return {
|
|
1517
|
+
display_name: options.displayName,
|
|
1518
|
+
description: options.description,
|
|
1519
|
+
is_production_mode: options.isProductionMode,
|
|
1520
|
+
config: {
|
|
1521
|
+
domains: options.config?.domains?.map((d) => ({
|
|
1522
|
+
domain: d.domain,
|
|
1523
|
+
handler_path: d.handlerPath
|
|
1524
|
+
})),
|
|
1525
|
+
oauth_providers: options.config?.oauthProviders?.map((p) => ({
|
|
1526
|
+
id: p.id,
|
|
1527
|
+
enabled: p.enabled,
|
|
1528
|
+
type: p.type,
|
|
1529
|
+
...p.type === "standard" && {
|
|
1530
|
+
client_id: p.clientId,
|
|
1531
|
+
client_secret: p.clientSecret
|
|
1532
|
+
}
|
|
1533
|
+
})),
|
|
1534
|
+
email_config: options.config?.emailConfig && (options.config.emailConfig.type === "shared" ? {
|
|
1535
|
+
type: "shared"
|
|
1536
|
+
} : {
|
|
1537
|
+
type: "standard",
|
|
1538
|
+
host: options.config.emailConfig.host,
|
|
1539
|
+
port: options.config.emailConfig.port,
|
|
1540
|
+
username: options.config.emailConfig.username,
|
|
1541
|
+
password: options.config.emailConfig.password,
|
|
1542
|
+
sender_name: options.config.emailConfig.senderName,
|
|
1543
|
+
sender_email: options.config.emailConfig.senderEmail
|
|
1544
|
+
}),
|
|
1545
|
+
credential_enabled: options.config?.credentialEnabled,
|
|
1546
|
+
magic_link_enabled: options.config?.magicLinkEnabled,
|
|
1547
|
+
allow_localhost: options.config?.allowLocalhost,
|
|
1548
|
+
create_team_on_sign_up: options.config?.createTeamOnSignUp,
|
|
1549
|
+
team_creator_default_permissions: options.config?.teamCreatorDefaultPermissions,
|
|
1550
|
+
team_member_default_permissions: options.config?.teamMemberDefaultPermissions
|
|
1551
|
+
}
|
|
1552
|
+
};
|
|
1553
|
+
}
|
|
1554
|
+
function adminProjectCreateOptionsToCrud(options) {
|
|
1555
|
+
return {
|
|
1556
|
+
...adminProjectUpdateOptionsToCrud(options),
|
|
1557
|
+
display_name: options.displayName
|
|
1558
|
+
};
|
|
1559
|
+
}
|
|
1560
|
+
function apiKeyCreateOptionsToCrud(options) {
|
|
1561
|
+
return {
|
|
1562
|
+
description: options.description,
|
|
1563
|
+
expires_at_millis: options.expiresAt.getTime(),
|
|
1564
|
+
has_publishable_client_key: options.hasPublishableClientKey,
|
|
1565
|
+
has_secret_server_key: options.hasSecretServerKey,
|
|
1566
|
+
has_super_secret_admin_key: options.hasSuperSecretAdminKey
|
|
1567
|
+
};
|
|
1568
|
+
}
|
|
1569
|
+
function teamCreateOptionsToCrud(options) {
|
|
1570
|
+
return {
|
|
1571
|
+
display_name: options.displayName,
|
|
1572
|
+
profile_image_url: options.profileImageUrl
|
|
1573
|
+
};
|
|
1574
|
+
}
|
|
1575
|
+
function serverTeamCreateOptionsToCrud(options) {
|
|
1576
|
+
return teamCreateOptionsToCrud(options);
|
|
1577
|
+
}
|
|
1578
|
+
function serverTeamUpdateOptionsToCrud(options) {
|
|
1579
|
+
return {
|
|
1580
|
+
display_name: options.displayName,
|
|
1581
|
+
profile_image_url: options.profileImageUrl
|
|
1582
|
+
};
|
|
1583
|
+
}
|
|
1584
|
+
function serverTeamPermissionDefinitionCreateOptionsToCrud(options) {
|
|
1585
|
+
return {
|
|
1586
|
+
id: options.id,
|
|
1587
|
+
description: options.description,
|
|
1588
|
+
contained_permission_ids: options.containedPermissionIds
|
|
1589
|
+
};
|
|
1590
|
+
}
|
|
1591
|
+
function serverTeamPermissionDefinitionUpdateOptionsToCrud(options) {
|
|
1592
|
+
return {
|
|
1593
|
+
id: options.id,
|
|
1594
|
+
description: options.description,
|
|
1595
|
+
contained_permission_ids: options.containedPermissionIds
|
|
1596
|
+
};
|
|
1597
|
+
}
|
|
1481
1598
|
var StackClientApp = _StackClientAppImpl;
|
|
1482
1599
|
var StackServerApp = _StackServerAppImpl;
|
|
1483
1600
|
var StackAdminApp = _StackAdminAppImpl;
|
|
1601
|
+
function adminEmailTemplateUpdateOptionsToCrud(options) {
|
|
1602
|
+
return {
|
|
1603
|
+
subject: options.subject,
|
|
1604
|
+
content: options.content
|
|
1605
|
+
};
|
|
1606
|
+
}
|
|
1484
1607
|
export {
|
|
1485
1608
|
StackAdminApp,
|
|
1486
1609
|
StackClientApp,
|
|
1487
1610
|
StackServerApp,
|
|
1611
|
+
serverTeamPermissionDefinitionCreateOptionsToCrud,
|
|
1612
|
+
serverTeamPermissionDefinitionUpdateOptionsToCrud,
|
|
1488
1613
|
stackAppInternalsSymbol
|
|
1489
1614
|
};
|
|
1490
1615
|
//# sourceMappingURL=stack-app.js.map
|