@stackframe/stack-shared 2.5.7 → 2.5.9

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 CHANGED
@@ -1,5 +1,19 @@
1
1
  # @stackframe/stack-shared
2
2
 
3
+ ## 2.5.9
4
+
5
+ ### Patch Changes
6
+
7
+ - Impersonation
8
+ - @stackframe/stack-sc@2.5.9
9
+
10
+ ## 2.5.8
11
+
12
+ ### Patch Changes
13
+
14
+ - Improved docs
15
+ - @stackframe/stack-sc@2.5.8
16
+
3
17
  ## 2.5.7
4
18
 
5
19
  ### Patch Changes
package/dist/crud.d.ts CHANGED
@@ -11,6 +11,7 @@ declare module 'yup' {
11
11
  description?: string;
12
12
  exampleValue?: any;
13
13
  hidden?: boolean;
14
+ onlyShowInOperations?: Capitalize<CrudlOperation>[];
14
15
  };
15
16
  }
16
17
  }
@@ -18,6 +19,7 @@ type ShownEndpointDocumentation = {
18
19
  summary: string;
19
20
  description: string;
20
21
  tags?: string[];
22
+ crudOperation?: Capitalize<CrudlOperation>;
21
23
  };
22
24
  export type EndpointDocumentation = ({
23
25
  hidden: true;
@@ -3,6 +3,7 @@ import { AccessToken, InternalSession, RefreshToken } from '../sessions';
3
3
  import { ReadonlyJson } from '../utils/json';
4
4
  import { Result } from "../utils/results";
5
5
  import { CurrentUserCrud } from './crud/current-user';
6
+ import { ProviderAccessTokenCrud } from './crud/oauth';
6
7
  import { InternalProjectsCrud, ProjectsCrud } from './crud/projects';
7
8
  import { TeamPermissionsCrud } from './crud/team-permissions';
8
9
  import { TeamsCrud } from './crud/teams';
@@ -15,12 +16,6 @@ export type ClientInterfaceOptions = {
15
16
  } | {
16
17
  projectOwnerSession: InternalSession;
17
18
  });
18
- export type SharedProvider = "shared-github" | "shared-google" | "shared-facebook" | "shared-microsoft" | "shared-spotify";
19
- export declare const sharedProviders: readonly ["shared-github", "shared-google", "shared-facebook", "shared-microsoft", "shared-spotify"];
20
- export type StandardProvider = "github" | "facebook" | "google" | "microsoft" | "spotify";
21
- export declare const standardProviders: readonly ["github", "facebook", "google", "microsoft", "spotify"];
22
- export declare function toStandardProvider(provider: SharedProvider | StandardProvider): StandardProvider;
23
- export declare function toSharedProvider(provider: SharedProvider | StandardProvider): SharedProvider;
24
19
  export declare class StackClientInterface {
25
20
  readonly options: ClientInterfaceOptions;
26
21
  constructor(options: ClientInterfaceOptions);
@@ -46,7 +41,7 @@ export declare class StackClientInterface {
46
41
  featureName?: string;
47
42
  } & ReadonlyJson): Promise<never>;
48
43
  sendForgotPasswordEmail(email: string, callbackUrl: string): Promise<KnownErrors["UserNotFound"] | undefined>;
49
- sendVerificationEmail(emailVerificationRedirectUrl: string, session: InternalSession): Promise<KnownErrors["EmailAlreadyVerified"] | undefined>;
44
+ sendVerificationEmail(email: string, callbackUrl: string, session: InternalSession): Promise<KnownErrors["EmailAlreadyVerified"] | undefined>;
50
45
  sendMagicLinkEmail(email: string, callbackUrl: string): Promise<KnownErrors["RedirectUrlNotWhitelisted"] | undefined>;
51
46
  resetPassword(options: {
52
47
  code: string;
@@ -111,8 +106,6 @@ export declare class StackClientInterface {
111
106
  updateClientUser(update: CurrentUserCrud["Client"]["Update"], session: InternalSession): Promise<void>;
112
107
  listProjects(session: InternalSession): Promise<InternalProjectsCrud['Client']['Read'][]>;
113
108
  createProject(project: InternalProjectsCrud['Client']['Create'], session: InternalSession): Promise<InternalProjectsCrud['Client']['Read']>;
114
- getAccessToken(provider: string, scope: string, session: InternalSession): Promise<{
115
- accessToken: string;
116
- }>;
109
+ createProviderAccessToken(provider: string, scope: string, session: InternalSession): Promise<ProviderAccessTokenCrud['Client']['Read']>;
117
110
  createTeamForCurrentUser(data: TeamsCrud['Client']['Create'], session: InternalSession): Promise<TeamsCrud['Client']['Read']>;
118
111
  }
@@ -6,26 +6,6 @@ import { generateSecureRandomString } from '../utils/crypto';
6
6
  import { StackAssertionError, throwErr } from '../utils/errors';
7
7
  import { globalVar } from '../utils/globals';
8
8
  import { Result } from "../utils/results";
9
- export const sharedProviders = [
10
- "shared-github",
11
- "shared-google",
12
- "shared-facebook",
13
- "shared-microsoft",
14
- "shared-spotify",
15
- ];
16
- export const standardProviders = [
17
- "github",
18
- "facebook",
19
- "google",
20
- "microsoft",
21
- "spotify",
22
- ];
23
- export function toStandardProvider(provider) {
24
- return provider.replace("shared-", "");
25
- }
26
- export function toSharedProvider(provider) {
27
- return "shared-" + provider;
28
- }
29
9
  export class StackClientInterface {
30
10
  constructor(options) {
31
11
  this.options = options;
@@ -254,14 +234,15 @@ export class StackClientInterface {
254
234
  return res.error;
255
235
  }
256
236
  }
257
- async sendVerificationEmail(emailVerificationRedirectUrl, session) {
237
+ async sendVerificationEmail(email, callbackUrl, session) {
258
238
  const res = await this.sendClientRequestAndCatchKnownError("/contact-channels/send-verification-code", {
259
239
  method: "POST",
260
240
  headers: {
261
241
  "Content-Type": "application/json"
262
242
  },
263
243
  body: JSON.stringify({
264
- emailVerificationRedirectUrl,
244
+ email,
245
+ callback_url: callbackUrl,
265
246
  }),
266
247
  }, session, [KnownErrors.EmailAlreadyVerified]);
267
248
  if (res.status === "error") {
@@ -417,7 +398,7 @@ export class StackClientInterface {
417
398
  url.searchParams.set("type", options.type);
418
399
  url.searchParams.set("error_redirect_url", options.errorRedirectUrl);
419
400
  if (options.afterCallbackRedirectUrl) {
420
- url.searchParams.set("after_callback_redirect_rrl", options.afterCallbackRedirectUrl);
401
+ url.searchParams.set("after_callback_redirect_url", options.afterCallbackRedirectUrl);
421
402
  }
422
403
  if (options.type === "link") {
423
404
  const tokens = await options.session.getPotentiallyExpiredTokens();
@@ -551,18 +532,15 @@ export class StackClientInterface {
551
532
  const json = await fetchResponse.json();
552
533
  return json;
553
534
  }
554
- async getAccessToken(provider, scope, session) {
555
- const response = await this.sendClientRequest(`/auth/oauth/connected-account/${provider}/access-token`, {
535
+ async createProviderAccessToken(provider, scope, session) {
536
+ const response = await this.sendClientRequest(`/auth/oauth/connected-accounts/${provider}/access-token`, {
556
537
  method: "POST",
557
538
  headers: {
558
539
  "content-type": "application/json",
559
540
  },
560
541
  body: JSON.stringify({ scope }),
561
542
  }, session);
562
- const json = await response.json();
563
- return {
564
- accessToken: json.accessToken,
565
- };
543
+ return await response.json();
566
544
  }
567
545
  async createTeamForCurrentUser(data, session) {
568
546
  const response = await this.sendClientRequest("/teams?add_current_user=true", {
@@ -8,7 +8,6 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
8
8
  id: string;
9
9
  account_id: string;
10
10
  }[];
11
- project_id: string;
12
11
  primary_email: string | null;
13
12
  profile_image_url: string | null;
14
13
  client_metadata: {} | null;
@@ -24,7 +23,6 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
24
23
  profile_image_url: string | null;
25
24
  } | null;
26
25
  }) | null, import("yup").AnyObject, {
27
- project_id: undefined;
28
26
  id: undefined;
29
27
  primary_email: undefined;
30
28
  primary_email_verified: undefined;
@@ -44,7 +42,6 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
44
42
  server_metadata: undefined;
45
43
  }, "">;
46
44
  serverReadSchema: import("yup").ObjectSchema<{
47
- project_id: string;
48
45
  id: string;
49
46
  primary_email: string | null;
50
47
  primary_email_verified: NonNullable<boolean | undefined>;
@@ -68,7 +65,6 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
68
65
  client_metadata: {} | null;
69
66
  server_metadata: {} | null;
70
67
  } | null, import("yup").AnyObject, {
71
- project_id: undefined;
72
68
  id: undefined;
73
69
  primary_email: undefined;
74
70
  primary_email_verified: undefined;
@@ -9,7 +9,6 @@ const clientUpdateSchema = usersCrudServerUpdateSchema.pick([
9
9
  ]).required();
10
10
  const serverUpdateSchema = usersCrudServerUpdateSchema;
11
11
  const clientReadSchema = usersCrudServerReadSchema.pick([
12
- "project_id",
13
12
  "id",
14
13
  "primary_email",
15
14
  "primary_email_verified",
@@ -1,15 +1,15 @@
1
1
  import { CrudTypeOf } from "../../crud";
2
- export declare const accessTokenReadSchema: import("yup").ObjectSchema<{
2
+ export declare const providerAccessTokenReadSchema: import("yup").ObjectSchema<{
3
3
  access_token: string;
4
4
  }, import("yup").AnyObject, {
5
5
  access_token: undefined;
6
6
  }, "">;
7
- export declare const accessTokenCreateSchema: import("yup").ObjectSchema<{
7
+ export declare const providerAccessTokenCreateSchema: import("yup").ObjectSchema<{
8
8
  scope: string | undefined;
9
9
  }, import("yup").AnyObject, {
10
10
  scope: undefined;
11
11
  }, "">;
12
- export declare const accessTokenCrud: import("../../crud").CrudSchemaFromOptions<{
12
+ export declare const providerAccessTokenCrud: import("../../crud").CrudSchemaFromOptions<{
13
13
  clientReadSchema: import("yup").ObjectSchema<{
14
14
  access_token: string;
15
15
  }, import("yup").AnyObject, {
@@ -21,4 +21,4 @@ export declare const accessTokenCrud: import("../../crud").CrudSchemaFromOptions
21
21
  scope: undefined;
22
22
  }, "">;
23
23
  }>;
24
- export type AccessTokenCrud = CrudTypeOf<typeof accessTokenCrud>;
24
+ export type ProviderAccessTokenCrud = CrudTypeOf<typeof providerAccessTokenCrud>;
@@ -1,12 +1,12 @@
1
1
  import { createCrud } from "../../crud";
2
2
  import { yupObject, yupString } from "../../schema-fields";
3
- export const accessTokenReadSchema = yupObject({
3
+ export const providerAccessTokenReadSchema = yupObject({
4
4
  access_token: yupString().required(),
5
5
  }).required();
6
- export const accessTokenCreateSchema = yupObject({
6
+ export const providerAccessTokenCreateSchema = yupObject({
7
7
  scope: yupString().optional(),
8
8
  }).required();
9
- export const accessTokenCrud = createCrud({
10
- clientReadSchema: accessTokenReadSchema,
11
- clientCreateSchema: accessTokenCreateSchema,
9
+ export const providerAccessTokenCrud = createCrud({
10
+ clientReadSchema: providerAccessTokenReadSchema,
11
+ clientCreateSchema: providerAccessTokenCreateSchema,
12
12
  });
@@ -0,0 +1,72 @@
1
+ import { CrudTypeOf } from "../../crud";
2
+ export declare const teamMemberProfilesCrudClientReadSchema: import("yup").ObjectSchema<{
3
+ team_id: string;
4
+ user_id: string;
5
+ display_name: string | null;
6
+ profile_image_url: string | null;
7
+ }, import("yup").AnyObject, {
8
+ team_id: undefined;
9
+ user_id: undefined;
10
+ display_name: undefined;
11
+ profile_image_url: undefined;
12
+ }, "">;
13
+ export declare const teamMemberProfilesCrudClientUpdateSchema: import("yup").ObjectSchema<{
14
+ display_name: string | undefined;
15
+ profile_image_url: string | null | undefined;
16
+ }, import("yup").AnyObject, {
17
+ display_name: undefined;
18
+ profile_image_url: undefined;
19
+ }, "">;
20
+ export declare const teamMemberProfilesCrud: import("../../crud").CrudSchemaFromOptions<{
21
+ clientReadSchema: import("yup").ObjectSchema<{
22
+ team_id: string;
23
+ user_id: string;
24
+ display_name: string | null;
25
+ profile_image_url: string | null;
26
+ }, import("yup").AnyObject, {
27
+ team_id: undefined;
28
+ user_id: undefined;
29
+ display_name: undefined;
30
+ profile_image_url: undefined;
31
+ }, "">;
32
+ clientUpdateSchema: import("yup").ObjectSchema<{
33
+ display_name: string | undefined;
34
+ profile_image_url: string | null | undefined;
35
+ }, import("yup").AnyObject, {
36
+ display_name: undefined;
37
+ profile_image_url: undefined;
38
+ }, "">;
39
+ docs: {
40
+ clientList: {
41
+ summary: string;
42
+ description: string;
43
+ tags: string[];
44
+ };
45
+ serverList: {
46
+ summary: string;
47
+ description: string;
48
+ tags: string[];
49
+ };
50
+ clientRead: {
51
+ summary: string;
52
+ description: string;
53
+ tags: string[];
54
+ };
55
+ serverRead: {
56
+ summary: string;
57
+ description: string;
58
+ tags: string[];
59
+ };
60
+ clientUpdate: {
61
+ summary: string;
62
+ description: string;
63
+ tags: string[];
64
+ };
65
+ serverUpdate: {
66
+ summary: string;
67
+ description: string;
68
+ tags: string[];
69
+ };
70
+ };
71
+ }>;
72
+ export type TeamMemberProfilesCrud = CrudTypeOf<typeof teamMemberProfilesCrud>;
@@ -0,0 +1,49 @@
1
+ import { createCrud } from "../../crud";
2
+ import * as schemaFields from "../../schema-fields";
3
+ import { yupObject } from "../../schema-fields";
4
+ export const teamMemberProfilesCrudClientReadSchema = yupObject({
5
+ team_id: schemaFields.teamIdSchema.required(),
6
+ user_id: schemaFields.userIdSchema.required(),
7
+ display_name: schemaFields.teamMemberDisplayNameSchema.nullable().defined(),
8
+ profile_image_url: schemaFields.teamMemberProfileImageUrlSchema.nullable().defined(),
9
+ }).required();
10
+ export const teamMemberProfilesCrudClientUpdateSchema = yupObject({
11
+ display_name: schemaFields.teamMemberDisplayNameSchema.optional(),
12
+ profile_image_url: schemaFields.teamMemberProfileImageUrlSchema.nullable().optional(),
13
+ }).required();
14
+ export const teamMemberProfilesCrud = createCrud({
15
+ clientReadSchema: teamMemberProfilesCrudClientReadSchema,
16
+ clientUpdateSchema: teamMemberProfilesCrudClientUpdateSchema,
17
+ docs: {
18
+ clientList: {
19
+ summary: "List team members profiles",
20
+ description: "List team members profiles. You always need to specify a `team_id` that your are a member of on the client. You can always filter for your own profile by setting `me` as the `user_id` in the path parameters. If you want list all the profiles in a team, you need to have the `$read_members` permission in that team.",
21
+ tags: ["Teams"],
22
+ },
23
+ serverList: {
24
+ summary: "List team members profiles",
25
+ description: "List team members profiles and filter by team ID and user ID",
26
+ tags: ["Teams"],
27
+ },
28
+ clientRead: {
29
+ summary: "Get a team member profile",
30
+ description: "Get a team member profile. you can always get your own profile by setting `me` as the `user_id` in the path parameters on the client. If you want to get someone else's profile in a team, you need to have the `$read_members` permission in that team.",
31
+ tags: ["Teams"],
32
+ },
33
+ serverRead: {
34
+ summary: "Get a team member profile",
35
+ description: "Get a team member profile by user ID",
36
+ tags: ["Teams"],
37
+ },
38
+ clientUpdate: {
39
+ summary: "Update your team member profile",
40
+ description: "Update your own team member profile. `user_id` must be `me` in the path parameters on the client.",
41
+ tags: ["Teams"],
42
+ },
43
+ serverUpdate: {
44
+ summary: "Update a team member profile",
45
+ description: "Update a team member profile by user ID",
46
+ tags: ["Teams"],
47
+ },
48
+ },
49
+ });
@@ -1,11 +1,11 @@
1
1
  import { CrudTypeOf } from "../../crud";
2
- export declare const teamMembershipsCrudServerReadSchema: import("yup").ObjectSchema<{}, import("yup").AnyObject, {}, "">;
2
+ export declare const teamMembershipsCrudClientReadSchema: import("yup").ObjectSchema<{}, import("yup").AnyObject, {}, "">;
3
3
  export declare const teamMembershipsCrudServerCreateSchema: import("yup").ObjectSchema<{}, import("yup").AnyObject, {}, "">;
4
- export declare const teamMembershipsCrudServerDeleteSchema: import("yup").MixedSchema<{} | undefined, import("yup").AnyObject, undefined, "">;
4
+ export declare const teamMembershipsCrudClientDeleteSchema: import("yup").MixedSchema<{} | undefined, import("yup").AnyObject, undefined, "">;
5
5
  export declare const teamMembershipsCrud: import("../../crud").CrudSchemaFromOptions<{
6
- serverReadSchema: import("yup").ObjectSchema<{}, import("yup").AnyObject, {}, "">;
6
+ clientReadSchema: import("yup").ObjectSchema<{}, import("yup").AnyObject, {}, "">;
7
+ clientDeleteSchema: import("yup").MixedSchema<{} | undefined, import("yup").AnyObject, undefined, "">;
7
8
  serverCreateSchema: import("yup").ObjectSchema<{}, import("yup").AnyObject, {}, "">;
8
- serverDeleteSchema: import("yup").MixedSchema<{} | undefined, import("yup").AnyObject, undefined, "">;
9
9
  docs: {
10
10
  serverCreate: {
11
11
  summary: string;
@@ -1,12 +1,14 @@
1
1
  import { createCrud } from "../../crud";
2
2
  import { yupMixed, yupObject } from "../../schema-fields";
3
- export const teamMembershipsCrudServerReadSchema = yupObject({}).required();
3
+ export const teamMembershipsCrudClientReadSchema = yupObject({}).required();
4
4
  export const teamMembershipsCrudServerCreateSchema = yupObject({}).required();
5
- export const teamMembershipsCrudServerDeleteSchema = yupMixed();
5
+ export const teamMembershipsCrudClientDeleteSchema = yupMixed();
6
6
  export const teamMembershipsCrud = createCrud({
7
- serverReadSchema: teamMembershipsCrudServerReadSchema,
7
+ // Client
8
+ clientReadSchema: teamMembershipsCrudClientReadSchema,
9
+ clientDeleteSchema: teamMembershipsCrudClientDeleteSchema,
10
+ // Server
8
11
  serverCreateSchema: teamMembershipsCrudServerCreateSchema,
9
- serverDeleteSchema: teamMembershipsCrudServerDeleteSchema,
10
12
  docs: {
11
13
  serverCreate: {
12
14
  summary: "Add a user to a team",
@@ -15,13 +15,13 @@ export const teamPermissionsCrud = createCrud({
15
15
  serverDeleteSchema: teamPermissionsCrudServerDeleteSchema,
16
16
  docs: {
17
17
  clientList: {
18
- summary: "List team permissions of the current user",
19
- description: "user_id=me needs to be set",
18
+ summary: "List team permissions",
19
+ description: "List team permissions of the current user. `user_id=me` must be set for client requests. Note that this might contain the permissions with the same permission ID across different teams. `(team_id, user_id, permission_id)` together uniquely identify a permission.",
20
20
  tags: ["Permissions"],
21
21
  },
22
22
  serverList: {
23
23
  summary: "List team permissions of a user",
24
- description: "Query and filter the permission with team_id, user_id, and permission_id",
24
+ description: "Query and filter the permission with `team_id`, `user_id`, and `permission_id`. Note that this might contain the permissions with the same permission ID across different teams and users. `(team_id, user_id, permission_id)` together uniquely identify a permission.",
25
25
  tags: ["Permissions"],
26
26
  },
27
27
  serverCreate: {
@@ -64,6 +64,13 @@ export declare const teamsCrud: import("../../crud").CrudSchemaFromOptions<{
64
64
  display_name: undefined;
65
65
  profile_image_url: undefined;
66
66
  }, "">;
67
+ clientUpdateSchema: import("yup").ObjectSchema<{
68
+ display_name: string | undefined;
69
+ profile_image_url: string | null | undefined;
70
+ }, import("yup").AnyObject, {
71
+ display_name: undefined;
72
+ profile_image_url: undefined;
73
+ }, "">;
67
74
  clientCreateSchema: import("yup").ObjectSchema<{
68
75
  display_name: string;
69
76
  profile_image_url: string | null | undefined;
@@ -73,6 +80,7 @@ export declare const teamsCrud: import("../../crud").CrudSchemaFromOptions<{
73
80
  display_name: undefined;
74
81
  profile_image_url: undefined;
75
82
  }, "">;
83
+ clientDeleteSchema: import("yup").MixedSchema<{} | undefined, import("yup").AnyObject, undefined, "">;
76
84
  serverReadSchema: import("yup").ObjectSchema<{
77
85
  id: string;
78
86
  display_name: string;
@@ -5,7 +5,7 @@ import { yupMixed, yupObject } from "../../schema-fields";
5
5
  export const teamsCrudClientReadSchema = yupObject({
6
6
  id: fieldSchema.teamIdSchema.required(),
7
7
  display_name: fieldSchema.teamDisplayNameSchema.required(),
8
- profile_image_url: fieldSchema.profileImageUrlSchema.nullable().defined(),
8
+ profile_image_url: fieldSchema.teamProfileImageUrlSchema.nullable().defined(),
9
9
  }).required();
10
10
  export const teamsCrudServerReadSchema = teamsCrudClientReadSchema.concat(yupObject({
11
11
  created_at_millis: fieldSchema.teamCreatedAtMillisSchema.required(),
@@ -13,7 +13,7 @@ export const teamsCrudServerReadSchema = teamsCrudClientReadSchema.concat(yupObj
13
13
  // Update
14
14
  export const teamsCrudClientUpdateSchema = yupObject({
15
15
  display_name: fieldSchema.teamDisplayNameSchema.optional(),
16
- profile_image_url: fieldSchema.profileImageUrlSchema.nullable().optional(),
16
+ profile_image_url: fieldSchema.teamProfileImageUrlSchema.nullable().optional(),
17
17
  }).required();
18
18
  export const teamsCrudServerUpdateSchema = teamsCrudClientUpdateSchema.concat(yupObject({}).required());
19
19
  // Create
@@ -27,10 +27,12 @@ export const teamsCrudServerCreateSchema = teamsCrudServerUpdateSchema.concat(yu
27
27
  export const teamsCrudClientDeleteSchema = yupMixed();
28
28
  export const teamsCrudServerDeleteSchema = teamsCrudClientDeleteSchema;
29
29
  export const teamsCrud = createCrud({
30
+ // Client
30
31
  clientReadSchema: teamsCrudClientReadSchema,
31
- // clientUpdateSchema: teamsCrudClientUpdateSchema,
32
+ clientUpdateSchema: teamsCrudClientUpdateSchema,
32
33
  clientCreateSchema: teamsCrudClientCreateSchema,
33
- // clientDeleteSchema: teamsCrudClientDeleteSchema,
34
+ clientDeleteSchema: teamsCrudClientDeleteSchema,
35
+ // Server
34
36
  serverReadSchema: teamsCrudServerReadSchema,
35
37
  serverUpdateSchema: teamsCrudServerUpdateSchema,
36
38
  serverCreateSchema: teamsCrudServerCreateSchema,
@@ -38,12 +40,12 @@ export const teamsCrud = createCrud({
38
40
  docs: {
39
41
  clientList: {
40
42
  summary: "List teams",
41
- description: "List all the teams that the current user is a member of.",
43
+ description: "List all the teams that the current user is a member of. `user_id=me` must be passed in the query parameters.",
42
44
  tags: ["Teams"],
43
45
  },
44
46
  clientCreate: {
45
47
  summary: "Create a team",
46
- description: "Create a new team and add the current user as a member.",
48
+ description: "Create a new team and optionally add the current user as a member.",
47
49
  tags: ["Teams"],
48
50
  },
49
51
  clientRead: {
@@ -53,7 +55,7 @@ export const teamsCrud = createCrud({
53
55
  },
54
56
  serverCreate: {
55
57
  summary: "Create a team",
56
- description: "Create a new team and add the current user as a member.",
58
+ description: "Create a new team and optionally add the current user as a member.",
57
59
  tags: ["Teams"],
58
60
  },
59
61
  serverList: {
@@ -68,7 +70,7 @@ export const teamsCrud = createCrud({
68
70
  },
69
71
  serverUpdate: {
70
72
  summary: "Update a team",
71
- description: "Update a team by ID.",
73
+ description: "Update the team information by ID.",
72
74
  tags: ["Teams"],
73
75
  },
74
76
  serverDelete: {
@@ -21,7 +21,6 @@ export declare const usersCrudServerUpdateSchema: import("yup").ObjectSchema<{
21
21
  selected_team_id: undefined;
22
22
  }, "">;
23
23
  export declare const usersCrudServerReadSchema: import("yup").ObjectSchema<{
24
- project_id: string;
25
24
  id: string;
26
25
  primary_email: string | null;
27
26
  primary_email_verified: NonNullable<boolean | undefined>;
@@ -45,7 +44,6 @@ export declare const usersCrudServerReadSchema: import("yup").ObjectSchema<{
45
44
  client_metadata: {} | null;
46
45
  server_metadata: {} | null;
47
46
  }, import("yup").AnyObject, {
48
- project_id: undefined;
49
47
  id: undefined;
50
48
  primary_email: undefined;
51
49
  primary_email_verified: undefined;
@@ -96,7 +94,6 @@ export declare const usersCrudServerCreateSchema: import("yup").ObjectSchema<{
96
94
  export declare const usersCrudServerDeleteSchema: import("yup").MixedSchema<{} | undefined, import("yup").AnyObject, undefined, "">;
97
95
  export declare const usersCrud: import("../../crud").CrudSchemaFromOptions<{
98
96
  serverReadSchema: import("yup").ObjectSchema<{
99
- project_id: string;
100
97
  id: string;
101
98
  primary_email: string | null;
102
99
  primary_email_verified: NonNullable<boolean | undefined>;
@@ -120,7 +117,6 @@ export declare const usersCrud: import("../../crud").CrudSchemaFromOptions<{
120
117
  client_metadata: {} | null;
121
118
  server_metadata: {} | null;
122
119
  }, import("yup").AnyObject, {
123
- project_id: undefined;
124
120
  id: undefined;
125
121
  primary_email: undefined;
126
122
  primary_email_verified: undefined;
@@ -13,7 +13,6 @@ export const usersCrudServerUpdateSchema = fieldSchema.yupObject({
13
13
  selected_team_id: fieldSchema.selectedTeamIdSchema.nullable().optional(),
14
14
  }).required();
15
15
  export const usersCrudServerReadSchema = fieldSchema.yupObject({
16
- project_id: fieldSchema.projectIdSchema.required(),
17
16
  id: fieldSchema.userIdSchema.required(),
18
17
  primary_email: fieldSchema.primaryEmailSchema.nullable().defined(),
19
18
  primary_email_verified: fieldSchema.primaryEmailVerifiedSchema.required(),
@@ -28,7 +27,7 @@ export const usersCrudServerReadSchema = fieldSchema.yupObject({
28
27
  id: fieldSchema.yupString().required(),
29
28
  account_id: fieldSchema.yupString().required(),
30
29
  email: fieldSchema.yupString().nullable(),
31
- }).required()).required().meta({ openapiField: { description: 'A list of OAuth providers connected to this account', exampleValue: ['google', 'github'] } }),
30
+ }).required()).required().meta({ openapiField: { description: 'A list of OAuth providers connected to this account', exampleValue: [{ id: 'google', account_id: '12345', email: 'john.doe@gmail.com' }] } }),
32
31
  client_metadata: fieldSchema.userClientMetadataSchema,
33
32
  server_metadata: fieldSchema.userServerMetadataSchema,
34
33
  }).required();
@@ -5,8 +5,8 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
5
5
  display_name: string | null;
6
6
  oauth_providers: {
7
7
  email?: string | null | undefined;
8
- account_id: string;
9
8
  provider_id: string;
9
+ account_id: string;
10
10
  }[];
11
11
  project_id: string;
12
12
  primary_email: string | null;
@@ -48,8 +48,8 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
48
48
  auth_with_email: NonNullable<boolean | undefined>;
49
49
  oauth_providers: {
50
50
  email?: string | null | undefined;
51
- account_id: string;
52
51
  provider_id: string;
52
+ account_id: string;
53
53
  }[];
54
54
  client_metadata: {} | null;
55
55
  server_metadata: {} | null;
@@ -34,8 +34,8 @@ export declare const usersCrudServerReadSchema: import("yup").ObjectSchema<{
34
34
  auth_with_email: NonNullable<boolean | undefined>;
35
35
  oauth_providers: {
36
36
  email?: string | null | undefined;
37
- account_id: string;
38
37
  provider_id: string;
38
+ account_id: string;
39
39
  }[];
40
40
  client_metadata: {} | null;
41
41
  server_metadata: {} | null;
@@ -68,8 +68,8 @@ export declare const usersCrudServerCreateSchema: import("yup").ObjectSchema<{
68
68
  } & {
69
69
  oauth_providers: {
70
70
  email: string | null;
71
- account_id: string;
72
71
  provider_id: string;
72
+ account_id: string;
73
73
  }[] | undefined;
74
74
  }, import("yup").AnyObject, {
75
75
  display_name: undefined;
@@ -99,8 +99,8 @@ export declare const usersCrud: import("../../crud").CrudSchemaFromOptions<{
99
99
  auth_with_email: NonNullable<boolean | undefined>;
100
100
  oauth_providers: {
101
101
  email?: string | null | undefined;
102
- account_id: string;
103
102
  provider_id: string;
103
+ account_id: string;
104
104
  }[];
105
105
  client_metadata: {} | null;
106
106
  server_metadata: {} | null;
@@ -154,8 +154,8 @@ export declare const usersCrud: import("../../crud").CrudSchemaFromOptions<{
154
154
  } & {
155
155
  oauth_providers: {
156
156
  email: string | null;
157
- account_id: string;
158
157
  provider_id: string;
158
+ account_id: string;
159
159
  }[] | undefined;
160
160
  }, import("yup").AnyObject, {
161
161
  display_name: undefined;
@@ -49,6 +49,10 @@ export declare class StackServerInterface extends StackClientInterface {
49
49
  teamId: string;
50
50
  }): Promise<void>;
51
51
  updateServerUser(userId: string, update: UsersCrud['Server']['Update']): Promise<UsersCrud['Server']['Read']>;
52
+ createServerUserSession(userId: string, expiresInMillis: number): Promise<{
53
+ accessToken: string;
54
+ refreshToken: string;
55
+ }>;
52
56
  listServerTeamMemberPermissions(options: {
53
57
  teamId: string;
54
58
  userId: string;
@@ -130,6 +130,23 @@ export class StackServerInterface extends StackClientInterface {
130
130
  }, null);
131
131
  return await response.json();
132
132
  }
133
+ async createServerUserSession(userId, expiresInMillis) {
134
+ const response = await this.sendServerRequest("/auth/sessions", {
135
+ method: "POST",
136
+ headers: {
137
+ "content-type": "application/json",
138
+ },
139
+ body: JSON.stringify({
140
+ user_id: userId,
141
+ expires_in_millis: expiresInMillis,
142
+ }),
143
+ }, null);
144
+ const result = await response.json();
145
+ return {
146
+ accessToken: result.access_token,
147
+ refreshToken: result.refresh_token,
148
+ };
149
+ }
133
150
  async listServerTeamMemberPermissions(options) {
134
151
  const response = await this.sendServerRequest(`/team-permissions?team_id=${options.teamId}&user_id=${options.userId}&recursive=${options.recursive}`, {}, null);
135
152
  const result = await response.json();
@@ -233,6 +233,9 @@ export declare const KnownErrors: {
233
233
  UserEmailAlreadyExists: KnownErrorConstructor<KnownError & KnownErrorBrand<"USER_EMAIL_ALREADY_EXISTS">, []> & {
234
234
  errorCode: "USER_EMAIL_ALREADY_EXISTS";
235
235
  };
236
+ UserIdDoesNotExist: KnownErrorConstructor<KnownError & KnownErrorBrand<"USER_ID_DOES_NOT_EXIST">, [userId: string]> & {
237
+ errorCode: "USER_ID_DOES_NOT_EXIST";
238
+ };
236
239
  UserNotFound: KnownErrorConstructor<KnownError & KnownErrorBrand<"USER_NOT_FOUND">, []> & {
237
240
  errorCode: "USER_NOT_FOUND";
238
241
  };
@@ -348,5 +351,14 @@ export declare const KnownErrors: {
348
351
  TeamMembershipAlreadyExists: KnownErrorConstructor<KnownError & KnownErrorBrand<"TEAM_MEMBERSHIP_ALREADY_EXISTS">, []> & {
349
352
  errorCode: "TEAM_MEMBERSHIP_ALREADY_EXISTS";
350
353
  };
354
+ TeamPermissionRequired: KnownErrorConstructor<KnownError & KnownErrorBrand<"TEAM_PERMISSION_REQUIRED">, [any, any, any]> & {
355
+ errorCode: "TEAM_PERMISSION_REQUIRED";
356
+ };
357
+ InvalidSharedOAuthProviderId: KnownErrorConstructor<KnownError & KnownErrorBrand<"INVALID_SHARED_OAUTH_PROVIDER_ID">, [any]> & {
358
+ errorCode: "INVALID_SHARED_OAUTH_PROVIDER_ID";
359
+ };
360
+ InvalidStandardOAuthProviderId: KnownErrorConstructor<KnownError & KnownErrorBrand<"INVALID_STANDARD_OAUTH_PROVIDER_ID">, [any]> & {
361
+ errorCode: "INVALID_STANDARD_OAUTH_PROVIDER_ID";
362
+ };
351
363
  };
352
364
  export {};
@@ -146,14 +146,22 @@ const InvalidAccessType = createKnownErrorConstructor(InvalidProjectAuthenticati
146
146
  ]);
147
147
  const AccessTypeWithoutProjectId = createKnownErrorConstructor(InvalidProjectAuthentication, "ACCESS_TYPE_WITHOUT_PROJECT_ID", (accessType) => [
148
148
  400,
149
- `The x-stack-access-type header was '${accessType}', but the x-stack-project-id header was not provided.`,
149
+ deindent `
150
+ The x-stack-access-type header was '${accessType}', but the x-stack-project-id header was not provided.
151
+
152
+ For more information, see the docs on REST API authentication: https://docs.stack-auth.com/rest-api/auth#authentication
153
+ `,
150
154
  {
151
155
  request_type: accessType,
152
156
  },
153
157
  ], (json) => [json.request_type]);
154
158
  const AccessTypeRequired = createKnownErrorConstructor(InvalidProjectAuthentication, "ACCESS_TYPE_REQUIRED", () => [
155
159
  400,
156
- `You must specify an access level for this Stack project. Make sure project API keys are provided (eg. x-stack-publishable-client-key) and you set the x-stack-access-type header to 'client', 'server', or 'admin'.`,
160
+ deindent `
161
+ You must specify an access level for this Stack project. Make sure project API keys are provided (eg. x-stack-publishable-client-key) and you set the x-stack-access-type header to 'client', 'server', or 'admin'.
162
+
163
+ For more information, see the docs on REST API authentication: https://docs.stack-auth.com/rest-api/auth#authentication
164
+ `,
157
165
  ], () => []);
158
166
  const InsufficientAccessType = createKnownErrorConstructor(InvalidProjectAuthentication, "INSUFFICIENT_ACCESS_TYPE", (actualAccessType, allowedAccessTypes) => [
159
167
  401,
@@ -286,6 +294,13 @@ const CannotGetOwnUserWithoutUser = createKnownErrorConstructor(KnownError, "CAN
286
294
  400,
287
295
  "You have specified 'me' as a userId, but did not provide authentication for a user.",
288
296
  ], () => []);
297
+ const UserIdDoesNotExist = createKnownErrorConstructor(KnownError, "USER_ID_DOES_NOT_EXIST", (userId) => [
298
+ 400,
299
+ `The given user with the ID ${userId} does not exist.`,
300
+ {
301
+ user_id: userId,
302
+ },
303
+ ], (json) => [json.user_id]);
289
304
  const UserNotFound = createKnownErrorConstructor(KnownError, "USER_NOT_FOUND", () => [
290
305
  404,
291
306
  "User not found.",
@@ -464,6 +479,29 @@ const TeamMembershipAlreadyExists = createKnownErrorConstructor(KnownError, "TEA
464
479
  400,
465
480
  "Team membership already exists.",
466
481
  ], () => []);
482
+ const TeamPermissionRequired = createKnownErrorConstructor(KnownError, "TEAM_PERMISSION_REQUIRED", (teamId, userId, permissionId) => [
483
+ 401,
484
+ `User ${userId} does not have permission ${permissionId} in team ${teamId}.`,
485
+ {
486
+ team_id: teamId,
487
+ user_id: userId,
488
+ permission_id: permissionId,
489
+ },
490
+ ], (json) => [json.team_id, json.user_id, json.permission_id]);
491
+ const InvalidSharedOAuthProviderId = createKnownErrorConstructor(KnownError, "INVALID_SHARED_OAUTH_PROVIDER_ID", (providerId) => [
492
+ 400,
493
+ `The shared OAuth provider with ID ${providerId} is not valid.`,
494
+ {
495
+ provider_id: providerId,
496
+ },
497
+ ], (json) => [json.provider_id]);
498
+ const InvalidStandardOAuthProviderId = createKnownErrorConstructor(KnownError, "INVALID_STANDARD_OAUTH_PROVIDER_ID", (providerId) => [
499
+ 400,
500
+ `The standard OAuth provider with ID ${providerId} is not valid.`,
501
+ {
502
+ provider_id: providerId,
503
+ },
504
+ ], (json) => [json.provider_id]);
467
505
  export const KnownErrors = {
468
506
  UnsupportedError,
469
507
  BodyParsingError,
@@ -506,6 +544,7 @@ export const KnownErrors = {
506
544
  ProviderRejected,
507
545
  RefreshTokenNotFoundOrExpired,
508
546
  UserEmailAlreadyExists,
547
+ UserIdDoesNotExist,
509
548
  UserNotFound,
510
549
  ApiKeyNotFound,
511
550
  ProjectNotFound,
@@ -541,6 +580,9 @@ export const KnownErrors = {
541
580
  OAuthProviderNotFoundOrNotEnabled,
542
581
  UserAuthenticationRequired,
543
582
  TeamMembershipAlreadyExists,
583
+ TeamPermissionRequired,
584
+ InvalidSharedOAuthProviderId,
585
+ InvalidStandardOAuthProviderId,
544
586
  };
545
587
  // ensure that all known error codes are unique
546
588
  const knownErrorCodes = new Set();
@@ -19,6 +19,7 @@ export declare const adaptSchema: yup.MixedSchema<typeof StackAdaptSentinel | un
19
19
  export declare const urlSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
20
20
  export declare const jsonSchema: yup.MixedSchema<{} | null, yup.AnyObject, undefined, "">;
21
21
  export declare const jsonStringSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
22
+ export declare const jsonStringOrEmptySchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
22
23
  export declare const emailSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
23
24
  export declare const clientOrHigherAuthTypeSchema: yup.StringSchema<"client" | "server" | "admin" | undefined, yup.AnyObject, undefined, "">;
24
25
  export declare const serverOrHigherAuthTypeSchema: yup.StringSchema<"server" | "admin" | undefined, yup.AnyObject, undefined, "">;
@@ -85,8 +86,11 @@ export declare const teamPermissionDescriptionSchema: yup.StringSchema<string |
85
86
  export declare const containedPermissionIdsSchema: yup.ArraySchema<string[] | undefined, yup.AnyObject, undefined, "">;
86
87
  export declare const teamIdSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
87
88
  export declare const teamDisplayNameSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
89
+ export declare const teamProfileImageUrlSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
88
90
  export declare const teamClientMetadataSchema: yup.MixedSchema<{} | null, yup.AnyObject, undefined, "">;
89
91
  export declare const teamServerMetadataSchema: yup.MixedSchema<{} | null, yup.AnyObject, undefined, "">;
90
92
  export declare const teamCreatedAtMillisSchema: yup.NumberSchema<number | undefined, yup.AnyObject, undefined, "">;
93
+ export declare const teamMemberDisplayNameSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
94
+ export declare const teamMemberProfileImageUrlSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
91
95
  export declare function yupRequiredWhen<S extends yup.AnyObject>(schema: S, triggerName: string, isValue: any): S;
92
96
  export {};
@@ -1,12 +1,14 @@
1
1
  import * as yup from "yup";
2
+ import { allProviders } from "./utils/oauth";
2
3
  import { isUuid } from "./utils/uuids";
3
- const _idDescription = (identify) => `The immutable ID used to uniquely identify this ${identify}`;
4
- const _displayNameDescription = (identify) => `Human-readable ${identify} display name, used in places like frontend UI. This is not a unique identifier.`;
4
+ const _idDescription = (identify) => `The unique identifier of this ${identify}`;
5
+ const _displayNameDescription = (identify) => `Human-readable ${identify} display name. This is not a unique identifier.`;
5
6
  const _clientMetaDataDescription = (identify) => `Client metadata. Used as a data store, accessible from the client side. Do not store information that should not be exposed to the client.`;
7
+ const _profileImageUrlDescription = (identify) => `URL of the profile image for ${identify}. Can be a Base64 encoded image. Please compress and crop to a square before passing in.`;
6
8
  const _serverMetaDataDescription = (identify) => `Server metadata. Used as a data store, only accessible from the server side. You can store secret information related to the ${identify} here.`;
7
9
  const _atMillisDescription = (identify) => `(the number of milliseconds since epoch, January 1, 1970, UTC)`;
8
10
  const _createdAtMillisDescription = (identify) => `The time the ${identify} was created ${_atMillisDescription(identify)}`;
9
- const _updatedAtMillisDescription = (identify) => `The time the ${identify} was last updated ${_atMillisDescription(identify)}`;
11
+ const _signedUpAtMillisDescription = `The time the user signed up ${_atMillisDescription}`;
10
12
  // Built-in replacements
11
13
  /* eslint-disable no-restricted-syntax */
12
14
  export function yupString(...args) {
@@ -85,6 +87,17 @@ export const jsonStringSchema = yupString().test("json", "Invalid JSON format",
85
87
  return false;
86
88
  }
87
89
  });
90
+ export const jsonStringOrEmptySchema = yupString().test("json", "Invalid JSON format", (value) => {
91
+ if (!value)
92
+ return true;
93
+ try {
94
+ JSON.parse(value);
95
+ return true;
96
+ }
97
+ catch (error) {
98
+ return false;
99
+ }
100
+ });
88
101
  export const emailSchema = yupString().email();
89
102
  // Request auth
90
103
  export const clientOrHigherAuthTypeSchema = yupString().oneOf(['client', 'server', 'admin']);
@@ -104,7 +117,7 @@ export const projectCreateTeamOnSignUpSchema = yupBoolean().meta({ openapiField:
104
117
  export const projectMagicLinkEnabledSchema = yupBoolean().meta({ openapiField: { description: 'Whether magic link authentication is enabled for this project', exampleValue: true } });
105
118
  export const projectCredentialEnabledSchema = yupBoolean().meta({ openapiField: { description: 'Whether email password authentication is enabled for this project', exampleValue: true } });
106
119
  // Project OAuth config
107
- export const oauthIdSchema = yupString().oneOf(['google', 'github', 'facebook', 'microsoft', 'spotify']).meta({ openapiField: { description: 'OAuth provider ID, one of google, github, facebook, microsoft, spotify', exampleValue: 'google' } });
120
+ export const oauthIdSchema = yupString().oneOf(allProviders).meta({ openapiField: { description: `OAuth provider ID, one of ${allProviders.map(x => `\`${x}\``).join(', ')}`, exampleValue: 'google' } });
108
121
  export const oauthEnabledSchema = yupBoolean().meta({ openapiField: { description: 'Whether the OAuth provider is enabled. If an provider is first enabled, then disabled, it will be shown in the list but with enabled=false', exampleValue: true } });
109
122
  export const oauthTypeSchema = yupString().oneOf(['shared', 'standard']).meta({ openapiField: { description: 'OAuth provider type, one of shared, standard. "shared" uses Stack shared OAuth keys and it is only meant for development. "standard" uses your own OAuth keys and will show your logo and company name when signing in with the provider.', exampleValue: 'standard' } });
110
123
  export const oauthClientIdSchema = yupString().meta({ openapiField: { description: 'OAuth client ID. Needs to be specified when using type="standard"', exampleValue: 'google-oauth-client-id' } });
@@ -143,8 +156,8 @@ export const primaryEmailSchema = emailSchema.meta({ openapiField: { description
143
156
  export const primaryEmailVerifiedSchema = yupBoolean().meta({ openapiField: { description: 'Whether the primary email has been verified to belong to this user', exampleValue: true } });
144
157
  export const userDisplayNameSchema = yupString().nullable().meta({ openapiField: { description: _displayNameDescription('user'), exampleValue: 'John Doe' } });
145
158
  export const selectedTeamIdSchema = yupString().meta({ openapiField: { description: 'ID of the team currently selected by the user', exampleValue: 'team-id' } });
146
- export const profileImageUrlSchema = yupString().meta({ openapiField: { description: 'Profile image URL', exampleValue: 'https://example.com/image.jpg' } });
147
- export const signedUpAtMillisSchema = yupNumber().meta({ openapiField: { description: 'Signed up at milliseconds', exampleValue: 1630000000000 } });
159
+ export const profileImageUrlSchema = yupString().meta({ openapiField: { description: _profileImageUrlDescription('user'), exampleValue: 'https://example.com/image.jpg' } });
160
+ export const signedUpAtMillisSchema = yupNumber().meta({ openapiField: { description: _signedUpAtMillisDescription, exampleValue: 1630000000000 } });
148
161
  export const userClientMetadataSchema = jsonSchema.meta({ openapiField: { description: _clientMetaDataDescription('user'), exampleValue: { key: 'value' } } });
149
162
  export const userServerMetadataSchema = jsonSchema.meta({ openapiField: { description: _serverMetaDataDescription('user'), exampleValue: { key: 'value' } } });
150
163
  // Auth
@@ -177,7 +190,7 @@ export const teamPermissionDefinitionIdSchema = yupString()
177
190
  }
178
191
  return true;
179
192
  })
180
- .meta({ openapiField: { description: `The permission ID used to uniquely identify a permission. Can either be a custom permission with lowercase letters, numbers, ":", and "_" characters, or one of the system permissions: ${teamSystemPermissions.join(', ')}`, exampleValue: '$read_secret_info' } });
193
+ .meta({ openapiField: { description: `The permission ID used to uniquely identify a permission. Can either be a custom permission with lowercase letters, numbers, \`:\`, and \`_\` characters, or one of the system permissions: ${teamSystemPermissions.map(x => `\`${x}\``).join(', ')}`, exampleValue: 'read_secret_info' } });
181
194
  export const customTeamPermissionDefinitionIdSchema = yupString()
182
195
  .matches(/^[a-z0-9_:]+$/, 'Only lowercase letters, numbers, ":", "_" are allowed')
183
196
  .meta({ openapiField: { description: 'The permission ID used to uniquely identify a permission. Can only contain lowercase letters, numbers, ":", and "_" characters', exampleValue: 'read_secret_info' } });
@@ -186,9 +199,13 @@ export const containedPermissionIdsSchema = yupArray(teamPermissionDefinitionIdS
186
199
  // Teams
187
200
  export const teamIdSchema = yupString().uuid().meta({ openapiField: { description: _idDescription('team'), exampleValue: 'ad962777-8244-496a-b6a2-e0c6a449c79e' } });
188
201
  export const teamDisplayNameSchema = yupString().meta({ openapiField: { description: _displayNameDescription('team'), exampleValue: 'My Team' } });
202
+ export const teamProfileImageUrlSchema = yupString().meta({ openapiField: { description: _profileImageUrlDescription('team'), exampleValue: 'https://example.com/image.jpg' } });
189
203
  export const teamClientMetadataSchema = jsonSchema.meta({ openapiField: { description: _clientMetaDataDescription('team'), exampleValue: { key: 'value' } } });
190
204
  export const teamServerMetadataSchema = jsonSchema.meta({ openapiField: { description: _serverMetaDataDescription('team'), exampleValue: { key: 'value' } } });
191
205
  export const teamCreatedAtMillisSchema = yupNumber().meta({ openapiField: { description: _createdAtMillisDescription('team'), exampleValue: 1630000000000 } });
206
+ // Team member profiles
207
+ export const teamMemberDisplayNameSchema = yupString().meta({ openapiField: { description: _displayNameDescription('team member') + ' Note that this is separate from the display_name of the user.', exampleValue: 'John Doe' } });
208
+ export const teamMemberProfileImageUrlSchema = yupString().meta({ openapiField: { description: _profileImageUrlDescription('team member'), exampleValue: 'https://example.com/image.jpg' } });
192
209
  // Utils
193
210
  export function yupRequiredWhen(schema, triggerName, isValue) {
194
211
  return schema.when(triggerName, {
@@ -13,7 +13,7 @@ export function throwErr(...args) {
13
13
  }
14
14
  export class StackAssertionError extends Error {
15
15
  constructor(message, extraData, options) {
16
- const disclaimer = `\n\nThis is likely an error in Stack. Please report it.`;
16
+ const disclaimer = `\n\nThis is likely an error in Stack. Please make sure you are running the newest version and report it.`;
17
17
  super(`${message}${message.endsWith(disclaimer) ? "" : disclaimer}`, options);
18
18
  this.extraData = extraData;
19
19
  }
@@ -0,0 +1,6 @@
1
+ export declare const standardProviders: readonly ["google", "github", "facebook", "microsoft", "spotify"];
2
+ export declare const sharedProviders: readonly ["google", "github", "facebook", "microsoft", "spotify"];
3
+ export declare const allProviders: readonly ["google", "github", "facebook", "microsoft", "spotify"];
4
+ export type ProviderType = typeof allProviders[number];
5
+ export type StandardProviderType = typeof standardProviders[number];
6
+ export type SharedProviderType = typeof sharedProviders[number];
@@ -0,0 +1,3 @@
1
+ export const standardProviders = ["google", "github", "facebook", "microsoft", "spotify"];
2
+ export const sharedProviders = ["google", "github", "facebook", "microsoft", "spotify"];
3
+ export const allProviders = ["google", "github", "facebook", "microsoft", "spotify"];
@@ -1 +1,3 @@
1
1
  export declare function isLocalhost(urlOrString: string | URL): boolean;
2
+ export declare function isRelative(url: string): boolean;
3
+ export declare function getRelativePart(url: URL): string;
@@ -1,3 +1,4 @@
1
+ import { generateSecureRandomString } from "./crypto";
1
2
  export function isLocalhost(urlOrString) {
2
3
  const url = new URL(urlOrString);
3
4
  if (url.hostname === "localhost" || url.hostname.endsWith(".localhost"))
@@ -6,3 +7,15 @@ export function isLocalhost(urlOrString) {
6
7
  return true;
7
8
  return false;
8
9
  }
10
+ export function isRelative(url) {
11
+ const randomDomain = `${generateSecureRandomString()}.stack-auth.example.com`;
12
+ const u = new URL(url, `https://${randomDomain}`);
13
+ if (u.host !== randomDomain)
14
+ return false;
15
+ if (u.protocol !== "https:")
16
+ return false;
17
+ return true;
18
+ }
19
+ export function getRelativePart(url) {
20
+ return url.pathname + url.search + url.hash;
21
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackframe/stack-shared",
3
- "version": "2.5.7",
3
+ "version": "2.5.9",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "files": [
@@ -36,7 +36,7 @@
36
36
  "jose": "^5.2.2",
37
37
  "oauth4webapi": "^2.10.3",
38
38
  "uuid": "^9.0.1",
39
- "@stackframe/stack-sc": "2.5.7"
39
+ "@stackframe/stack-sc": "2.5.9"
40
40
  },
41
41
  "devDependencies": {
42
42
  "rimraf": "^5.0.5",