@stackframe/stack-shared 2.3.6 → 2.4.1
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/dist/index.d.ts +2 -2
- package/dist/interface/adminInterface.d.ts +2 -1
- package/dist/interface/adminInterface.js +2 -2
- package/dist/interface/clientInterface.d.ts +40 -4
- package/dist/interface/clientInterface.js +21 -4
- package/dist/interface/serverInterface.d.ts +54 -7
- package/dist/interface/serverInterface.js +121 -2
- package/dist/known-errors.d.ts +22 -0
- package/dist/known-errors.js +73 -1
- package/dist/utils/errors.js +7 -2
- package/dist/utils/strings.d.ts +1 -0
- package/dist/utils/strings.js +3 -0
- package/dist/utils/types.d.ts +1 -0
- package/dist/utils/types.js +1 -0
- package/package.json +13 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { StackClientInterface, UserJson as UserJson,
|
|
2
|
-
export { StackServerInterface, ServerUserJson,
|
|
1
|
+
export { StackClientInterface, UserJson as UserJson, ClientProjectJson, ProjectJson, OAuthProviderConfigJson, getProductionModeErrors, } from "./interface/clientInterface";
|
|
2
|
+
export { StackServerInterface, ServerUserJson, } from "./interface/serverInterface";
|
|
3
3
|
export { StackAdminInterface, ApiKeySetBaseJson, ApiKeySetFirstViewJson, ApiKeySetJson, } from "./interface/adminInterface";
|
|
4
4
|
export { KnownError, KnownErrors, } from "./known-errors";
|
|
@@ -27,6 +27,7 @@ export type ProjectUpdateOptions = {
|
|
|
27
27
|
credentialEnabled?: boolean;
|
|
28
28
|
magicLinkEnabled?: boolean;
|
|
29
29
|
allowLocalhost?: boolean;
|
|
30
|
+
createTeamOnSignUp?: boolean;
|
|
30
31
|
};
|
|
31
32
|
};
|
|
32
33
|
export type ApiKeySetBaseJson = {
|
|
@@ -62,7 +63,7 @@ export type ApiKeySetCreateOptions = {
|
|
|
62
63
|
export declare class StackAdminInterface extends StackServerInterface {
|
|
63
64
|
readonly options: AdminAuthApplicationOptions;
|
|
64
65
|
constructor(options: AdminAuthApplicationOptions);
|
|
65
|
-
protected sendAdminRequest(path: string, options: RequestInit, tokenStore: TokenStore | null): Promise<Response & {
|
|
66
|
+
protected sendAdminRequest(path: string, options: RequestInit, tokenStore: TokenStore | null, requestType?: "admin"): Promise<Response & {
|
|
66
67
|
usedTokens: Readonly<{
|
|
67
68
|
refreshToken: string | null;
|
|
68
69
|
accessToken: string | null;
|
|
@@ -5,14 +5,14 @@ export class StackAdminInterface extends StackServerInterface {
|
|
|
5
5
|
super(options);
|
|
6
6
|
this.options = options;
|
|
7
7
|
}
|
|
8
|
-
async sendAdminRequest(path, options, tokenStore) {
|
|
8
|
+
async sendAdminRequest(path, options, tokenStore, requestType = "admin") {
|
|
9
9
|
return await this.sendServerRequest(path, {
|
|
10
10
|
...options,
|
|
11
11
|
headers: {
|
|
12
12
|
"x-stack-super-secret-admin-key": "superSecretAdminKey" in this.options ? this.options.superSecretAdminKey : "",
|
|
13
13
|
...options.headers,
|
|
14
14
|
},
|
|
15
|
-
}, tokenStore);
|
|
15
|
+
}, tokenStore, requestType);
|
|
16
16
|
}
|
|
17
17
|
async getProject(options) {
|
|
18
18
|
const response = await this.sendAdminRequest("/projects/" + encodeURIComponent(this.projectId), {
|
|
@@ -3,12 +3,12 @@ import { Result } from "../utils/results";
|
|
|
3
3
|
import { ReadonlyJson } from '../utils/json';
|
|
4
4
|
import { AsyncStore, ReadonlyAsyncStore } from '../utils/stores';
|
|
5
5
|
import { KnownErrors } from '../known-errors';
|
|
6
|
-
|
|
7
|
-
readonly projectId: string;
|
|
6
|
+
type UserCustomizableJson = {
|
|
8
7
|
readonly displayName: string | null;
|
|
9
8
|
readonly clientMetadata: ReadonlyJson;
|
|
10
9
|
};
|
|
11
10
|
export type UserJson = UserCustomizableJson & {
|
|
11
|
+
readonly projectId: string;
|
|
12
12
|
readonly id: string;
|
|
13
13
|
readonly primaryEmail: string | null;
|
|
14
14
|
readonly primaryEmailVerified: boolean;
|
|
@@ -16,11 +16,15 @@ export type UserJson = UserCustomizableJson & {
|
|
|
16
16
|
readonly clientMetadata: ReadonlyJson;
|
|
17
17
|
readonly profileImageUrl: string | null;
|
|
18
18
|
readonly signedUpAtMillis: number;
|
|
19
|
+
/**
|
|
20
|
+
* not used anymore, for backwards compatibility
|
|
21
|
+
*/
|
|
19
22
|
readonly authMethod: "credential" | "oauth";
|
|
20
23
|
readonly hasPassword: boolean;
|
|
21
24
|
readonly authWithEmail: boolean;
|
|
22
25
|
readonly oauthProviders: readonly string[];
|
|
23
26
|
};
|
|
27
|
+
export type UserUpdateJson = Partial<UserCustomizableJson>;
|
|
24
28
|
export type ClientProjectJson = {
|
|
25
29
|
readonly id: string;
|
|
26
30
|
readonly credentialEnabled: boolean;
|
|
@@ -65,6 +69,7 @@ export type ProjectJson = {
|
|
|
65
69
|
oauthProviders: OAuthProviderConfigJson[];
|
|
66
70
|
emailConfig?: EmailConfigJson;
|
|
67
71
|
domains: DomainConfigJson[];
|
|
72
|
+
createTeamOnSignUp: boolean;
|
|
68
73
|
};
|
|
69
74
|
};
|
|
70
75
|
export type OAuthProviderConfigJson = {
|
|
@@ -98,6 +103,30 @@ export type ProductionModeError = {
|
|
|
98
103
|
errorMessage: string;
|
|
99
104
|
fixUrlRelative: string;
|
|
100
105
|
};
|
|
106
|
+
export type OrglikeJson = {
|
|
107
|
+
id: string;
|
|
108
|
+
displayName: string;
|
|
109
|
+
createdAtMillis: number;
|
|
110
|
+
};
|
|
111
|
+
export type TeamJson = OrglikeJson;
|
|
112
|
+
export type OrganizationJson = OrglikeJson;
|
|
113
|
+
export type TeamMemberJson = {
|
|
114
|
+
userId: string;
|
|
115
|
+
teamId: string;
|
|
116
|
+
displayName: string | null;
|
|
117
|
+
};
|
|
118
|
+
export type PermissionDefinitionScopeJson = {
|
|
119
|
+
type: "global";
|
|
120
|
+
} | {
|
|
121
|
+
type: "any-team";
|
|
122
|
+
} | {
|
|
123
|
+
type: "specific-team";
|
|
124
|
+
teamId: string;
|
|
125
|
+
};
|
|
126
|
+
export type PermissionDefinitionJson = {
|
|
127
|
+
id: string;
|
|
128
|
+
scope: PermissionDefinitionScopeJson;
|
|
129
|
+
};
|
|
101
130
|
export declare class StackClientInterface {
|
|
102
131
|
readonly options: ClientInterfaceOptions;
|
|
103
132
|
constructor(options: ClientInterfaceOptions);
|
|
@@ -105,7 +134,7 @@ export declare class StackClientInterface {
|
|
|
105
134
|
getSessionCookieName(): string;
|
|
106
135
|
getApiUrl(): string;
|
|
107
136
|
protected refreshAccessToken(tokenStore: TokenStore): Promise<void>;
|
|
108
|
-
protected sendClientRequest(path: string, requestOptions: RequestInit, tokenStoreOrNull: TokenStore | null): Promise<Response & {
|
|
137
|
+
protected sendClientRequest(path: string, requestOptions: RequestInit, tokenStoreOrNull: TokenStore | null, requestType?: "client" | "server" | "admin"): Promise<Response & {
|
|
109
138
|
usedTokens: Readonly<{
|
|
110
139
|
refreshToken: string | null;
|
|
111
140
|
accessToken: string | null;
|
|
@@ -141,9 +170,16 @@ export declare class StackClientInterface {
|
|
|
141
170
|
callOAuthCallback(oauthParams: URLSearchParams, redirectUri: string, codeVerifier: string, state: string, tokenStore: TokenStore): Promise<oauth.OAuth2TokenEndpointResponse>;
|
|
142
171
|
signOut(tokenStore: TokenStore): Promise<void>;
|
|
143
172
|
getClientUserByToken(tokenStore: TokenStore): Promise<Result<UserJson>>;
|
|
173
|
+
listClientUserTeamPermissions(options: {
|
|
174
|
+
teamId: string;
|
|
175
|
+
type: 'global' | 'team';
|
|
176
|
+
direct: boolean;
|
|
177
|
+
}, tokenStore: TokenStore): Promise<PermissionDefinitionJson[]>;
|
|
178
|
+
listClientUserTeams(tokenStore: TokenStore): Promise<TeamJson[]>;
|
|
144
179
|
getClientProject(): Promise<Result<ClientProjectJson>>;
|
|
145
|
-
setClientUserCustomizableData(update:
|
|
180
|
+
setClientUserCustomizableData(update: UserUpdateJson, tokenStore: TokenStore): Promise<void>;
|
|
146
181
|
listProjects(tokenStore: TokenStore): Promise<ProjectJson[]>;
|
|
147
182
|
createProject(project: Pick<ProjectJson, "displayName" | "description">, tokenStore: TokenStore): Promise<ProjectJson>;
|
|
148
183
|
}
|
|
149
184
|
export declare function getProductionModeErrors(project: ProjectJson): ProductionModeError[];
|
|
185
|
+
export {};
|
|
@@ -4,6 +4,8 @@ import { Result } from "../utils/results";
|
|
|
4
4
|
import { AsyncStore } from '../utils/stores';
|
|
5
5
|
import { KnownError, KnownErrors } from '../known-errors';
|
|
6
6
|
import { StackAssertionError } from '../utils/errors';
|
|
7
|
+
import { cookies } from '@stackframe/stack-sc';
|
|
8
|
+
import { generateSecureRandomString } from '../utils/crypto';
|
|
7
9
|
export const sharedProviders = [
|
|
8
10
|
"shared-github",
|
|
9
11
|
"shared-google",
|
|
@@ -94,12 +96,12 @@ export class StackClientInterface {
|
|
|
94
96
|
refreshToken: result.refresh_token ?? old?.refreshToken ?? null,
|
|
95
97
|
}));
|
|
96
98
|
}
|
|
97
|
-
async sendClientRequest(path, requestOptions, tokenStoreOrNull) {
|
|
99
|
+
async sendClientRequest(path, requestOptions, tokenStoreOrNull, requestType = "client") {
|
|
98
100
|
const tokenStore = tokenStoreOrNull ?? new AsyncStore({
|
|
99
101
|
accessToken: null,
|
|
100
102
|
refreshToken: null,
|
|
101
103
|
});
|
|
102
|
-
return await Result.orThrowAsync(Result.retry(() => this.sendClientRequestInner(path, requestOptions, tokenStore), 5, { exponentialDelayBase: 1000 }));
|
|
104
|
+
return await Result.orThrowAsync(Result.retry(() => this.sendClientRequestInner(path, requestOptions, tokenStore, requestType), 5, { exponentialDelayBase: 1000 }));
|
|
103
105
|
}
|
|
104
106
|
async sendClientRequestAndCatchKnownError(path, requestOptions, tokenStoreOrNull, errorsToCatch) {
|
|
105
107
|
try {
|
|
@@ -118,12 +120,14 @@ export class StackClientInterface {
|
|
|
118
120
|
/**
|
|
119
121
|
* This object will be modified for future retries, so it should be passed by reference.
|
|
120
122
|
*/
|
|
121
|
-
tokenStore) {
|
|
123
|
+
tokenStore, requestType) {
|
|
122
124
|
let tokenObj = await tokenStore.getOrWait();
|
|
123
125
|
if (!tokenObj.accessToken && tokenObj.refreshToken) {
|
|
124
126
|
await this.refreshAccessToken(tokenStore);
|
|
125
127
|
tokenObj = await tokenStore.getOrWait();
|
|
126
128
|
}
|
|
129
|
+
// all requests should be dynamic to prevent Next.js caching
|
|
130
|
+
cookies?.();
|
|
127
131
|
const url = this.getApiUrl() + path;
|
|
128
132
|
const params = {
|
|
129
133
|
/**
|
|
@@ -138,6 +142,7 @@ export class StackClientInterface {
|
|
|
138
142
|
headers: {
|
|
139
143
|
"X-Stack-Override-Error-Status": "true",
|
|
140
144
|
"X-Stack-Project-Id": this.projectId,
|
|
145
|
+
"X-Stack-Request-Type": requestType,
|
|
141
146
|
...tokenObj.accessToken ? {
|
|
142
147
|
"Authorization": "StackSession " + tokenObj.accessToken,
|
|
143
148
|
} : {},
|
|
@@ -147,8 +152,10 @@ export class StackClientInterface {
|
|
|
147
152
|
...'projectOwnerTokens' in this.options ? {
|
|
148
153
|
"X-Stack-Admin-Access-Token": (await this.options.projectOwnerTokens?.getOrWait())?.accessToken ?? "",
|
|
149
154
|
} : {},
|
|
155
|
+
"X-Stack-Random-Nonce": generateSecureRandomString(),
|
|
150
156
|
...options.headers,
|
|
151
157
|
},
|
|
158
|
+
cache: "no-store",
|
|
152
159
|
};
|
|
153
160
|
const rawRes = await fetch(url, params);
|
|
154
161
|
const processedRes = await this._processResponse(rawRes);
|
|
@@ -432,6 +439,16 @@ export class StackClientInterface {
|
|
|
432
439
|
return Result.error(new Error("Failed to get user"));
|
|
433
440
|
return Result.ok(user);
|
|
434
441
|
}
|
|
442
|
+
async listClientUserTeamPermissions(options, tokenStore) {
|
|
443
|
+
const response = await this.sendClientRequest(`/current-user/teams/${options.teamId}/permissions?type=${options.type}&direct=${options.direct}`, {}, tokenStore);
|
|
444
|
+
const permissions = await response.json();
|
|
445
|
+
return permissions;
|
|
446
|
+
}
|
|
447
|
+
async listClientUserTeams(tokenStore) {
|
|
448
|
+
const response = await this.sendClientRequest("/current-user/teams", {}, tokenStore);
|
|
449
|
+
const teams = await response.json();
|
|
450
|
+
return teams;
|
|
451
|
+
}
|
|
435
452
|
async getClientProject() {
|
|
436
453
|
const response = await this.sendClientRequest("/projects/" + this.options.projectId, {}, null);
|
|
437
454
|
const project = await response.json();
|
|
@@ -473,7 +490,7 @@ export class StackClientInterface {
|
|
|
473
490
|
}
|
|
474
491
|
export function getProductionModeErrors(project) {
|
|
475
492
|
const errors = [];
|
|
476
|
-
const fixUrlRelative = `/projects/${
|
|
493
|
+
const fixUrlRelative = `/projects/${project.id}/auth/urls-and-callbacks`;
|
|
477
494
|
if (project.evaluatedConfig.allowLocalhost) {
|
|
478
495
|
errors.push({
|
|
479
496
|
errorMessage: "Localhost is not allowed in production mode, turn off 'Allow localhost' in project settings",
|
|
@@ -1,13 +1,28 @@
|
|
|
1
|
-
import { ClientInterfaceOptions,
|
|
1
|
+
import { ClientInterfaceOptions, UserJson, TokenStore, StackClientInterface, ReadonlyTokenStore, OrglikeJson, UserUpdateJson, PermissionDefinitionJson, PermissionDefinitionScopeJson as PermissionDefinitionScopeJson, TeamMemberJson } from "./clientInterface";
|
|
2
2
|
import { Result } from "../utils/results";
|
|
3
3
|
import { ReadonlyJson } from "../utils/json";
|
|
4
4
|
export type ServerUserJson = UserJson & {
|
|
5
5
|
readonly serverMetadata: ReadonlyJson;
|
|
6
6
|
};
|
|
7
|
-
export type
|
|
8
|
-
readonly serverMetadata
|
|
9
|
-
readonly primaryEmail
|
|
10
|
-
readonly primaryEmailVerified
|
|
7
|
+
export type ServerUserUpdateJson = UserUpdateJson & {
|
|
8
|
+
readonly serverMetadata?: ReadonlyJson;
|
|
9
|
+
readonly primaryEmail?: string | null;
|
|
10
|
+
readonly primaryEmailVerified?: boolean;
|
|
11
|
+
};
|
|
12
|
+
export type ServerOrglikeCustomizableJson = Pick<ServerOrglikeJson, "displayName">;
|
|
13
|
+
export type ServerOrglikeJson = OrglikeJson & {};
|
|
14
|
+
export type ServerTeamCustomizableJson = ServerOrglikeCustomizableJson;
|
|
15
|
+
export type ServerTeamJson = ServerOrglikeJson;
|
|
16
|
+
export type ServerTeamMemberJson = TeamMemberJson;
|
|
17
|
+
export type ServerPermissionDefinitionCustomizableJson = {
|
|
18
|
+
readonly id: string;
|
|
19
|
+
readonly description?: string;
|
|
20
|
+
readonly scope: PermissionDefinitionScopeJson;
|
|
21
|
+
readonly containPermissionIds: string[];
|
|
22
|
+
};
|
|
23
|
+
export type ServerPermissionDefinitionJson = PermissionDefinitionJson & ServerPermissionDefinitionCustomizableJson & {
|
|
24
|
+
readonly __databaseUniqueId: string;
|
|
25
|
+
readonly scope: PermissionDefinitionScopeJson;
|
|
11
26
|
};
|
|
12
27
|
export type ServerAuthApplicationOptions = (ClientInterfaceOptions & ({
|
|
13
28
|
readonly secretServerKey: string;
|
|
@@ -17,14 +32,46 @@ export type ServerAuthApplicationOptions = (ClientInterfaceOptions & ({
|
|
|
17
32
|
export declare class StackServerInterface extends StackClientInterface {
|
|
18
33
|
options: ServerAuthApplicationOptions;
|
|
19
34
|
constructor(options: ServerAuthApplicationOptions);
|
|
20
|
-
protected sendServerRequest(path: string, options: RequestInit, tokenStore: TokenStore | null): Promise<Response & {
|
|
35
|
+
protected sendServerRequest(path: string, options: RequestInit, tokenStore: TokenStore | null, requestType?: "server" | "admin"): Promise<Response & {
|
|
21
36
|
usedTokens: Readonly<{
|
|
22
37
|
refreshToken: string | null;
|
|
23
38
|
accessToken: string | null;
|
|
24
39
|
}>;
|
|
25
40
|
}>;
|
|
26
41
|
getServerUserByToken(tokenStore: TokenStore): Promise<Result<ServerUserJson>>;
|
|
42
|
+
getServerUserById(userId: string): Promise<Result<ServerUserJson>>;
|
|
43
|
+
listServerUserTeamPermissions(options: {
|
|
44
|
+
teamId: string;
|
|
45
|
+
type: 'global' | 'team';
|
|
46
|
+
direct: boolean;
|
|
47
|
+
}, tokenStore: TokenStore): Promise<ServerPermissionDefinitionJson[]>;
|
|
48
|
+
listServerUserTeams(tokenStore: TokenStore): Promise<ServerTeamJson[]>;
|
|
49
|
+
listPermissionDefinitions(): Promise<ServerPermissionDefinitionJson[]>;
|
|
50
|
+
createPermissionDefinition(data: ServerPermissionDefinitionCustomizableJson): Promise<ServerPermissionDefinitionJson>;
|
|
51
|
+
updatePermissionDefinition(permissionId: string, data: Partial<ServerPermissionDefinitionCustomizableJson>): Promise<void>;
|
|
52
|
+
deletePermissionDefinition(permissionId: string): Promise<void>;
|
|
27
53
|
listUsers(): Promise<ServerUserJson[]>;
|
|
28
|
-
|
|
54
|
+
listTeams(): Promise<ServerTeamJson[]>;
|
|
55
|
+
listTeamMembers(teamId: string): Promise<ServerTeamMemberJson[]>;
|
|
56
|
+
createTeam(data: ServerTeamCustomizableJson): Promise<ServerTeamJson>;
|
|
57
|
+
updateTeam(teamId: string, data: Partial<ServerTeamCustomizableJson>): Promise<void>;
|
|
58
|
+
deleteTeam(teamId: string): Promise<void>;
|
|
59
|
+
addUserToTeam(options: {
|
|
60
|
+
userId: string;
|
|
61
|
+
teamId: string;
|
|
62
|
+
}): Promise<void>;
|
|
63
|
+
removeUserFromTeam(options: {
|
|
64
|
+
userId: string;
|
|
65
|
+
teamId: string;
|
|
66
|
+
}): Promise<void>;
|
|
67
|
+
setServerUserCustomizableData(userId: string, update: ServerUserUpdateJson): Promise<void>;
|
|
68
|
+
listTeamMemberPermissions(options: {
|
|
69
|
+
teamId: string;
|
|
70
|
+
userId: string;
|
|
71
|
+
type: 'global' | 'team';
|
|
72
|
+
direct: boolean;
|
|
73
|
+
}): Promise<ServerPermissionDefinitionJson[]>;
|
|
74
|
+
grantTeamUserPermission(teamId: string, userId: string, permissionId: string, type: 'global' | 'team'): Promise<void>;
|
|
75
|
+
revokeTeamUserPermission(teamId: string, userId: string, permissionId: string, type: 'global' | 'team'): Promise<void>;
|
|
29
76
|
deleteServerUser(userId: string): Promise<void>;
|
|
30
77
|
}
|
|
@@ -6,14 +6,14 @@ export class StackServerInterface extends StackClientInterface {
|
|
|
6
6
|
super(options);
|
|
7
7
|
this.options = options;
|
|
8
8
|
}
|
|
9
|
-
async sendServerRequest(path, options, tokenStore) {
|
|
9
|
+
async sendServerRequest(path, options, tokenStore, requestType = "server") {
|
|
10
10
|
return await this.sendClientRequest(path, {
|
|
11
11
|
...options,
|
|
12
12
|
headers: {
|
|
13
13
|
"x-stack-secret-server-key": "secretServerKey" in this.options ? this.options.secretServerKey : "",
|
|
14
14
|
...options.headers,
|
|
15
15
|
},
|
|
16
|
-
}, tokenStore);
|
|
16
|
+
}, tokenStore, requestType);
|
|
17
17
|
}
|
|
18
18
|
async getServerUserByToken(tokenStore) {
|
|
19
19
|
const response = await this.sendServerRequest("/current-user?server=true", {}, tokenStore);
|
|
@@ -22,10 +22,107 @@ export class StackServerInterface extends StackClientInterface {
|
|
|
22
22
|
return Result.error(new Error("Failed to get user"));
|
|
23
23
|
return Result.ok(user);
|
|
24
24
|
}
|
|
25
|
+
async getServerUserById(userId) {
|
|
26
|
+
const response = await this.sendServerRequest(`/users/${userId}?server=true`, {}, null);
|
|
27
|
+
const user = await response.json();
|
|
28
|
+
if (!user)
|
|
29
|
+
return Result.error(new Error("Failed to get user"));
|
|
30
|
+
return Result.ok(user);
|
|
31
|
+
}
|
|
32
|
+
async listServerUserTeamPermissions(options, tokenStore) {
|
|
33
|
+
const response = await this.sendServerRequest(`/current-user/teams/${options.teamId}/permissions?type=${options.type}&direct=${options.direct}&server=true`, {}, tokenStore);
|
|
34
|
+
const permissions = await response.json();
|
|
35
|
+
return permissions;
|
|
36
|
+
}
|
|
37
|
+
async listServerUserTeams(tokenStore) {
|
|
38
|
+
const response = await this.sendServerRequest("/current-user/teams?server=true", {}, tokenStore);
|
|
39
|
+
const teams = await response.json();
|
|
40
|
+
return teams;
|
|
41
|
+
}
|
|
42
|
+
async listPermissionDefinitions() {
|
|
43
|
+
const response = await this.sendServerRequest(`/permission-definitions?server=true`, {}, null);
|
|
44
|
+
return await response.json();
|
|
45
|
+
}
|
|
46
|
+
async createPermissionDefinition(data) {
|
|
47
|
+
const response = await this.sendServerRequest("/permission-definitions?server=true", {
|
|
48
|
+
method: "POST",
|
|
49
|
+
headers: {
|
|
50
|
+
"content-type": "application/json",
|
|
51
|
+
},
|
|
52
|
+
body: JSON.stringify({
|
|
53
|
+
...data,
|
|
54
|
+
scope: {
|
|
55
|
+
type: "any-team",
|
|
56
|
+
}
|
|
57
|
+
}),
|
|
58
|
+
}, null);
|
|
59
|
+
return await response.json();
|
|
60
|
+
}
|
|
61
|
+
async updatePermissionDefinition(permissionId, data) {
|
|
62
|
+
await this.sendServerRequest(`/permission-definitions/${permissionId}?server=true`, {
|
|
63
|
+
method: "PUT",
|
|
64
|
+
headers: {
|
|
65
|
+
"content-type": "application/json",
|
|
66
|
+
},
|
|
67
|
+
body: JSON.stringify(data),
|
|
68
|
+
}, null);
|
|
69
|
+
}
|
|
70
|
+
async deletePermissionDefinition(permissionId) {
|
|
71
|
+
await this.sendServerRequest(`/permission-definitions/${permissionId}?server=true`, { method: "DELETE" }, null);
|
|
72
|
+
}
|
|
25
73
|
async listUsers() {
|
|
26
74
|
const response = await this.sendServerRequest("/users?server=true", {}, null);
|
|
27
75
|
return await response.json();
|
|
28
76
|
}
|
|
77
|
+
async listTeams() {
|
|
78
|
+
const response = await this.sendServerRequest("/teams?server=true", {}, null);
|
|
79
|
+
const json = await response.json();
|
|
80
|
+
return json;
|
|
81
|
+
}
|
|
82
|
+
async listTeamMembers(teamId) {
|
|
83
|
+
const response = await this.sendServerRequest(`/teams/${teamId}/users?server=true`, {}, null);
|
|
84
|
+
return await response.json();
|
|
85
|
+
}
|
|
86
|
+
async createTeam(data) {
|
|
87
|
+
const response = await this.sendServerRequest("/teams?server=true", {
|
|
88
|
+
method: "POST",
|
|
89
|
+
headers: {
|
|
90
|
+
"content-type": "application/json",
|
|
91
|
+
},
|
|
92
|
+
body: JSON.stringify(data),
|
|
93
|
+
}, null);
|
|
94
|
+
return await response.json();
|
|
95
|
+
}
|
|
96
|
+
async updateTeam(teamId, data) {
|
|
97
|
+
await this.sendServerRequest(`/teams/${teamId}?server=true`, {
|
|
98
|
+
method: "PUT",
|
|
99
|
+
headers: {
|
|
100
|
+
"content-type": "application/json",
|
|
101
|
+
},
|
|
102
|
+
body: JSON.stringify(data),
|
|
103
|
+
}, null);
|
|
104
|
+
}
|
|
105
|
+
async deleteTeam(teamId) {
|
|
106
|
+
await this.sendServerRequest(`/teams/${teamId}?server=true`, { method: "DELETE" }, null);
|
|
107
|
+
}
|
|
108
|
+
async addUserToTeam(options) {
|
|
109
|
+
await this.sendServerRequest(`/teams/${options.teamId}/users/${options.userId}?server=true`, {
|
|
110
|
+
method: "POST",
|
|
111
|
+
headers: {
|
|
112
|
+
"content-type": "application/json",
|
|
113
|
+
},
|
|
114
|
+
body: JSON.stringify({}),
|
|
115
|
+
}, null);
|
|
116
|
+
}
|
|
117
|
+
async removeUserFromTeam(options) {
|
|
118
|
+
await this.sendServerRequest(`/teams/${options.teamId}/users/${options.userId}?server=true`, {
|
|
119
|
+
method: "DELETE",
|
|
120
|
+
headers: {
|
|
121
|
+
"content-type": "application/json",
|
|
122
|
+
},
|
|
123
|
+
body: JSON.stringify({}),
|
|
124
|
+
}, null);
|
|
125
|
+
}
|
|
29
126
|
async setServerUserCustomizableData(userId, update) {
|
|
30
127
|
await this.sendServerRequest(`/users/${userId}?server=true`, {
|
|
31
128
|
method: "PUT",
|
|
@@ -35,6 +132,28 @@ export class StackServerInterface extends StackClientInterface {
|
|
|
35
132
|
body: JSON.stringify(update),
|
|
36
133
|
}, null);
|
|
37
134
|
}
|
|
135
|
+
async listTeamMemberPermissions(options) {
|
|
136
|
+
const response = await this.sendServerRequest(`/teams/${options.teamId}/users/${options.userId}/permissions?server=true&type=${options.type}&direct=${options.direct}`, {}, null);
|
|
137
|
+
return await response.json();
|
|
138
|
+
}
|
|
139
|
+
async grantTeamUserPermission(teamId, userId, permissionId, type) {
|
|
140
|
+
await this.sendServerRequest(`/teams/${teamId}/users/${userId}/permissions/${permissionId}?server=true`, {
|
|
141
|
+
method: "POST",
|
|
142
|
+
headers: {
|
|
143
|
+
"content-type": "application/json",
|
|
144
|
+
},
|
|
145
|
+
body: JSON.stringify({ type }),
|
|
146
|
+
}, null);
|
|
147
|
+
}
|
|
148
|
+
async revokeTeamUserPermission(teamId, userId, permissionId, type) {
|
|
149
|
+
await this.sendServerRequest(`/teams/${teamId}/users/${userId}/permissions/${permissionId}?server=true`, {
|
|
150
|
+
method: "DELETE",
|
|
151
|
+
headers: {
|
|
152
|
+
"content-type": "application/json",
|
|
153
|
+
},
|
|
154
|
+
body: JSON.stringify({ type }),
|
|
155
|
+
}, null);
|
|
156
|
+
}
|
|
38
157
|
async deleteServerUser(userId) {
|
|
39
158
|
await this.sendServerRequest(`/users/${userId}?server=true`, {
|
|
40
159
|
method: "DELETE",
|
package/dist/known-errors.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PermissionDefinitionScopeJson } from "./interface/clientInterface";
|
|
1
2
|
import { StatusError } from "./utils/errors";
|
|
2
3
|
import { Json } from "./utils/json";
|
|
3
4
|
export type KnownErrorJson = {
|
|
@@ -58,6 +59,15 @@ export declare const KnownErrors: {
|
|
|
58
59
|
InvalidProjectAuthentication: KnownErrorConstructor<KnownError & KnownErrorBrand<"PROJECT_AUTHENTICATION_ERROR"> & KnownErrorBrand<"INVALID_PROJECT_AUTHENTICATION">, [statusCode: number, humanReadableMessage: string, details?: Json | undefined]> & {
|
|
59
60
|
errorCode: "INVALID_PROJECT_AUTHENTICATION";
|
|
60
61
|
};
|
|
62
|
+
ProjectKeyWithoutRequestType: KnownErrorConstructor<KnownError & KnownErrorBrand<"PROJECT_AUTHENTICATION_ERROR"> & KnownErrorBrand<"INVALID_PROJECT_AUTHENTICATION"> & KnownErrorBrand<"PROJECT_KEY_WITHOUT_REQUEST_TYPE">, []> & {
|
|
63
|
+
errorCode: "PROJECT_KEY_WITHOUT_REQUEST_TYPE";
|
|
64
|
+
};
|
|
65
|
+
InvalidRequestType: KnownErrorConstructor<KnownError & KnownErrorBrand<"PROJECT_AUTHENTICATION_ERROR"> & KnownErrorBrand<"INVALID_PROJECT_AUTHENTICATION"> & KnownErrorBrand<"INVALID_REQUEST_TYPE">, [requestType: string]> & {
|
|
66
|
+
errorCode: "INVALID_REQUEST_TYPE";
|
|
67
|
+
};
|
|
68
|
+
RequestTypeWithoutProjectId: KnownErrorConstructor<KnownError & KnownErrorBrand<"PROJECT_AUTHENTICATION_ERROR"> & KnownErrorBrand<"INVALID_PROJECT_AUTHENTICATION"> & KnownErrorBrand<"REQUEST_TYPE_WITHOUT_PROJECT_ID">, [requestType: "client" | "server" | "admin"]> & {
|
|
69
|
+
errorCode: "REQUEST_TYPE_WITHOUT_PROJECT_ID";
|
|
70
|
+
};
|
|
61
71
|
InvalidPublishableClientKey: KnownErrorConstructor<KnownError & KnownErrorBrand<"PROJECT_AUTHENTICATION_ERROR"> & KnownErrorBrand<"INVALID_PROJECT_AUTHENTICATION"> & KnownErrorBrand<"INVALID_PUBLISHABLE_CLIENT_KEY">, []> & {
|
|
62
72
|
errorCode: "INVALID_PUBLISHABLE_CLIENT_KEY";
|
|
63
73
|
};
|
|
@@ -79,6 +89,9 @@ export declare const KnownErrors: {
|
|
|
79
89
|
InvalidProjectForAdminAccessToken: KnownErrorConstructor<KnownError & KnownErrorBrand<"PROJECT_AUTHENTICATION_ERROR"> & KnownErrorBrand<"INVALID_PROJECT_AUTHENTICATION"> & KnownErrorBrand<"INVALID_ADMIN_ACCESS_TOKEN"> & KnownErrorBrand<"INVALID_PROJECT_FOR_ADMIN_ACCESS_TOKEN">, []> & {
|
|
80
90
|
errorCode: "INVALID_PROJECT_FOR_ADMIN_ACCESS_TOKEN";
|
|
81
91
|
};
|
|
92
|
+
AdminAccessTokenIsNotAdmin: KnownErrorConstructor<KnownError & KnownErrorBrand<"PROJECT_AUTHENTICATION_ERROR"> & KnownErrorBrand<"INVALID_PROJECT_AUTHENTICATION"> & KnownErrorBrand<"INVALID_ADMIN_ACCESS_TOKEN"> & KnownErrorBrand<"ADMIN_ACCESS_TOKEN_IS_NOT_ADMIN">, []> & {
|
|
93
|
+
errorCode: "ADMIN_ACCESS_TOKEN_IS_NOT_ADMIN";
|
|
94
|
+
};
|
|
82
95
|
ProjectAuthenticationRequired: KnownErrorConstructor<KnownError & KnownErrorBrand<"PROJECT_AUTHENTICATION_ERROR"> & KnownErrorBrand<"PROJECT_AUTHENTICATION_REQUIRED">, [statusCode: number, humanReadableMessage: string, details?: Json | undefined]> & {
|
|
83
96
|
errorCode: "PROJECT_AUTHENTICATION_REQUIRED";
|
|
84
97
|
};
|
|
@@ -214,5 +227,14 @@ export declare const KnownErrors: {
|
|
|
214
227
|
EmailAlreadyVerified: KnownErrorConstructor<KnownError & KnownErrorBrand<"EMAIL_ALREADY_VERIFIED">, []> & {
|
|
215
228
|
errorCode: "EMAIL_ALREADY_VERIFIED";
|
|
216
229
|
};
|
|
230
|
+
PermissionNotFound: KnownErrorConstructor<KnownError & KnownErrorBrand<"PERMISSION_NOT_FOUND">, [permissionId: string]> & {
|
|
231
|
+
errorCode: "PERMISSION_NOT_FOUND";
|
|
232
|
+
};
|
|
233
|
+
PermissionScopeMismatch: KnownErrorConstructor<KnownError & KnownErrorBrand<"PERMISSION_SCOPE_MISMATCH">, [permissionId: string, permissionScope: PermissionDefinitionScopeJson, testScope: PermissionDefinitionScopeJson]> & {
|
|
234
|
+
errorCode: "PERMISSION_SCOPE_MISMATCH";
|
|
235
|
+
};
|
|
236
|
+
TeamNotFound: KnownErrorConstructor<KnownError & KnownErrorBrand<"TEAM_NOT_FOUND">, [teamId: string]> & {
|
|
237
|
+
errorCode: "TEAM_NOT_FOUND";
|
|
238
|
+
};
|
|
217
239
|
};
|
|
218
240
|
export {};
|
package/dist/known-errors.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { StatusError, throwErr, throwStackErr } from "./utils/errors";
|
|
2
2
|
import { identityArgs } from "./utils/functions";
|
|
3
|
+
import { deindent } from "./utils/strings";
|
|
3
4
|
export class KnownError extends StatusError {
|
|
4
5
|
statusCode;
|
|
5
6
|
humanReadableMessage;
|
|
@@ -80,7 +81,13 @@ const SchemaError = createKnownErrorConstructor(KnownError, "SCHEMA_ERROR", (mes
|
|
|
80
81
|
], (json) => [json.message]);
|
|
81
82
|
const AllOverloadsFailed = createKnownErrorConstructor(KnownError, "ALL_OVERLOADS_FAILED", (overloadErrors) => [
|
|
82
83
|
400,
|
|
83
|
-
|
|
84
|
+
deindent `
|
|
85
|
+
This endpoint has multiple overloads, but they all failed to process the request.
|
|
86
|
+
|
|
87
|
+
${overloadErrors.map((e, i) => deindent `
|
|
88
|
+
Overload ${i + 1}: ${JSON.stringify(e, undefined, 2)}
|
|
89
|
+
`).join("\n\n")}
|
|
90
|
+
`,
|
|
84
91
|
{
|
|
85
92
|
overloads: overloadErrors,
|
|
86
93
|
},
|
|
@@ -89,6 +96,23 @@ const AllOverloadsFailed = createKnownErrorConstructor(KnownError, "ALL_OVERLOAD
|
|
|
89
96
|
]);
|
|
90
97
|
const ProjectAuthenticationError = createKnownErrorConstructor(KnownError, "PROJECT_AUTHENTICATION_ERROR", "inherit", "inherit");
|
|
91
98
|
const InvalidProjectAuthentication = createKnownErrorConstructor(ProjectAuthenticationError, "INVALID_PROJECT_AUTHENTICATION", "inherit", "inherit");
|
|
99
|
+
const ProjectKeyWithoutRequestType = createKnownErrorConstructor(InvalidProjectAuthentication, "PROJECT_KEY_WITHOUT_REQUEST_TYPE", () => [
|
|
100
|
+
400,
|
|
101
|
+
"Either an API key or an admin access token was provided, but the x-stack-request-type header is missing. Set it to 'client', 'server', or 'admin' as appropriate.",
|
|
102
|
+
], () => []);
|
|
103
|
+
const InvalidRequestType = createKnownErrorConstructor(InvalidProjectAuthentication, "INVALID_REQUEST_TYPE", (requestType) => [
|
|
104
|
+
400,
|
|
105
|
+
`The x-stack-request-type header must be 'client', 'server', or 'admin', but was '${requestType}'.`,
|
|
106
|
+
], (json) => [
|
|
107
|
+
json.details?.requestType ?? throwErr("requestType not found in InvalidRequestType details"),
|
|
108
|
+
]);
|
|
109
|
+
const RequestTypeWithoutProjectId = createKnownErrorConstructor(InvalidProjectAuthentication, "REQUEST_TYPE_WITHOUT_PROJECT_ID", (requestType) => [
|
|
110
|
+
400,
|
|
111
|
+
`The x-stack-request-type header was '${requestType}', but the x-stack-project-id header was not provided.`,
|
|
112
|
+
{
|
|
113
|
+
requestType,
|
|
114
|
+
},
|
|
115
|
+
], (json) => [json.requestType]);
|
|
92
116
|
const InvalidPublishableClientKey = createKnownErrorConstructor(InvalidProjectAuthentication, "INVALID_PUBLISHABLE_CLIENT_KEY", () => [
|
|
93
117
|
401,
|
|
94
118
|
"The publishable key is not valid for the given project. Does the project and/or the key exist?",
|
|
@@ -114,6 +138,10 @@ const InvalidProjectForAdminAccessToken = createKnownErrorConstructor(InvalidAdm
|
|
|
114
138
|
401,
|
|
115
139
|
"Admin access token not valid for this project.",
|
|
116
140
|
], () => []);
|
|
141
|
+
const AdminAccessTokenIsNotAdmin = createKnownErrorConstructor(InvalidAdminAccessToken, "ADMIN_ACCESS_TOKEN_IS_NOT_ADMIN", () => [
|
|
142
|
+
401,
|
|
143
|
+
"Admin access token does not have the required permissions to access this project.",
|
|
144
|
+
], () => []);
|
|
117
145
|
const ProjectAuthenticationRequired = createKnownErrorConstructor(ProjectAuthenticationError, "PROJECT_AUTHENTICATION_REQUIRED", "inherit", "inherit");
|
|
118
146
|
const ClientAuthenticationRequired = createKnownErrorConstructor(ProjectAuthenticationRequired, "CLIENT_AUTHENTICATION_REQUIRED", () => [
|
|
119
147
|
401,
|
|
@@ -268,12 +296,52 @@ const EmailAlreadyVerified = createKnownErrorConstructor(KnownError, "EMAIL_ALRE
|
|
|
268
296
|
400,
|
|
269
297
|
"The e-mail is already verified.",
|
|
270
298
|
], () => []);
|
|
299
|
+
const PermissionNotFound = createKnownErrorConstructor(KnownError, "PERMISSION_NOT_FOUND", (permissionId) => [
|
|
300
|
+
404,
|
|
301
|
+
`Permission ${permissionId} not found. Make sure you created it on the dashboard.`,
|
|
302
|
+
{
|
|
303
|
+
permissionId,
|
|
304
|
+
},
|
|
305
|
+
], (json) => [json.details.permissionId]);
|
|
306
|
+
const PermissionScopeMismatch = createKnownErrorConstructor(KnownError, "PERMISSION_SCOPE_MISMATCH", (permissionId, permissionScope, testScope) => {
|
|
307
|
+
return [
|
|
308
|
+
400,
|
|
309
|
+
`The scope of the permission with ID ${permissionId} is \`${permissionScope.type}\` but you tested against permissions of scope \`${testScope.type}\`. ${{
|
|
310
|
+
"global": `Please don't specify any teams when using global permissions. For example: \`user.hasPermission(${JSON.stringify(permissionId)})\`.`,
|
|
311
|
+
"any-team": `Please specify the team. For example: \`user.hasPermission(team, ${JSON.stringify(permissionId)})\`.`,
|
|
312
|
+
"specific-team": `Please specify the team. For example: \`user.hasPermission(team, ${JSON.stringify(permissionId)})\`.`,
|
|
313
|
+
}[permissionScope.type]}`,
|
|
314
|
+
{
|
|
315
|
+
permissionId,
|
|
316
|
+
permissionScope,
|
|
317
|
+
testScope,
|
|
318
|
+
},
|
|
319
|
+
];
|
|
320
|
+
}, (json) => [json.details.permissionId, json.details.permissionScope, json.details.testScope]);
|
|
321
|
+
const UserNotInTeam = createKnownErrorConstructor(KnownError, "USER_NOT_IN_TEAM", (userId, teamId) => [
|
|
322
|
+
400,
|
|
323
|
+
`User ${userId} is not in team ${teamId}.`,
|
|
324
|
+
{
|
|
325
|
+
userId,
|
|
326
|
+
teamId,
|
|
327
|
+
},
|
|
328
|
+
], (json) => [json.details.userId, json.details.teamId]);
|
|
329
|
+
const TeamNotFound = createKnownErrorConstructor(KnownError, "TEAM_NOT_FOUND", (teamId) => [
|
|
330
|
+
404,
|
|
331
|
+
`Team ${teamId} not found.`,
|
|
332
|
+
{
|
|
333
|
+
teamId,
|
|
334
|
+
},
|
|
335
|
+
], (json) => [json.details.teamId]);
|
|
271
336
|
export const KnownErrors = {
|
|
272
337
|
UnsupportedError,
|
|
273
338
|
SchemaError,
|
|
274
339
|
AllOverloadsFailed,
|
|
275
340
|
ProjectAuthenticationError,
|
|
276
341
|
InvalidProjectAuthentication,
|
|
342
|
+
ProjectKeyWithoutRequestType,
|
|
343
|
+
InvalidRequestType,
|
|
344
|
+
RequestTypeWithoutProjectId,
|
|
277
345
|
InvalidPublishableClientKey,
|
|
278
346
|
InvalidSecretServerKey,
|
|
279
347
|
InvalidSuperSecretAdminKey,
|
|
@@ -281,6 +349,7 @@ export const KnownErrors = {
|
|
|
281
349
|
UnparsableAdminAccessToken,
|
|
282
350
|
AdminAccessTokenExpired,
|
|
283
351
|
InvalidProjectForAdminAccessToken,
|
|
352
|
+
AdminAccessTokenIsNotAdmin,
|
|
284
353
|
ProjectAuthenticationRequired,
|
|
285
354
|
ClientAuthenticationRequired,
|
|
286
355
|
ServerAuthenticationRequired,
|
|
@@ -326,6 +395,9 @@ export const KnownErrors = {
|
|
|
326
395
|
PasswordResetCodeAlreadyUsed,
|
|
327
396
|
PasswordMismatch,
|
|
328
397
|
EmailAlreadyVerified,
|
|
398
|
+
PermissionNotFound,
|
|
399
|
+
PermissionScopeMismatch,
|
|
400
|
+
TeamNotFound,
|
|
329
401
|
};
|
|
330
402
|
// ensure that all known error codes are unique
|
|
331
403
|
const knownErrorCodes = new Set();
|
package/dist/utils/errors.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export function throwErr(...args) {
|
|
2
2
|
if (typeof args[0] === "string") {
|
|
3
|
-
throw new
|
|
3
|
+
throw new StackAssertionError(args[0]);
|
|
4
4
|
}
|
|
5
5
|
else if (args[0] instanceof Error) {
|
|
6
6
|
throw args[0];
|
|
@@ -28,7 +28,12 @@ export function registerErrorSink(sink) {
|
|
|
28
28
|
}
|
|
29
29
|
errorSinks.add(sink);
|
|
30
30
|
}
|
|
31
|
-
registerErrorSink((location, ...args) =>
|
|
31
|
+
registerErrorSink((location, ...args) => {
|
|
32
|
+
console.error(`Error in ${location}:`, ...args);
|
|
33
|
+
if (process.env.NODE_ENV === "development") {
|
|
34
|
+
debugger;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
32
37
|
export function captureError(location, error) {
|
|
33
38
|
for (const sink of errorSinks) {
|
|
34
39
|
sink(location, error);
|
package/dist/utils/strings.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare function typedToLowercase<S extends string>(s: S): Lowercase<S>;
|
|
2
2
|
export declare function typedToUppercase<S extends string>(s: S): Uppercase<S>;
|
|
3
|
+
export declare function typedCapitalize<S extends string>(s: S): Capitalize<S>;
|
|
3
4
|
/**
|
|
4
5
|
* Returns all whitespace character at the start of the string.
|
|
5
6
|
*
|
package/dist/utils/strings.js
CHANGED
|
@@ -4,6 +4,9 @@ export function typedToLowercase(s) {
|
|
|
4
4
|
export function typedToUppercase(s) {
|
|
5
5
|
return s.toUpperCase();
|
|
6
6
|
}
|
|
7
|
+
export function typedCapitalize(s) {
|
|
8
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
9
|
+
}
|
|
7
10
|
/**
|
|
8
11
|
* Returns all whitespace character at the start of the string.
|
|
9
12
|
*
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type IsAny<T> = 0 extends (1 & T) ? true : false;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stackframe/stack-shared",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.1",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -8,13 +8,23 @@
|
|
|
8
8
|
"dist"
|
|
9
9
|
],
|
|
10
10
|
"peerDependencies": {
|
|
11
|
-
"react": "^18.2"
|
|
11
|
+
"react": "^18.2",
|
|
12
|
+
"yup": "^1.4.0"
|
|
13
|
+
},
|
|
14
|
+
"peerDependenciesMeta": {
|
|
15
|
+
"react": {
|
|
16
|
+
"optional": true
|
|
17
|
+
},
|
|
18
|
+
"yup": {
|
|
19
|
+
"optional": true
|
|
20
|
+
}
|
|
12
21
|
},
|
|
13
22
|
"dependencies": {
|
|
14
23
|
"bcrypt": "^5.1.1",
|
|
15
24
|
"jose": "^5.2.2",
|
|
16
25
|
"oauth4webapi": "^2.10.3",
|
|
17
|
-
"uuid": "^9.0.1"
|
|
26
|
+
"uuid": "^9.0.1",
|
|
27
|
+
"@stackframe/stack-sc": "1.5.1"
|
|
18
28
|
},
|
|
19
29
|
"devDependencies": {
|
|
20
30
|
"@types/bcrypt": "^5.0.2",
|