@stackframe/stack 2.4.20 → 2.4.22
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 +18 -0
- package/dist/components/message-cards/known-error-message-card.d.mts +9 -0
- package/dist/components/message-cards/known-error-message-card.d.ts +9 -0
- package/dist/components/message-cards/known-error-message-card.js +67 -0
- package/dist/components/message-cards/known-error-message-card.js.map +1 -0
- package/dist/components/{message-card.d.mts → message-cards/message-card.d.mts} +5 -1
- package/dist/components/{message-card.d.ts → message-cards/message-card.d.ts} +5 -1
- package/dist/components/{message-card.js → message-cards/message-card.js} +10 -6
- package/dist/components/message-cards/message-card.js.map +1 -0
- package/dist/components/{redirect-message-card.d.mts → message-cards/predefined-message-card.d.mts} +3 -3
- package/dist/components/{redirect-message-card.d.ts → message-cards/predefined-message-card.d.ts} +3 -3
- package/dist/components/{redirect-message-card.js → message-cards/predefined-message-card.js} +32 -29
- package/dist/components/message-cards/predefined-message-card.js.map +1 -0
- package/dist/components/password-reset-inner.js +3 -3
- package/dist/components/password-reset-inner.js.map +1 -1
- package/dist/components-core/index.d.mts +4 -4
- package/dist/components-core/index.d.ts +4 -4
- package/dist/components-core-joy/text.d.mts +2 -2
- package/dist/components-core-joy/text.d.ts +2 -2
- package/dist/components-page/account-settings.js +2 -2
- package/dist/components-page/account-settings.js.map +1 -1
- package/dist/components-page/auth-page.js +2 -2
- package/dist/components-page/auth-page.js.map +1 -1
- package/dist/components-page/email-verification.js +3 -3
- package/dist/components-page/email-verification.js.map +1 -1
- package/dist/components-page/error-page.d.mts +8 -0
- package/dist/components-page/error-page.d.ts +8 -0
- package/dist/components-page/error-page.js +85 -0
- package/dist/components-page/error-page.js.map +1 -0
- package/dist/components-page/forgot-password.js +3 -3
- package/dist/components-page/forgot-password.js.map +1 -1
- package/dist/components-page/magic-link-callback.js +3 -3
- package/dist/components-page/magic-link-callback.js.map +1 -1
- package/dist/components-page/oauth-callback.js +4 -3
- package/dist/components-page/oauth-callback.js.map +1 -1
- package/dist/components-page/password-reset.js +1 -1
- package/dist/components-page/password-reset.js.map +1 -1
- package/dist/components-page/sign-out.js +2 -2
- package/dist/components-page/sign-out.js.map +1 -1
- package/dist/components-page/stack-handler.js +5 -1
- package/dist/components-page/stack-handler.js.map +1 -1
- package/dist/esm/components/message-cards/known-error-message-card.js +37 -0
- package/dist/esm/components/message-cards/known-error-message-card.js.map +1 -0
- package/dist/esm/components/message-cards/message-card.js +21 -0
- package/dist/esm/components/message-cards/message-card.js.map +1 -0
- package/dist/esm/components/{redirect-message-card.js → message-cards/predefined-message-card.js} +30 -27
- package/dist/esm/components/message-cards/predefined-message-card.js.map +1 -0
- package/dist/esm/components/password-reset-inner.js +3 -3
- package/dist/esm/components/password-reset-inner.js.map +1 -1
- package/dist/esm/components-page/account-settings.js +2 -2
- package/dist/esm/components-page/account-settings.js.map +1 -1
- package/dist/esm/components-page/auth-page.js +2 -2
- package/dist/esm/components-page/auth-page.js.map +1 -1
- package/dist/esm/components-page/email-verification.js +3 -3
- package/dist/esm/components-page/email-verification.js.map +1 -1
- package/dist/esm/components-page/error-page.js +55 -0
- package/dist/esm/components-page/error-page.js.map +1 -0
- package/dist/esm/components-page/forgot-password.js +3 -3
- package/dist/esm/components-page/forgot-password.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/oauth-callback.js +4 -3
- package/dist/esm/components-page/oauth-callback.js.map +1 -1
- package/dist/esm/components-page/password-reset.js +1 -1
- package/dist/esm/components-page/password-reset.js.map +1 -1
- package/dist/esm/components-page/sign-out.js +1 -1
- package/dist/esm/components-page/sign-out.js.map +1 -1
- package/dist/esm/components-page/stack-handler.js +5 -1
- package/dist/esm/components-page/stack-handler.js.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/auth.js +30 -14
- package/dist/esm/lib/auth.js.map +1 -1
- package/dist/esm/lib/stack-app.js +142 -68
- package/dist/esm/lib/stack-app.js.map +1 -1
- package/dist/esm/providers/stack-provider-client.js +1 -1
- package/dist/esm/providers/stack-provider-client.js.map +1 -1
- package/dist/esm/providers/styled-components-registry.js +1 -1
- package/dist/esm/providers/styled-components-registry.js.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/auth.d.mts +13 -3
- package/dist/lib/auth.d.ts +13 -3
- package/dist/lib/auth.js +31 -14
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/stack-app.d.mts +111 -65
- package/dist/lib/stack-app.d.ts +111 -65
- package/dist/lib/stack-app.js +139 -65
- package/dist/lib/stack-app.js.map +1 -1
- package/dist/providers/component-provider.d.mts +6 -6
- package/dist/providers/component-provider.d.ts +6 -6
- package/dist/providers/joy-provider.d.mts +2 -2
- package/dist/providers/joy-provider.d.ts +2 -2
- package/dist/providers/stack-provider-client.js +1 -1
- package/dist/providers/stack-provider-client.js.map +1 -1
- package/dist/providers/styled-components-registry.js +1 -1
- package/dist/providers/styled-components-registry.js.map +1 -1
- package/package.json +3 -3
- package/dist/components/message-card.js.map +0 -1
- package/dist/components/redirect-message-card.js.map +0 -1
- package/dist/esm/components/message-card.js +0 -17
- package/dist/esm/components/message-card.js.map +0 -1
- package/dist/esm/components/redirect-message-card.js.map +0 -1
package/dist/lib/stack-app.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ServerUserJson, OAuthProviderConfigJson, KnownErrors } from '@stackframe/stack-shared';
|
|
2
|
-
import { UserJson, UserUpdateJson, ProjectJson, ProductionModeError, TeamJson, EmailConfigJson, DomainConfigJson, ClientProjectJson } from '@stackframe/stack-shared/dist/interface/clientInterface';
|
|
2
|
+
import { StandardProvider, UserJson, UserUpdateJson, ProjectJson, ProductionModeError, TeamJson, EmailConfigJson, DomainConfigJson, ClientProjectJson } from '@stackframe/stack-shared/dist/interface/clientInterface';
|
|
3
3
|
import { ReadonlyJson } from '@stackframe/stack-shared/dist/utils/json';
|
|
4
4
|
import { ProjectUpdateOptions, ApiKeySetCreateOptions } from '@stackframe/stack-shared/dist/interface/adminInterface';
|
|
5
5
|
import { ServerUserUpdateJson, ServerTeamCustomizableJson, ServerPermissionDefinitionCustomizableJson, ServerPermissionDefinitionJson, EmailTemplateType } from '@stackframe/stack-shared/dist/interface/serverInterface';
|
|
@@ -30,6 +30,10 @@ type HandlerUrls = {
|
|
|
30
30
|
oauthCallback: string;
|
|
31
31
|
magicLinkCallback: string;
|
|
32
32
|
accountSettings: string;
|
|
33
|
+
error: string;
|
|
34
|
+
};
|
|
35
|
+
type OAuthScopesOnSignIn = {
|
|
36
|
+
[key in StandardProvider]: string[];
|
|
33
37
|
};
|
|
34
38
|
type ProjectCurrentUser<ProjectId> = ProjectId extends "internal" ? CurrentInternalUser : CurrentUser;
|
|
35
39
|
type StackClientAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = {
|
|
@@ -37,6 +41,7 @@ type StackClientAppConstructorOptions<HasTokenStore extends boolean, ProjectId e
|
|
|
37
41
|
projectId?: ProjectId;
|
|
38
42
|
publishableClientKey?: string;
|
|
39
43
|
urls?: Partial<HandlerUrls>;
|
|
44
|
+
oauthScopesOnSignIn?: Partial<OAuthScopesOnSignIn>;
|
|
40
45
|
tokenStore: TokenStoreInit<HasTokenStore>;
|
|
41
46
|
};
|
|
42
47
|
type StackServerAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppConstructorOptions<HasTokenStore, ProjectId> & {
|
|
@@ -67,6 +72,77 @@ type Auth<T, C> = {
|
|
|
67
72
|
readonly _internalSession: InternalSession;
|
|
68
73
|
readonly currentSession: Session;
|
|
69
74
|
signOut(this: T): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Returns headers for sending authenticated HTTP requests to external servers. Most commonly used in cross-origin
|
|
77
|
+
* requests. Similar to `getAuthJson`, but specifically for HTTP requests.
|
|
78
|
+
*
|
|
79
|
+
* If you are using `tokenStore: "cookie"`, you don't need this for same-origin requests. However, most
|
|
80
|
+
* browsers now disable third-party cookies by default, so we must pass authentication tokens by header instead
|
|
81
|
+
* if the client and server are on different hostnames.
|
|
82
|
+
*
|
|
83
|
+
* This function returns a header object that can be used with `fetch` or other HTTP request libraries to send
|
|
84
|
+
* authenticated requests.
|
|
85
|
+
*
|
|
86
|
+
* On the server, you can then pass in the `Request` object to the `tokenStore` option
|
|
87
|
+
* of your Stack app. Please note that CORS does not allow most headers by default, so you
|
|
88
|
+
* must include `x-stack-auth` in the [`Access-Control-Allow-Headers` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers)
|
|
89
|
+
* of the CORS preflight response.
|
|
90
|
+
*
|
|
91
|
+
* If you are not using HTTP (and hence cannot set headers), you will need to use the `getAuthJson()` function
|
|
92
|
+
* instead.
|
|
93
|
+
*
|
|
94
|
+
* Example:
|
|
95
|
+
*
|
|
96
|
+
* ```ts
|
|
97
|
+
* // client
|
|
98
|
+
* const res = await fetch("https://api.example.com", {
|
|
99
|
+
* headers: {
|
|
100
|
+
* ...await stackApp.getAuthHeaders()
|
|
101
|
+
* // you can also add your own headers here
|
|
102
|
+
* },
|
|
103
|
+
* });
|
|
104
|
+
*
|
|
105
|
+
* // server
|
|
106
|
+
* function handleRequest(req: Request) {
|
|
107
|
+
* const user = await stackServerApp.getUser({ tokenStore: req });
|
|
108
|
+
* return new Response("Welcome, " + user.displayName);
|
|
109
|
+
* }
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
getAuthHeaders(): Promise<{
|
|
113
|
+
"x-stack-auth": string;
|
|
114
|
+
}>;
|
|
115
|
+
/**
|
|
116
|
+
* Creates a JSON-serializable object containing the information to authenticate a user on an external server.
|
|
117
|
+
* Similar to `getAuthHeaders`, but returns an object that can be sent over any protocol instead of just
|
|
118
|
+
* HTTP headers.
|
|
119
|
+
*
|
|
120
|
+
* While `getAuthHeaders` is the recommended way to send authentication tokens over HTTP, your app may use
|
|
121
|
+
* a different protocol, for example WebSockets or gRPC. This function returns a token object that can be JSON-serialized and sent to the server in any way you like.
|
|
122
|
+
*
|
|
123
|
+
* On the server, you can pass in this token object into the `tokenStore` option to fetch user details.
|
|
124
|
+
*
|
|
125
|
+
* Example:
|
|
126
|
+
*
|
|
127
|
+
* ```ts
|
|
128
|
+
* // client
|
|
129
|
+
* const res = await rpcCall(rpcEndpoint, {
|
|
130
|
+
* data: {
|
|
131
|
+
* auth: await stackApp.getAuthJson(),
|
|
132
|
+
* },
|
|
133
|
+
* });
|
|
134
|
+
*
|
|
135
|
+
* // server
|
|
136
|
+
* function handleRequest(data) {
|
|
137
|
+
* const user = await stackServerApp.getUser({ tokenStore: data.auth });
|
|
138
|
+
* return new Response("Welcome, " + user.displayName);
|
|
139
|
+
* }
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
getAuthJson(): Promise<{
|
|
143
|
+
accessToken: string | null;
|
|
144
|
+
refreshToken: string | null;
|
|
145
|
+
}>;
|
|
70
146
|
update(this: T, user: C): Promise<void>;
|
|
71
147
|
updateSelectedTeam(this: T, team: Team | null): Promise<void>;
|
|
72
148
|
sendVerificationEmail(this: T): Promise<KnownErrors["EmailAlreadyVerified"] | void>;
|
|
@@ -104,6 +180,28 @@ type User = ({
|
|
|
104
180
|
hasPermission(this: CurrentUser, scope: Team, permissionId: string): Promise<boolean>;
|
|
105
181
|
getSelectedTeam(this: CurrentUser): Promise<Team | null>;
|
|
106
182
|
useSelectedTeam(this: CurrentUser): Team | null;
|
|
183
|
+
getConnection(id: StandardProvider, options?: {
|
|
184
|
+
scopes?: string[];
|
|
185
|
+
}): Promise<OAuthConnection | null>;
|
|
186
|
+
getConnection(id: StandardProvider, options: {
|
|
187
|
+
or: 'redirect';
|
|
188
|
+
scopes?: string[];
|
|
189
|
+
}): Promise<OAuthConnection>;
|
|
190
|
+
getConnection(id: StandardProvider, options?: {
|
|
191
|
+
or?: 'redirect';
|
|
192
|
+
scopes?: string[];
|
|
193
|
+
}): Promise<OAuthConnection | null>;
|
|
194
|
+
useConnection(id: StandardProvider, options?: {
|
|
195
|
+
scopes?: string[];
|
|
196
|
+
}): OAuthConnection | null;
|
|
197
|
+
useConnection(id: StandardProvider, options: {
|
|
198
|
+
or: 'redirect';
|
|
199
|
+
scopes?: string[];
|
|
200
|
+
}): OAuthConnection;
|
|
201
|
+
useConnection(id: StandardProvider, options?: {
|
|
202
|
+
or?: 'redirect';
|
|
203
|
+
scopes?: string[];
|
|
204
|
+
}): OAuthConnection | null;
|
|
107
205
|
toJson(this: CurrentUser): UserJson;
|
|
108
206
|
} & AsyncStoreProperty<"team", [id: string], Team | null, false> & AsyncStoreProperty<"teams", [], Team[], true> & Omit<AsyncStoreProperty<"permission", [scope: Team, permissionId: string, options?: {
|
|
109
207
|
direct?: boolean;
|
|
@@ -193,6 +291,17 @@ type ServerPermission = Permission & {
|
|
|
193
291
|
readonly description?: string;
|
|
194
292
|
readonly containPermissionIds: string[];
|
|
195
293
|
};
|
|
294
|
+
type Connection = {
|
|
295
|
+
id: string;
|
|
296
|
+
};
|
|
297
|
+
type OAuthConnection = Connection & {
|
|
298
|
+
getAccessToken(): Promise<{
|
|
299
|
+
accessToken: string;
|
|
300
|
+
}>;
|
|
301
|
+
useAccessToken(): {
|
|
302
|
+
accessToken: string;
|
|
303
|
+
};
|
|
304
|
+
};
|
|
196
305
|
type ApiKeySetBase = {
|
|
197
306
|
id: string;
|
|
198
307
|
description: string;
|
|
@@ -262,69 +371,6 @@ type StackClientApp<HasTokenStore extends boolean = boolean, ProjectId extends s
|
|
|
262
371
|
verifyPasswordResetCode(code: string): Promise<KnownErrors["PasswordResetCodeError"] | void>;
|
|
263
372
|
verifyEmail(code: string): Promise<KnownErrors["EmailVerificationError"] | void>;
|
|
264
373
|
signInWithMagicLink(code: string): Promise<KnownErrors["MagicLinkError"] | void>;
|
|
265
|
-
/**
|
|
266
|
-
* With most browsers now disabling third-party cookies by default, the best way to send authenticated requests
|
|
267
|
-
* across different origins is to pass the tokens in a header.
|
|
268
|
-
*
|
|
269
|
-
* This function returns a header object that can be used with `fetch` or other HTTP request libraries to send
|
|
270
|
-
* authenticated requests.
|
|
271
|
-
*
|
|
272
|
-
* On the server, you can then pass in the `Request` object to the `tokenStore` option
|
|
273
|
-
* on your Stack app to fetch user details. Please note that CORS by default does not allow custom headers, so you
|
|
274
|
-
* must set the [`Access-Control-Allow-Headers` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers)
|
|
275
|
-
* to include `x-stack-auth` in the CORS preflight response.
|
|
276
|
-
*
|
|
277
|
-
* Example:
|
|
278
|
-
*
|
|
279
|
-
* ```ts
|
|
280
|
-
* // client
|
|
281
|
-
* const res = await fetch("https://api.example.com", {
|
|
282
|
-
* headers: {
|
|
283
|
-
* ...await stackApp.getCrossOriginHeaders()
|
|
284
|
-
* // you can also add your own headers here
|
|
285
|
-
* },
|
|
286
|
-
* });
|
|
287
|
-
*
|
|
288
|
-
* // server
|
|
289
|
-
* function handleRequest(req: Request) {
|
|
290
|
-
* const user = await stackServerApp.getUser({ tokenStore: req });
|
|
291
|
-
* return new Response("Welcome, " + user.displayName);
|
|
292
|
-
* }
|
|
293
|
-
* ```
|
|
294
|
-
*/
|
|
295
|
-
getCrossOriginHeaders(): Promise<{
|
|
296
|
-
"x-stack-auth": string;
|
|
297
|
-
}>;
|
|
298
|
-
/**
|
|
299
|
-
* With most browsers now disabling third-party cookies by default, there need to be new ways to send authenticated
|
|
300
|
-
* requests across different origins. While `getCrossOriginHeaders` is the recommended way to do this, there
|
|
301
|
-
* are some cases where you might want to send the tokens differently, for example when you are using WebSockets
|
|
302
|
-
* or non-HTTP protocols.
|
|
303
|
-
*
|
|
304
|
-
* This function returns a token object that can be JSON-serialized and sent to the server in any way you like.
|
|
305
|
-
* There, you can use the `tokenStore` option on your Stack app to fetch user details.
|
|
306
|
-
*
|
|
307
|
-
* Example:
|
|
308
|
-
*
|
|
309
|
-
* ```ts
|
|
310
|
-
* // client
|
|
311
|
-
* const res = await rpcCall(rpcEndpoint, {
|
|
312
|
-
* data: {
|
|
313
|
-
* auth: await stackApp.getCrossOriginTokenObject(),
|
|
314
|
-
* },
|
|
315
|
-
* });
|
|
316
|
-
*
|
|
317
|
-
* // server
|
|
318
|
-
* function handleRequest(data) {
|
|
319
|
-
* const user = await stackServerApp.getUser({ tokenStore: data.auth });
|
|
320
|
-
* return new Response("Welcome, " + user.displayName);
|
|
321
|
-
* }
|
|
322
|
-
* ```
|
|
323
|
-
*/
|
|
324
|
-
getCrossOriginTokenObject(): Promise<{
|
|
325
|
-
accessToken: string | null;
|
|
326
|
-
refreshToken: string | null;
|
|
327
|
-
}>;
|
|
328
374
|
[stackAppInternalsSymbol]: {
|
|
329
375
|
toClientJson(): StackClientAppJson<HasTokenStore, ProjectId>;
|
|
330
376
|
setCurrentUser(userJsonPromise: Promise<UserJson | null>): void;
|
|
@@ -376,4 +422,4 @@ type StackAdminApp<HasTokenStore extends boolean = boolean, ProjectId extends st
|
|
|
376
422
|
});
|
|
377
423
|
declare const StackAdminApp: StackAdminAppConstructor;
|
|
378
424
|
|
|
379
|
-
export { type ApiKeySet, type ApiKeySetBase, type ApiKeySetFirstView, type CurrentInternalServerUser, type CurrentInternalUser, type CurrentServerUser, type CurrentUser, type DomainConfig, type EmailConfig, type GetUserOptions, type HandlerUrls, type OAuthProviderConfig, type Permission, type Project, type ServerPermission, type ServerTeam, type ServerTeamMember, type ServerUser, StackAdminApp, type StackAdminAppConstructorOptions, StackClientApp, type StackClientAppConstructorOptions, type StackClientAppJson, StackServerApp, type StackServerAppConstructorOptions, type Team, type TeamMember, type TokenStoreInit, type User, stackAppInternalsSymbol };
|
|
425
|
+
export { type ApiKeySet, type ApiKeySetBase, type ApiKeySetFirstView, type Connection, type CurrentInternalServerUser, type CurrentInternalUser, type CurrentServerUser, type CurrentUser, type DomainConfig, type EmailConfig, type GetUserOptions, type HandlerUrls, type OAuthConnection, type OAuthProviderConfig, type OAuthScopesOnSignIn, type Permission, type Project, type ServerPermission, type ServerTeam, type ServerTeamMember, type ServerUser, StackAdminApp, type StackAdminAppConstructorOptions, StackClientApp, type StackClientAppConstructorOptions, type StackClientAppJson, StackServerApp, type StackServerAppConstructorOptions, type Team, type TeamMember, type TokenStoreInit, type User, stackAppInternalsSymbol };
|
package/dist/lib/stack-app.js
CHANGED
|
@@ -45,7 +45,7 @@ var import_results = require("@stackframe/stack-shared/dist/utils/results");
|
|
|
45
45
|
var import_react2 = require("@stackframe/stack-shared/dist/utils/react");
|
|
46
46
|
var import_stores = require("@stackframe/stack-shared/dist/utils/stores");
|
|
47
47
|
var import_clientInterface = require("@stackframe/stack-shared/dist/interface/clientInterface");
|
|
48
|
-
var import_env = require("@stackframe/stack-shared/
|
|
48
|
+
var import_env = require("@stackframe/stack-shared/dist/utils/env");
|
|
49
49
|
var import_auth = require("./auth");
|
|
50
50
|
var NextNavigationUnscrambled = __toESM(require("next/navigation"));
|
|
51
51
|
var import_url = require("../utils/url");
|
|
@@ -58,8 +58,9 @@ var import_stack_sc = require("@stackframe/stack-sc");
|
|
|
58
58
|
var cookie = __toESM(require("cookie"));
|
|
59
59
|
var import_sessions = require("@stackframe/stack-shared/dist/sessions");
|
|
60
60
|
var import_use_trigger = require("@stackframe/stack-shared/dist/hooks/use-trigger");
|
|
61
|
+
var import_strings = require("@stackframe/stack-shared/src/utils/strings");
|
|
61
62
|
var NextNavigation = (0, import_compile_time.scrambleDuringCompileTime)(NextNavigationUnscrambled);
|
|
62
|
-
var clientVersion = "js @stackframe/stack@2.4.
|
|
63
|
+
var clientVersion = "js @stackframe/stack@2.4.22";
|
|
63
64
|
function permissionDefinitionScopeToType(scope) {
|
|
64
65
|
return { "any-team": "team", "specific-team": "team", "global": "global" }[scope.type];
|
|
65
66
|
}
|
|
@@ -80,9 +81,22 @@ function getUrls(partial) {
|
|
|
80
81
|
magicLinkCallback: `${handler}/magic-link-callback`,
|
|
81
82
|
home: "/",
|
|
82
83
|
accountSettings: `${handler}/account-settings`,
|
|
84
|
+
error: `${handler}/error`,
|
|
83
85
|
...(0, import_objects.filterUndefined)(partial)
|
|
84
86
|
};
|
|
85
87
|
}
|
|
88
|
+
async function _redirectTo(url, options) {
|
|
89
|
+
if (import_stack_sc.isReactServer) {
|
|
90
|
+
NextNavigation.redirect(url, options?.replace ? NextNavigation.RedirectType.replace : NextNavigation.RedirectType.push);
|
|
91
|
+
} else {
|
|
92
|
+
if (options?.replace) {
|
|
93
|
+
window.location.replace(url);
|
|
94
|
+
} else {
|
|
95
|
+
window.location.assign(url);
|
|
96
|
+
}
|
|
97
|
+
await (0, import_promises.wait)(2e3);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
86
100
|
function getDefaultProjectId() {
|
|
87
101
|
return process.env.NEXT_PUBLIC_STACK_PROJECT_ID || (0, import_errors.throwErr)(new Error("Welcome to Stack! It seems that you haven't provided a project ID. Please create a project on the Stack dashboard at https://app.stack-auth.com and put it in the NEXT_PUBLIC_STACK_PROJECT_ID environment variable."));
|
|
88
102
|
}
|
|
@@ -157,6 +171,7 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
157
171
|
}
|
|
158
172
|
this._tokenStoreInit = _options.tokenStore;
|
|
159
173
|
this._urlOptions = _options.urls ?? {};
|
|
174
|
+
this._oauthScopesOnSignIn = _options.oauthScopesOnSignIn ?? {};
|
|
160
175
|
if (_options.uniqueIdentifier) {
|
|
161
176
|
this._uniqueIdentifier = _options.uniqueIdentifier;
|
|
162
177
|
this._initUniqueIdentifier();
|
|
@@ -170,6 +185,7 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
170
185
|
_interface;
|
|
171
186
|
_tokenStoreInit;
|
|
172
187
|
_urlOptions;
|
|
188
|
+
_oauthScopesOnSignIn;
|
|
173
189
|
__DEMO_ENABLE_SLIGHT_FETCH_DELAY = false;
|
|
174
190
|
_currentUserCache = createCacheBySession(async (session) => {
|
|
175
191
|
if (this.__DEMO_ENABLE_SLIGHT_FETCH_DELAY) {
|
|
@@ -190,6 +206,64 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
190
206
|
_currentUserTeamsCache = createCacheBySession(async (session) => {
|
|
191
207
|
return await this._interface.listClientUserTeams(session);
|
|
192
208
|
});
|
|
209
|
+
_currentUserOAuthConnectionAccessTokensCache = createCacheBySession(
|
|
210
|
+
async (session, [accountId, scope]) => {
|
|
211
|
+
try {
|
|
212
|
+
return await this._interface.getAccessToken(accountId, scope || "", session);
|
|
213
|
+
} catch (err) {
|
|
214
|
+
if (!(err instanceof import_stack_shared.KnownErrors.OAuthConnectionDoesNotHaveRequiredScope || err instanceof import_stack_shared.KnownErrors.OAuthConnectionNotConnectedToUser)) {
|
|
215
|
+
throw err;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
);
|
|
221
|
+
_currentUserOAuthConnectionCache = createCacheBySession(
|
|
222
|
+
async (session, [connectionId, scope, redirect]) => {
|
|
223
|
+
const user = await this._currentUserCache.getOrWait([session], "write-only");
|
|
224
|
+
let hasConnection = true;
|
|
225
|
+
if (!user || !user.oauthProviders.find((p) => p === connectionId)) {
|
|
226
|
+
hasConnection = false;
|
|
227
|
+
}
|
|
228
|
+
const token = await this._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
|
|
229
|
+
if (!token) {
|
|
230
|
+
hasConnection = false;
|
|
231
|
+
}
|
|
232
|
+
if (!hasConnection && redirect) {
|
|
233
|
+
await (0, import_auth.addNewOAuthProviderOrScope)(
|
|
234
|
+
this._interface,
|
|
235
|
+
{
|
|
236
|
+
provider: connectionId,
|
|
237
|
+
redirectUrl: this.urls.oauthCallback,
|
|
238
|
+
errorRedirectUrl: this.urls.error,
|
|
239
|
+
providerScope: (0, import_strings.mergeScopeStrings)(scope || "", (this._oauthScopesOnSignIn[connectionId] ?? []).join(" "))
|
|
240
|
+
},
|
|
241
|
+
this._getSession()
|
|
242
|
+
);
|
|
243
|
+
return await (0, import_promises.neverResolve)();
|
|
244
|
+
} else if (!hasConnection) {
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
const app = this;
|
|
248
|
+
return {
|
|
249
|
+
id: connectionId,
|
|
250
|
+
async getAccessToken() {
|
|
251
|
+
const result = await app._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
|
|
252
|
+
if (!result) {
|
|
253
|
+
throw new import_errors.StackAssertionError("No access token available");
|
|
254
|
+
}
|
|
255
|
+
return result;
|
|
256
|
+
},
|
|
257
|
+
useAccessToken() {
|
|
258
|
+
const result = useAsyncCache(app._currentUserOAuthConnectionAccessTokensCache, [session, connectionId, scope || ""], "oauthAccount.useAccessToken()");
|
|
259
|
+
if (!result) {
|
|
260
|
+
throw new import_errors.StackAssertionError("No access token available");
|
|
261
|
+
}
|
|
262
|
+
return result;
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
);
|
|
193
267
|
_initUniqueIdentifier() {
|
|
194
268
|
if (!this._uniqueIdentifier) {
|
|
195
269
|
throw new import_errors.StackAssertionError("Unique identifier not initialized");
|
|
@@ -426,6 +500,14 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
426
500
|
}
|
|
427
501
|
_userFromJson(json) {
|
|
428
502
|
const app = this;
|
|
503
|
+
async function getConnection(id, options) {
|
|
504
|
+
const scopeString = options?.scopes?.join(" ");
|
|
505
|
+
return await app._currentUserOAuthConnectionCache.getOrWait([app._getSession(), id, scopeString || "", options?.or === "redirect"], "write-only");
|
|
506
|
+
}
|
|
507
|
+
function useConnection(id, options) {
|
|
508
|
+
const scopeString = options?.scopes?.join(" ");
|
|
509
|
+
return useAsyncCache(app._currentUserOAuthConnectionCache, [app._useSession(), id, scopeString || "", options?.or === "redirect"], "user.useConnection()");
|
|
510
|
+
}
|
|
429
511
|
return {
|
|
430
512
|
projectId: json.projectId,
|
|
431
513
|
id: json.id,
|
|
@@ -439,6 +521,8 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
439
521
|
hasPassword: json.hasPassword,
|
|
440
522
|
authWithEmail: json.authWithEmail,
|
|
441
523
|
oauthProviders: json.oauthProviders,
|
|
524
|
+
getConnection,
|
|
525
|
+
useConnection,
|
|
442
526
|
async getSelectedTeam() {
|
|
443
527
|
return await this.getTeam(json.selectedTeamId || "");
|
|
444
528
|
},
|
|
@@ -508,12 +592,9 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
508
592
|
displayName: json.displayName
|
|
509
593
|
};
|
|
510
594
|
}
|
|
511
|
-
|
|
512
|
-
if (json === null)
|
|
513
|
-
return null;
|
|
595
|
+
_authFromJson(session) {
|
|
514
596
|
const app = this;
|
|
515
|
-
|
|
516
|
-
...this._userFromJson(json),
|
|
597
|
+
return {
|
|
517
598
|
_internalSession: session,
|
|
518
599
|
currentSession: {
|
|
519
600
|
async getTokens() {
|
|
@@ -524,15 +605,25 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
524
605
|
};
|
|
525
606
|
}
|
|
526
607
|
},
|
|
608
|
+
async getAuthHeaders() {
|
|
609
|
+
return {
|
|
610
|
+
"x-stack-auth": JSON.stringify(await this.getAuthJson())
|
|
611
|
+
};
|
|
612
|
+
},
|
|
613
|
+
async getAuthJson() {
|
|
614
|
+
const tokens = await this.currentSession.getTokens();
|
|
615
|
+
return tokens;
|
|
616
|
+
},
|
|
617
|
+
signOut() {
|
|
618
|
+
return app._signOut(session);
|
|
619
|
+
},
|
|
620
|
+
// TODO these should not actually be on Auth, instead on User
|
|
527
621
|
async updateSelectedTeam(team) {
|
|
528
622
|
await app._updateUser({ selectedTeamId: team?.id ?? null }, session);
|
|
529
623
|
},
|
|
530
624
|
update(update) {
|
|
531
625
|
return app._updateUser(update, session);
|
|
532
626
|
},
|
|
533
|
-
signOut() {
|
|
534
|
-
return app._signOut(session);
|
|
535
|
-
},
|
|
536
627
|
sendVerificationEmail() {
|
|
537
628
|
return app._sendVerificationEmail(session);
|
|
538
629
|
},
|
|
@@ -540,6 +631,15 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
540
631
|
return app._updatePassword(options, session);
|
|
541
632
|
}
|
|
542
633
|
};
|
|
634
|
+
}
|
|
635
|
+
_currentUserFromJson(json, session) {
|
|
636
|
+
if (json === null)
|
|
637
|
+
return null;
|
|
638
|
+
const app = this;
|
|
639
|
+
const currentUser = {
|
|
640
|
+
...this._userFromJson(json),
|
|
641
|
+
...this._authFromJson(session)
|
|
642
|
+
};
|
|
543
643
|
if (this._isInternalProject()) {
|
|
544
644
|
const internalUser = {
|
|
545
645
|
...currentUser,
|
|
@@ -610,33 +710,12 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
610
710
|
get urls() {
|
|
611
711
|
return getUrls(this._urlOptions);
|
|
612
712
|
}
|
|
613
|
-
async getCrossOriginHeaders() {
|
|
614
|
-
return {
|
|
615
|
-
"x-stack-auth": JSON.stringify(await this.getCrossOriginTokenObject())
|
|
616
|
-
};
|
|
617
|
-
}
|
|
618
|
-
async getCrossOriginTokenObject() {
|
|
619
|
-
const user = await this.getUser();
|
|
620
|
-
if (!user)
|
|
621
|
-
return { accessToken: null, refreshToken: null };
|
|
622
|
-
const tokens = await user.currentSession.getTokens();
|
|
623
|
-
return tokens;
|
|
624
|
-
}
|
|
625
713
|
async _redirectTo(handlerName, options) {
|
|
626
714
|
const url = this.urls[handlerName];
|
|
627
715
|
if (!url) {
|
|
628
716
|
throw new Error(`No URL for handler name ${handlerName}`);
|
|
629
717
|
}
|
|
630
|
-
|
|
631
|
-
NextNavigation.redirect(url, options?.replace ? NextNavigation.RedirectType.replace : NextNavigation.RedirectType.push);
|
|
632
|
-
} else {
|
|
633
|
-
if (options?.replace) {
|
|
634
|
-
window.location.replace(url);
|
|
635
|
-
} else {
|
|
636
|
-
window.location.assign(url);
|
|
637
|
-
}
|
|
638
|
-
await (0, import_promises.wait)(2e3);
|
|
639
|
-
}
|
|
718
|
+
await _redirectTo(url, options);
|
|
640
719
|
}
|
|
641
720
|
async redirectToSignIn() {
|
|
642
721
|
return await this._redirectTo("signIn");
|
|
@@ -677,6 +756,9 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
677
756
|
async redirectToAccountSettings() {
|
|
678
757
|
return await this._redirectTo("accountSettings");
|
|
679
758
|
}
|
|
759
|
+
async redirectToError() {
|
|
760
|
+
return await this._redirectTo("error");
|
|
761
|
+
}
|
|
680
762
|
async sendForgotPasswordEmail(email) {
|
|
681
763
|
const redirectUrl = (0, import_url.constructRedirectUrl)(this.urls.passwordReset);
|
|
682
764
|
const error = await this._interface.sendForgotPasswordEmail(email, redirectUrl);
|
|
@@ -756,7 +838,15 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
756
838
|
}
|
|
757
839
|
async signInWithOAuth(provider) {
|
|
758
840
|
this._ensurePersistentTokenStore();
|
|
759
|
-
await (0, import_auth.signInWithOAuth)(
|
|
841
|
+
await (0, import_auth.signInWithOAuth)(
|
|
842
|
+
this._interface,
|
|
843
|
+
{
|
|
844
|
+
provider,
|
|
845
|
+
redirectUrl: this.urls.oauthCallback,
|
|
846
|
+
errorRedirectUrl: this.urls.error,
|
|
847
|
+
providerScope: this._oauthScopesOnSignIn[provider]?.join(" ")
|
|
848
|
+
}
|
|
849
|
+
);
|
|
760
850
|
}
|
|
761
851
|
async signInWithCredential(options) {
|
|
762
852
|
this._ensurePersistentTokenStore();
|
|
@@ -803,7 +893,10 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
803
893
|
const result = await (0, import_auth.callOAuthCallback)(this._interface, this.urls.oauthCallback);
|
|
804
894
|
if (result) {
|
|
805
895
|
await this._signInToAccountWithTokens(result);
|
|
806
|
-
if (result.
|
|
896
|
+
if (result.afterCallbackRedirectUrl) {
|
|
897
|
+
await _redirectTo(result.afterCallbackRedirectUrl, { replace: true });
|
|
898
|
+
return true;
|
|
899
|
+
} else if (result.newUser) {
|
|
807
900
|
await this.redirectToAfterSignUp({ replace: true });
|
|
808
901
|
return true;
|
|
809
902
|
} else {
|
|
@@ -883,6 +976,9 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
883
976
|
return res;
|
|
884
977
|
}
|
|
885
978
|
async _refreshUser(session) {
|
|
979
|
+
await this._refreshSession(session);
|
|
980
|
+
}
|
|
981
|
+
async _refreshSession(session) {
|
|
886
982
|
await this._currentUserCache.refresh([session]);
|
|
887
983
|
}
|
|
888
984
|
async _refreshUsers() {
|
|
@@ -926,6 +1022,7 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
926
1022
|
publishableClientKey: this._interface.options.publishableClientKey,
|
|
927
1023
|
tokenStore: this._tokenStoreInit,
|
|
928
1024
|
urls: this._urlOptions,
|
|
1025
|
+
oauthScopesOnSignIn: this._oauthScopesOnSignIn,
|
|
929
1026
|
uniqueIdentifier: this._getUniqueIdentifier()
|
|
930
1027
|
};
|
|
931
1028
|
},
|
|
@@ -967,7 +1064,8 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
967
1064
|
super("interface" in options ? {
|
|
968
1065
|
interface: options.interface,
|
|
969
1066
|
tokenStore: options.tokenStore,
|
|
970
|
-
urls: options.urls
|
|
1067
|
+
urls: options.urls,
|
|
1068
|
+
oauthScopesOnSignIn: options.oauthScopesOnSignIn
|
|
971
1069
|
} : {
|
|
972
1070
|
interface: new import_stack_shared.StackServerInterface({
|
|
973
1071
|
baseUrl: options.baseUrl ?? getDefaultBaseUrl(),
|
|
@@ -977,7 +1075,8 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
977
1075
|
secretServerKey: options.secretServerKey ?? getDefaultSecretServerKey()
|
|
978
1076
|
}),
|
|
979
1077
|
tokenStore: options.tokenStore,
|
|
980
|
-
urls: options.urls ?? {}
|
|
1078
|
+
urls: options.urls ?? {},
|
|
1079
|
+
oauthScopesOnSignIn: options.oauthScopesOnSignIn ?? {}
|
|
981
1080
|
});
|
|
982
1081
|
}
|
|
983
1082
|
_serverUserFromJson(json) {
|
|
@@ -1073,40 +1172,14 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
1073
1172
|
const nonCurrentServerUser = this._serverUserFromJson(json);
|
|
1074
1173
|
const currentUser = {
|
|
1075
1174
|
...nonCurrentServerUser,
|
|
1076
|
-
|
|
1077
|
-
currentSession: {
|
|
1078
|
-
async getTokens() {
|
|
1079
|
-
const tokens = await session.getPotentiallyExpiredTokens();
|
|
1080
|
-
return {
|
|
1081
|
-
accessToken: tokens?.accessToken.token ?? null,
|
|
1082
|
-
refreshToken: tokens?.refreshToken?.token ?? null
|
|
1083
|
-
};
|
|
1084
|
-
}
|
|
1085
|
-
},
|
|
1175
|
+
...this._authFromJson(session),
|
|
1086
1176
|
async delete() {
|
|
1087
1177
|
const res = await nonCurrentServerUser.delete();
|
|
1088
1178
|
await app._refreshUser(session);
|
|
1089
1179
|
return res;
|
|
1090
1180
|
},
|
|
1091
|
-
async updateSelectedTeam(team) {
|
|
1092
|
-
await this.update({ selectedTeamId: team?.id ?? null });
|
|
1093
|
-
},
|
|
1094
|
-
async update(update) {
|
|
1095
|
-
const res = await nonCurrentServerUser.update(update);
|
|
1096
|
-
await app._refreshUser(session);
|
|
1097
|
-
return res;
|
|
1098
|
-
},
|
|
1099
|
-
signOut() {
|
|
1100
|
-
return app._signOut(session);
|
|
1101
|
-
},
|
|
1102
1181
|
getClientUser() {
|
|
1103
1182
|
return app._currentUserFromJson(json, session);
|
|
1104
|
-
},
|
|
1105
|
-
sendVerificationEmail() {
|
|
1106
|
-
return app._sendVerificationEmail(session);
|
|
1107
|
-
},
|
|
1108
|
-
updatePassword(options) {
|
|
1109
|
-
return app._updatePassword(options, session);
|
|
1110
1183
|
}
|
|
1111
1184
|
};
|
|
1112
1185
|
if (this._isInternalProject()) {
|
|
@@ -1281,7 +1354,7 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
1281
1354
|
return teams.find((t) => t.id === teamId) ?? null;
|
|
1282
1355
|
}, [teams, teamId]);
|
|
1283
1356
|
}
|
|
1284
|
-
async
|
|
1357
|
+
async _refreshSession(session) {
|
|
1285
1358
|
await Promise.all([
|
|
1286
1359
|
super._refreshUser(session),
|
|
1287
1360
|
this._currentServerUserCache.refresh([session])
|
|
@@ -1330,7 +1403,8 @@ var _StackAdminAppImpl = class extends _StackServerAppImpl {
|
|
|
1330
1403
|
}
|
|
1331
1404
|
}),
|
|
1332
1405
|
tokenStore: options.tokenStore,
|
|
1333
|
-
urls: options.urls
|
|
1406
|
+
urls: options.urls,
|
|
1407
|
+
oauthScopesOnSignIn: options.oauthScopesOnSignIn
|
|
1334
1408
|
});
|
|
1335
1409
|
}
|
|
1336
1410
|
_createApiKeySetBaseFromJson(data) {
|