@stackframe/stack-shared 2.5.17 → 2.5.18

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,12 @@
1
1
  # @stackframe/stack-shared
2
2
 
3
+ ## 2.5.18
4
+
5
+ ### Patch Changes
6
+
7
+ - Multi-factor authentication
8
+ - @stackframe/stack-sc@2.5.18
9
+
3
10
  ## 2.5.17
4
11
 
5
12
  ### Patch Changes
@@ -65,6 +65,23 @@ export declare class StackClientInterface {
65
65
  }, session: InternalSession): Promise<KnownErrors["PasswordConfirmationMismatch"] | KnownErrors["PasswordRequirementsNotMet"] | undefined>;
66
66
  verifyPasswordResetCode(code: string): Promise<KnownErrors["VerificationCodeError"] | undefined>;
67
67
  verifyEmail(code: string): Promise<KnownErrors["VerificationCodeError"] | undefined>;
68
+ sendTeamInvitation(options: {
69
+ email: string;
70
+ teamId: string;
71
+ callbackUrl: string;
72
+ session: InternalSession | null;
73
+ }): Promise<Result<undefined, KnownErrors["TeamPermissionRequired"]>>;
74
+ acceptTeamInvitation<T extends 'use' | 'details' | 'check'>(options: {
75
+ code: string;
76
+ session: InternalSession;
77
+ type: T;
78
+ }): Promise<Result<T extends 'details' ? {
79
+ team_display_name: string;
80
+ } : undefined, KnownErrors["VerificationCodeError"]>>;
81
+ totpMfa(attemptCode: string, totp: string, session: InternalSession): Promise<{
82
+ accessToken: any;
83
+ refreshToken: any;
84
+ }>;
68
85
  signInWithCredential(email: string, password: string, session: InternalSession): Promise<KnownErrors["EmailPasswordMismatch"] | {
69
86
  accessToken: string;
70
87
  refreshToken: string;
@@ -219,7 +219,6 @@ export class StackClientInterface {
219
219
  catch (e) {
220
220
  if (e instanceof TypeError) {
221
221
  // Network error, retry
222
- console.warn(`Stack detected a network error while fetching ${url}, retrying.`, e, { url });
223
222
  return Result.error(e);
224
223
  }
225
224
  throw e;
@@ -386,6 +385,64 @@ export class StackClientInterface {
386
385
  return res.error;
387
386
  }
388
387
  }
388
+ async sendTeamInvitation(options) {
389
+ const res = await this.sendClientRequestAndCatchKnownError("/team-invitations/send-code", {
390
+ method: "POST",
391
+ headers: {
392
+ "Content-Type": "application/json"
393
+ },
394
+ body: JSON.stringify({
395
+ email: options.email,
396
+ team_id: options.teamId,
397
+ callback_url: options.callbackUrl,
398
+ }),
399
+ }, options.session, [KnownErrors.TeamPermissionRequired]);
400
+ if (res.status === "error") {
401
+ return Result.error(res.error);
402
+ }
403
+ else {
404
+ return Result.ok(undefined);
405
+ }
406
+ }
407
+ async acceptTeamInvitation(options) {
408
+ const res = await this.sendClientRequestAndCatchKnownError(options.type === 'check' ?
409
+ "/team-invitations/accept/check-code" :
410
+ options.type === 'details' ?
411
+ "/team-invitations/accept/details" :
412
+ "/team-invitations/accept", {
413
+ method: "POST",
414
+ headers: {
415
+ "Content-Type": "application/json"
416
+ },
417
+ body: JSON.stringify({
418
+ code: options.code,
419
+ }),
420
+ }, options.session, [KnownErrors.VerificationCodeError]);
421
+ if (res.status === "error") {
422
+ return Result.error(res.error);
423
+ }
424
+ else {
425
+ return Result.ok(await res.data.json());
426
+ }
427
+ }
428
+ async totpMfa(attemptCode, totp, session) {
429
+ const res = await this.sendClientRequest("/auth/mfa/sign-in", {
430
+ method: "POST",
431
+ headers: {
432
+ "Content-Type": "application/json"
433
+ },
434
+ body: JSON.stringify({
435
+ code: attemptCode,
436
+ type: "totp",
437
+ totp: totp,
438
+ }),
439
+ }, session);
440
+ const result = await res.json();
441
+ return {
442
+ accessToken: result.access_token,
443
+ refreshToken: result.refresh_token,
444
+ };
445
+ }
389
446
  async signInWithCredential(email, password, session) {
390
447
  const res = await this.sendClientRequestAndCatchKnownError("/auth/password/sign-in", {
391
448
  method: "POST",
@@ -444,7 +501,7 @@ export class StackClientInterface {
444
501
  return {
445
502
  accessToken: result.access_token,
446
503
  refreshToken: result.refresh_token,
447
- newUser: result.new_user,
504
+ newUser: result.is_new_user,
448
505
  };
449
506
  }
450
507
  async getOAuthUrl(options) {
@@ -509,8 +566,8 @@ export class StackClientInterface {
509
566
  throw new StackAssertionError("Outer OAuth error during authorization code response", { result });
510
567
  }
511
568
  return {
512
- newUser: result.newUser,
513
- afterCallbackRedirectUrl: result.afterCallbackRedirectUrl,
569
+ newUser: result.is_new_user,
570
+ afterCallbackRedirectUrl: result.after_callback_redirect_url,
514
571
  accessToken: result.access_token,
515
572
  refreshToken: result.refresh_token ?? throwErr("Refresh token not found in outer OAuth response"),
516
573
  };
@@ -16,6 +16,7 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
16
16
  signed_up_at_millis: number;
17
17
  has_password: NonNullable<boolean | undefined>;
18
18
  auth_with_email: NonNullable<boolean | undefined>;
19
+ requires_totp_mfa: NonNullable<boolean | undefined>;
19
20
  auth_methods: ({
20
21
  type: "password";
21
22
  identifier: string;
@@ -60,6 +61,7 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
60
61
  signed_up_at_millis: undefined;
61
62
  has_password: undefined;
62
63
  auth_with_email: undefined;
64
+ requires_totp_mfa: undefined;
63
65
  oauth_providers: undefined;
64
66
  auth_methods: undefined;
65
67
  connected_accounts: undefined;
@@ -82,6 +84,7 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
82
84
  signed_up_at_millis: number;
83
85
  has_password: NonNullable<boolean | undefined>;
84
86
  auth_with_email: NonNullable<boolean | undefined>;
87
+ requires_totp_mfa: NonNullable<boolean | undefined>;
85
88
  oauth_providers: {
86
89
  email?: string | null | undefined;
87
90
  id: string;
@@ -128,6 +131,7 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
128
131
  signed_up_at_millis: undefined;
129
132
  has_password: undefined;
130
133
  auth_with_email: undefined;
134
+ requires_totp_mfa: undefined;
131
135
  oauth_providers: undefined;
132
136
  auth_methods: undefined;
133
137
  connected_accounts: undefined;
@@ -137,6 +141,7 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
137
141
  clientUpdateSchema: import("yup").ObjectSchema<{
138
142
  display_name: string | null | undefined;
139
143
  client_metadata: {} | null | undefined;
144
+ totp_secret_base64: string | null | undefined;
140
145
  selected_team_id: string | null | undefined;
141
146
  }, import("yup").AnyObject, {
142
147
  display_name: undefined;
@@ -147,6 +152,7 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
147
152
  primary_email_verified: undefined;
148
153
  primary_email_auth_enabled: undefined;
149
154
  password: undefined;
155
+ totp_secret_base64: undefined;
150
156
  selected_team_id: undefined;
151
157
  }, "">;
152
158
  serverUpdateSchema: import("yup").ObjectSchema<{
@@ -158,6 +164,7 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
158
164
  primary_email_verified: boolean | undefined;
159
165
  primary_email_auth_enabled: boolean | undefined;
160
166
  password: string | null | undefined;
167
+ totp_secret_base64: string | null | undefined;
161
168
  selected_team_id: string | null | undefined;
162
169
  }, import("yup").AnyObject, {
163
170
  display_name: undefined;
@@ -168,6 +175,7 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
168
175
  primary_email_verified: undefined;
169
176
  primary_email_auth_enabled: undefined;
170
177
  password: undefined;
178
+ totp_secret_base64: undefined;
171
179
  selected_team_id: undefined;
172
180
  }, "">;
173
181
  serverDeleteSchema: import("yup").MixedSchema<{} | undefined, import("yup").AnyObject, undefined, "">;
@@ -6,6 +6,7 @@ const clientUpdateSchema = usersCrudServerUpdateSchema.pick([
6
6
  "display_name",
7
7
  "client_metadata",
8
8
  "selected_team_id",
9
+ "totp_secret_base64",
9
10
  ]).required();
10
11
  const serverUpdateSchema = usersCrudServerUpdateSchema;
11
12
  const clientReadSchema = usersCrudServerReadSchema.pick([
@@ -22,6 +23,7 @@ const clientReadSchema = usersCrudServerReadSchema.pick([
22
23
  "selected_team_id",
23
24
  "auth_methods",
24
25
  "connected_accounts",
26
+ "requires_totp_mfa",
25
27
  ]).concat(yupObject({
26
28
  selected_team: teamsCrudClientReadSchema.nullable().defined(),
27
29
  })).nullable().defined(); // TODO: next-release: make required
@@ -1,8 +1,8 @@
1
1
  import { CrudTypeOf } from "../../crud";
2
2
  export type EmailTemplateType = typeof emailTemplateTypes[number];
3
- export declare const emailTemplateTypes: readonly ["email_verification", "password_reset", "magic_link"];
3
+ export declare const emailTemplateTypes: readonly ["email_verification", "password_reset", "magic_link", "team_invitation"];
4
4
  export declare const emailTemplateAdminReadSchema: import("yup").ObjectSchema<{
5
- type: NonNullable<"email_verification" | "password_reset" | "magic_link" | undefined>;
5
+ type: NonNullable<"email_verification" | "password_reset" | "magic_link" | "team_invitation" | undefined>;
6
6
  subject: string;
7
7
  content: {};
8
8
  is_default: NonNullable<boolean | undefined>;
@@ -21,7 +21,7 @@ export declare const emailTemplateCrudAdminUpdateSchema: import("yup").ObjectSch
21
21
  }, "">;
22
22
  export declare const emailTemplateCrudAdminDeleteSchema: import("yup").MixedSchema<{} | undefined, import("yup").AnyObject, undefined, "">;
23
23
  export declare const emailTemplateCrudAdminCreateSchema: import("yup").ObjectSchema<{
24
- type: NonNullable<"email_verification" | "password_reset" | "magic_link" | undefined>;
24
+ type: NonNullable<"email_verification" | "password_reset" | "magic_link" | "team_invitation" | undefined>;
25
25
  content: {};
26
26
  subject: string;
27
27
  }, import("yup").AnyObject, {
@@ -31,7 +31,7 @@ export declare const emailTemplateCrudAdminCreateSchema: import("yup").ObjectSch
31
31
  }, "">;
32
32
  export declare const emailTemplateCrud: import("../../crud").CrudSchemaFromOptions<{
33
33
  adminReadSchema: import("yup").ObjectSchema<{
34
- type: NonNullable<"email_verification" | "password_reset" | "magic_link" | undefined>;
34
+ type: NonNullable<"email_verification" | "password_reset" | "magic_link" | "team_invitation" | undefined>;
35
35
  subject: string;
36
36
  content: {};
37
37
  is_default: NonNullable<boolean | undefined>;
@@ -49,7 +49,7 @@ export declare const emailTemplateCrud: import("../../crud").CrudSchemaFromOptio
49
49
  subject: undefined;
50
50
  }, "">;
51
51
  adminCreateSchema: import("yup").ObjectSchema<{
52
- type: NonNullable<"email_verification" | "password_reset" | "magic_link" | undefined>;
52
+ type: NonNullable<"email_verification" | "password_reset" | "magic_link" | "team_invitation" | undefined>;
53
53
  content: {};
54
54
  subject: string;
55
55
  }, import("yup").AnyObject, {
@@ -1,6 +1,6 @@
1
1
  import { createCrud } from "../../crud";
2
2
  import { jsonSchema, yupBoolean, yupMixed, yupObject, yupString } from "../../schema-fields";
3
- export const emailTemplateTypes = ['email_verification', 'password_reset', 'magic_link'];
3
+ export const emailTemplateTypes = ['email_verification', 'password_reset', 'magic_link', 'team_invitation'];
4
4
  export const emailTemplateAdminReadSchema = yupObject({
5
5
  type: yupString().oneOf(emailTemplateTypes).required(),
6
6
  subject: yupString().required(),
@@ -9,6 +9,7 @@ export declare const projectsCrudServerReadSchema: import("yup").ObjectSchema<{
9
9
  config: {
10
10
  id: string;
11
11
  allow_localhost: NonNullable<boolean | undefined>;
12
+ sign_up_enabled: NonNullable<boolean | undefined>;
12
13
  credential_enabled: NonNullable<boolean | undefined>;
13
14
  magic_link_enabled: NonNullable<boolean | undefined>;
14
15
  oauth_providers: {
@@ -53,6 +54,7 @@ export declare const projectsCrudServerReadSchema: import("yup").ObjectSchema<{
53
54
  config: {
54
55
  id: undefined;
55
56
  allow_localhost: undefined;
57
+ sign_up_enabled: undefined;
56
58
  credential_enabled: undefined;
57
59
  magic_link_enabled: undefined;
58
60
  oauth_providers: undefined;
@@ -76,6 +78,7 @@ export declare const projectsCrudClientReadSchema: import("yup").ObjectSchema<{
76
78
  id: string;
77
79
  display_name: string;
78
80
  config: {
81
+ sign_up_enabled: NonNullable<boolean | undefined>;
79
82
  credential_enabled: NonNullable<boolean | undefined>;
80
83
  magic_link_enabled: NonNullable<boolean | undefined>;
81
84
  enabled_oauth_providers: {
@@ -86,6 +89,7 @@ export declare const projectsCrudClientReadSchema: import("yup").ObjectSchema<{
86
89
  id: undefined;
87
90
  display_name: undefined;
88
91
  config: {
92
+ sign_up_enabled: undefined;
89
93
  credential_enabled: undefined;
90
94
  magic_link_enabled: undefined;
91
95
  enabled_oauth_providers: undefined;
@@ -97,6 +101,7 @@ export declare const projectsCrudServerUpdateSchema: import("yup").ObjectSchema<
97
101
  is_production_mode: boolean | undefined;
98
102
  config: {
99
103
  allow_localhost?: boolean | undefined;
104
+ sign_up_enabled?: boolean | undefined;
100
105
  credential_enabled?: boolean | undefined;
101
106
  magic_link_enabled?: boolean | undefined;
102
107
  oauth_providers?: {
@@ -140,6 +145,7 @@ export declare const projectsCrudServerCreateSchema: import("yup").ObjectSchema<
140
145
  is_production_mode: boolean | undefined;
141
146
  config: {
142
147
  allow_localhost?: boolean | undefined;
148
+ sign_up_enabled?: boolean | undefined;
143
149
  credential_enabled?: boolean | undefined;
144
150
  magic_link_enabled?: boolean | undefined;
145
151
  oauth_providers?: {
@@ -184,6 +190,7 @@ export declare const projectsCrud: import("../../crud").CrudSchemaFromOptions<{
184
190
  id: string;
185
191
  display_name: string;
186
192
  config: {
193
+ sign_up_enabled: NonNullable<boolean | undefined>;
187
194
  credential_enabled: NonNullable<boolean | undefined>;
188
195
  magic_link_enabled: NonNullable<boolean | undefined>;
189
196
  enabled_oauth_providers: {
@@ -194,6 +201,7 @@ export declare const projectsCrud: import("../../crud").CrudSchemaFromOptions<{
194
201
  id: undefined;
195
202
  display_name: undefined;
196
203
  config: {
204
+ sign_up_enabled: undefined;
197
205
  credential_enabled: undefined;
198
206
  magic_link_enabled: undefined;
199
207
  enabled_oauth_providers: undefined;
@@ -209,6 +217,7 @@ export declare const projectsCrud: import("../../crud").CrudSchemaFromOptions<{
209
217
  config: {
210
218
  id: string;
211
219
  allow_localhost: NonNullable<boolean | undefined>;
220
+ sign_up_enabled: NonNullable<boolean | undefined>;
212
221
  credential_enabled: NonNullable<boolean | undefined>;
213
222
  magic_link_enabled: NonNullable<boolean | undefined>;
214
223
  oauth_providers: {
@@ -253,6 +262,7 @@ export declare const projectsCrud: import("../../crud").CrudSchemaFromOptions<{
253
262
  config: {
254
263
  id: undefined;
255
264
  allow_localhost: undefined;
265
+ sign_up_enabled: undefined;
256
266
  credential_enabled: undefined;
257
267
  magic_link_enabled: undefined;
258
268
  oauth_providers: undefined;
@@ -278,6 +288,7 @@ export declare const projectsCrud: import("../../crud").CrudSchemaFromOptions<{
278
288
  is_production_mode: boolean | undefined;
279
289
  config: {
280
290
  allow_localhost?: boolean | undefined;
291
+ sign_up_enabled?: boolean | undefined;
281
292
  credential_enabled?: boolean | undefined;
282
293
  magic_link_enabled?: boolean | undefined;
283
294
  oauth_providers?: {
@@ -345,6 +356,7 @@ export declare const internalProjectsCrud: import("../../crud").CrudSchemaFromOp
345
356
  config: {
346
357
  id: string;
347
358
  allow_localhost: NonNullable<boolean | undefined>;
359
+ sign_up_enabled: NonNullable<boolean | undefined>;
348
360
  credential_enabled: NonNullable<boolean | undefined>;
349
361
  magic_link_enabled: NonNullable<boolean | undefined>;
350
362
  oauth_providers: {
@@ -389,6 +401,7 @@ export declare const internalProjectsCrud: import("../../crud").CrudSchemaFromOp
389
401
  config: {
390
402
  id: undefined;
391
403
  allow_localhost: undefined;
404
+ sign_up_enabled: undefined;
392
405
  credential_enabled: undefined;
393
406
  magic_link_enabled: undefined;
394
407
  oauth_providers: undefined;
@@ -414,6 +427,7 @@ export declare const internalProjectsCrud: import("../../crud").CrudSchemaFromOp
414
427
  is_production_mode: boolean | undefined;
415
428
  config: {
416
429
  allow_localhost?: boolean | undefined;
430
+ sign_up_enabled?: boolean | undefined;
417
431
  credential_enabled?: boolean | undefined;
418
432
  magic_link_enabled?: boolean | undefined;
419
433
  oauth_providers?: {
@@ -39,6 +39,7 @@ export const projectsCrudServerReadSchema = yupObject({
39
39
  config: yupObject({
40
40
  id: schemaFields.projectConfigIdSchema.required(),
41
41
  allow_localhost: schemaFields.projectAllowLocalhostSchema.required(),
42
+ sign_up_enabled: schemaFields.projectSignUpEnabledSchema.required(),
42
43
  credential_enabled: schemaFields.projectCredentialEnabledSchema.required(),
43
44
  magic_link_enabled: schemaFields.projectMagicLinkEnabledSchema.required(),
44
45
  oauth_providers: yupArray(oauthProviderSchema.required()).required(),
@@ -54,6 +55,7 @@ export const projectsCrudClientReadSchema = yupObject({
54
55
  id: schemaFields.projectIdSchema.required(),
55
56
  display_name: schemaFields.projectDisplayNameSchema.required(),
56
57
  config: yupObject({
58
+ sign_up_enabled: schemaFields.projectSignUpEnabledSchema.required(),
57
59
  credential_enabled: schemaFields.projectCredentialEnabledSchema.required(),
58
60
  magic_link_enabled: schemaFields.projectMagicLinkEnabledSchema.required(),
59
61
  enabled_oauth_providers: yupArray(enabledOAuthProviderSchema.required()).required(),
@@ -64,6 +66,7 @@ export const projectsCrudServerUpdateSchema = yupObject({
64
66
  description: schemaFields.projectDescriptionSchema.optional(),
65
67
  is_production_mode: schemaFields.projectIsProductionModeSchema.optional(),
66
68
  config: yupObject({
69
+ sign_up_enabled: schemaFields.projectSignUpEnabledSchema.optional(),
67
70
  credential_enabled: schemaFields.projectCredentialEnabledSchema.optional(),
68
71
  magic_link_enabled: schemaFields.projectMagicLinkEnabledSchema.optional(),
69
72
  allow_localhost: schemaFields.projectAllowLocalhostSchema.optional(),
@@ -0,0 +1,25 @@
1
+ import { CrudTypeOf } from "../../crud";
2
+ export declare const teamInvitationDetailsClientReadSchema: import("yup").ObjectSchema<{
3
+ team_id: string;
4
+ team_display_name: string;
5
+ }, import("yup").AnyObject, {
6
+ team_id: undefined;
7
+ team_display_name: undefined;
8
+ }, "">;
9
+ export declare const teamInvitationDetailsCrud: import("../../crud").CrudSchemaFromOptions<{
10
+ clientReadSchema: import("yup").ObjectSchema<{
11
+ team_id: string;
12
+ team_display_name: string;
13
+ }, import("yup").AnyObject, {
14
+ team_id: undefined;
15
+ team_display_name: undefined;
16
+ }, "">;
17
+ docs: {
18
+ clientRead: {
19
+ summary: string;
20
+ description: string;
21
+ tags: string[];
22
+ };
23
+ };
24
+ }>;
25
+ export type TeamInvitationDetailsCrud = CrudTypeOf<typeof teamInvitationDetailsCrud>;
@@ -0,0 +1,17 @@
1
+ import { createCrud } from "../../crud";
2
+ import * as schemaFields from "../../schema-fields";
3
+ import { yupObject } from "../../schema-fields";
4
+ export const teamInvitationDetailsClientReadSchema = yupObject({
5
+ team_id: schemaFields.teamIdSchema.required(),
6
+ team_display_name: schemaFields.teamDisplayNameSchema.required(),
7
+ }).required();
8
+ export const teamInvitationDetailsCrud = createCrud({
9
+ clientReadSchema: teamInvitationDetailsClientReadSchema,
10
+ docs: {
11
+ clientRead: {
12
+ summary: "Get the team details with invitation code",
13
+ description: "",
14
+ tags: ["Teams"],
15
+ },
16
+ },
17
+ });
@@ -8,6 +8,7 @@ export declare const usersCrudServerUpdateSchema: import("yup").ObjectSchema<{
8
8
  primary_email_verified: boolean | undefined;
9
9
  primary_email_auth_enabled: boolean | undefined;
10
10
  password: string | null | undefined;
11
+ totp_secret_base64: string | null | undefined;
11
12
  selected_team_id: string | null | undefined;
12
13
  }, import("yup").AnyObject, {
13
14
  display_name: undefined;
@@ -18,6 +19,7 @@ export declare const usersCrudServerUpdateSchema: import("yup").ObjectSchema<{
18
19
  primary_email_verified: undefined;
19
20
  primary_email_auth_enabled: undefined;
20
21
  password: undefined;
22
+ totp_secret_base64: undefined;
21
23
  selected_team_id: undefined;
22
24
  }, "">;
23
25
  export declare const usersCrudServerReadSchema: import("yup").ObjectSchema<{
@@ -36,6 +38,7 @@ export declare const usersCrudServerReadSchema: import("yup").ObjectSchema<{
36
38
  signed_up_at_millis: number;
37
39
  has_password: NonNullable<boolean | undefined>;
38
40
  auth_with_email: NonNullable<boolean | undefined>;
41
+ requires_totp_mfa: NonNullable<boolean | undefined>;
39
42
  oauth_providers: {
40
43
  email?: string | null | undefined;
41
44
  id: string;
@@ -82,6 +85,7 @@ export declare const usersCrudServerReadSchema: import("yup").ObjectSchema<{
82
85
  signed_up_at_millis: undefined;
83
86
  has_password: undefined;
84
87
  auth_with_email: undefined;
88
+ requires_totp_mfa: undefined;
85
89
  oauth_providers: undefined;
86
90
  auth_methods: undefined;
87
91
  connected_accounts: undefined;
@@ -97,6 +101,7 @@ export declare const usersCrudServerCreateSchema: import("yup").ObjectSchema<{
97
101
  primary_email_verified: boolean | undefined;
98
102
  primary_email_auth_enabled: boolean | undefined;
99
103
  password: string | null | undefined;
104
+ totp_secret_base64: string | null | undefined;
100
105
  selected_team_id: string | null | undefined;
101
106
  } & {
102
107
  oauth_providers: {
@@ -113,6 +118,7 @@ export declare const usersCrudServerCreateSchema: import("yup").ObjectSchema<{
113
118
  primary_email_verified: undefined;
114
119
  primary_email_auth_enabled: undefined;
115
120
  password: undefined;
121
+ totp_secret_base64: undefined;
116
122
  selected_team_id: undefined;
117
123
  oauth_providers: undefined;
118
124
  }, "">;
@@ -134,6 +140,7 @@ export declare const usersCrud: import("../../crud").CrudSchemaFromOptions<{
134
140
  signed_up_at_millis: number;
135
141
  has_password: NonNullable<boolean | undefined>;
136
142
  auth_with_email: NonNullable<boolean | undefined>;
143
+ requires_totp_mfa: NonNullable<boolean | undefined>;
137
144
  oauth_providers: {
138
145
  email?: string | null | undefined;
139
146
  id: string;
@@ -180,6 +187,7 @@ export declare const usersCrud: import("../../crud").CrudSchemaFromOptions<{
180
187
  signed_up_at_millis: undefined;
181
188
  has_password: undefined;
182
189
  auth_with_email: undefined;
190
+ requires_totp_mfa: undefined;
183
191
  oauth_providers: undefined;
184
192
  auth_methods: undefined;
185
193
  connected_accounts: undefined;
@@ -195,6 +203,7 @@ export declare const usersCrud: import("../../crud").CrudSchemaFromOptions<{
195
203
  primary_email_verified: boolean | undefined;
196
204
  primary_email_auth_enabled: boolean | undefined;
197
205
  password: string | null | undefined;
206
+ totp_secret_base64: string | null | undefined;
198
207
  selected_team_id: string | null | undefined;
199
208
  }, import("yup").AnyObject, {
200
209
  display_name: undefined;
@@ -205,6 +214,7 @@ export declare const usersCrud: import("../../crud").CrudSchemaFromOptions<{
205
214
  primary_email_verified: undefined;
206
215
  primary_email_auth_enabled: undefined;
207
216
  password: undefined;
217
+ totp_secret_base64: undefined;
208
218
  selected_team_id: undefined;
209
219
  }, "">;
210
220
  serverCreateSchema: import("yup").ObjectSchema<{
@@ -216,6 +226,7 @@ export declare const usersCrud: import("../../crud").CrudSchemaFromOptions<{
216
226
  primary_email_verified: boolean | undefined;
217
227
  primary_email_auth_enabled: boolean | undefined;
218
228
  password: string | null | undefined;
229
+ totp_secret_base64: string | null | undefined;
219
230
  selected_team_id: string | null | undefined;
220
231
  } & {
221
232
  oauth_providers: {
@@ -232,6 +243,7 @@ export declare const usersCrud: import("../../crud").CrudSchemaFromOptions<{
232
243
  primary_email_verified: undefined;
233
244
  primary_email_auth_enabled: undefined;
234
245
  password: undefined;
246
+ totp_secret_base64: undefined;
235
247
  selected_team_id: undefined;
236
248
  oauth_providers: undefined;
237
249
  }, "">;
@@ -283,6 +295,7 @@ export declare const userCreatedWebhookEvent: {
283
295
  signed_up_at_millis: number;
284
296
  has_password: NonNullable<boolean | undefined>;
285
297
  auth_with_email: NonNullable<boolean | undefined>;
298
+ requires_totp_mfa: NonNullable<boolean | undefined>;
286
299
  oauth_providers: {
287
300
  email?: string | null | undefined;
288
301
  id: string;
@@ -329,6 +342,7 @@ export declare const userCreatedWebhookEvent: {
329
342
  signed_up_at_millis: undefined;
330
343
  has_password: undefined;
331
344
  auth_with_email: undefined;
345
+ requires_totp_mfa: undefined;
332
346
  oauth_providers: undefined;
333
347
  auth_methods: undefined;
334
348
  connected_accounts: undefined;
@@ -359,6 +373,7 @@ export declare const userUpdatedWebhookEvent: {
359
373
  signed_up_at_millis: number;
360
374
  has_password: NonNullable<boolean | undefined>;
361
375
  auth_with_email: NonNullable<boolean | undefined>;
376
+ requires_totp_mfa: NonNullable<boolean | undefined>;
362
377
  oauth_providers: {
363
378
  email?: string | null | undefined;
364
379
  id: string;
@@ -405,6 +420,7 @@ export declare const userUpdatedWebhookEvent: {
405
420
  signed_up_at_millis: undefined;
406
421
  has_password: undefined;
407
422
  auth_with_email: undefined;
423
+ requires_totp_mfa: undefined;
408
424
  oauth_providers: undefined;
409
425
  auth_methods: undefined;
410
426
  connected_accounts: undefined;
@@ -10,6 +10,7 @@ export const usersCrudServerUpdateSchema = fieldSchema.yupObject({
10
10
  primary_email_verified: fieldSchema.primaryEmailVerifiedSchema.optional(),
11
11
  primary_email_auth_enabled: fieldSchema.yupBoolean().optional().meta({ openapiField: { description: "Whether the primary email can be used to sign into this user's account", exampleValue: true } }),
12
12
  password: fieldSchema.yupString().nullable().meta({ openapiField: { description: 'A new password for the user, overwriting the old one (if it exists).', exampleValue: 'password' } }),
13
+ totp_secret_base64: fieldSchema.base64Schema.nullable().meta({ openapiField: { description: 'A TOTP secret for the user, overwriting the old one (if it exists). Set to null to disable 2FA.', exampleValue: 'dG90cC1zZWNyZXQ=' } }),
13
14
  selected_team_id: fieldSchema.selectedTeamIdSchema.nullable().optional(),
14
15
  }).required();
15
16
  export const usersCrudServerReadSchema = fieldSchema.yupObject({
@@ -26,6 +27,10 @@ export const usersCrudServerReadSchema = fieldSchema.yupObject({
26
27
  * @deprecated
27
28
  */
28
29
  auth_with_email: fieldSchema.yupBoolean().required().meta({ openapiField: { hidden: true, description: 'Whether the user can authenticate with their primary e-mail. If set to true, the user can log-in with credentials and/or magic link, if enabled in the project settings.', exampleValue: true } }),
30
+ /**
31
+ * @deprecated
32
+ */
33
+ requires_totp_mfa: fieldSchema.yupBoolean().required().meta({ openapiField: { hidden: true, description: 'Whether the user is required to use TOTP MFA to sign in', exampleValue: false } }),
29
34
  /**
30
35
  * @deprecated
31
36
  */
@@ -46,11 +51,11 @@ export const usersCrudServerReadSchema = fieldSchema.yupObject({
46
51
  }).required(), fieldSchema.yupObject({
47
52
  type: fieldSchema.yupString().oneOf(['oauth']).required(),
48
53
  provider: fieldSchema.userOAuthProviderSchema.required(),
49
- }).required())).required().meta({ openapiField: { description: 'A list of authentication methods available for this user to sign in with', exampleValue: [{ "contact_channel": { "email": "john.doe@gmail.com", "type": "email", }, "type": "otp", }] } }),
54
+ }).required())).required().meta({ openapiField: { hidden: true, description: 'A list of authentication methods available for this user to sign in with', exampleValue: [{ "contact_channel": { "email": "john.doe@gmail.com", "type": "email", }, "type": "otp", }] } }),
50
55
  connected_accounts: fieldSchema.yupArray(fieldSchema.yupUnion(fieldSchema.yupObject({
51
56
  type: fieldSchema.yupString().oneOf(['oauth']).required(),
52
57
  provider: fieldSchema.userOAuthProviderSchema.required(),
53
- }).required())).required().meta({ openapiField: { description: 'A list of connected accounts to this user', exampleValue: [{ "provider": { "provider_user_id": "12345", "type": "google", }, "type": "oauth", }] } }),
58
+ }).required())).required().meta({ openapiField: { hidden: true, description: 'A list of connected accounts to this user', exampleValue: [{ "provider": { "provider_user_id": "12345", "type": "google", }, "type": "oauth", }] } }),
54
59
  client_metadata: fieldSchema.userClientMetadataSchema,
55
60
  server_metadata: fieldSchema.userServerMetadataSchema,
56
61
  }).required();
@@ -1,8 +1,8 @@
1
1
  import { CrudTypeOf } from "../../crud";
2
2
  export type EmailTemplateType = typeof emailTemplateTypes[number];
3
- export declare const emailTemplateTypes: readonly ["EMAIL_VERIFICATION", "PASSWORD_RESET", "MAGIC_LINK"];
3
+ export declare const emailTemplateTypes: readonly ["EMAIL_VERIFICATION", "PASSWORD_RESET", "MAGIC_LINK", "TEAM_INVITATION"];
4
4
  export declare const emailTemplateServerReadSchema: import("yup").ObjectSchema<{
5
- type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | undefined>;
5
+ type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | "TEAM_INVITATION" | undefined>;
6
6
  subject: string;
7
7
  content: {};
8
8
  }, import("yup").AnyObject, {
@@ -19,7 +19,7 @@ export declare const emailTemplateCrudServerUpdateSchema: import("yup").ObjectSc
19
19
  }, "">;
20
20
  export declare const emailTemplateCrudServerDeleteSchema: import("yup").MixedSchema<{} | undefined, import("yup").AnyObject, undefined, "">;
21
21
  export declare const emailTemplateCrudServerCreateSchema: import("yup").ObjectSchema<{
22
- type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | undefined>;
22
+ type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | "TEAM_INVITATION" | undefined>;
23
23
  content: {};
24
24
  subject: string;
25
25
  }, import("yup").AnyObject, {
@@ -29,7 +29,7 @@ export declare const emailTemplateCrudServerCreateSchema: import("yup").ObjectSc
29
29
  }, "">;
30
30
  export declare const emailTemplateCrud: import("../../crud").CrudSchemaFromOptions<{
31
31
  serverReadSchema: import("yup").ObjectSchema<{
32
- type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | undefined>;
32
+ type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | "TEAM_INVITATION" | undefined>;
33
33
  subject: string;
34
34
  content: {};
35
35
  }, import("yup").AnyObject, {
@@ -45,7 +45,7 @@ export declare const emailTemplateCrud: import("../../crud").CrudSchemaFromOptio
45
45
  subject: undefined;
46
46
  }, "">;
47
47
  serverCreateSchema: import("yup").ObjectSchema<{
48
- type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | undefined>;
48
+ type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | "TEAM_INVITATION" | undefined>;
49
49
  content: {};
50
50
  subject: string;
51
51
  }, import("yup").AnyObject, {
@@ -1,6 +1,6 @@
1
1
  import { createCrud } from "../../crud";
2
2
  import { jsonSchema, yupMixed, yupObject, yupString } from "../../schema-fields";
3
- export const emailTemplateTypes = ['EMAIL_VERIFICATION', 'PASSWORD_RESET', 'MAGIC_LINK'];
3
+ export const emailTemplateTypes = ['EMAIL_VERIFICATION', 'PASSWORD_RESET', 'MAGIC_LINK', 'TEAM_INVITATION'];
4
4
  export const emailTemplateServerReadSchema = yupObject({
5
5
  type: yupString().oneOf(emailTemplateTypes).required(),
6
6
  subject: yupString().required(),
@@ -28,13 +28,14 @@ export declare class StackServerInterface extends StackClientInterface {
28
28
  refreshToken: RefreshToken | null;
29
29
  } | null;
30
30
  }, InstanceType<E>>>;
31
+ createServerUser(data: UsersCrud['Server']['Create']): Promise<UsersCrud['Server']['Read']>;
31
32
  getServerUserByToken(session: InternalSession): Promise<CurrentUserCrud['Server']['Read'] | null>;
32
33
  getServerUserById(userId: string): Promise<Result<UsersCrud['Server']['Read']>>;
33
34
  listServerTeamPermissions(options: {
34
35
  userId?: string;
35
36
  teamId?: string;
36
37
  recursive: boolean;
37
- }, session: InternalSession): Promise<TeamPermissionsCrud['Server']['Read'][]>;
38
+ }, session: InternalSession | null): Promise<TeamPermissionsCrud['Server']['Read'][]>;
38
39
  listServerUsers(): Promise<UsersCrud['Server']['Read'][]>;
39
40
  listServerTeams(options?: {
40
41
  userId?: string;
@@ -57,11 +58,6 @@ export declare class StackServerInterface extends StackClientInterface {
57
58
  accessToken: string;
58
59
  refreshToken: string;
59
60
  }>;
60
- listServerTeamMemberPermissions(options: {
61
- teamId: string;
62
- userId: string;
63
- recursive: boolean;
64
- }): Promise<TeamPermissionsCrud['Server']['Read'][]>;
65
61
  grantServerTeamUserPermission(teamId: string, userId: string, permissionId: string): Promise<void>;
66
62
  revokeServerTeamUserPermission(teamId: string, userId: string, permissionId: string): Promise<void>;
67
63
  deleteServerServerUser(userId: string): Promise<void>;
@@ -30,6 +30,16 @@ export class StackServerInterface extends StackClientInterface {
30
30
  throw e;
31
31
  }
32
32
  }
33
+ async createServerUser(data) {
34
+ const response = await this.sendServerRequest("/users", {
35
+ method: "POST",
36
+ headers: {
37
+ "content-type": "application/json",
38
+ },
39
+ body: JSON.stringify(data),
40
+ }, null);
41
+ return await response.json();
42
+ }
33
43
  async getServerUserByToken(session) {
34
44
  const responseOrError = await this.sendServerRequestAndCatchKnownError("/users/me", {}, session, [KnownErrors.CannotGetOwnUserWithoutUser]);
35
45
  if (responseOrError.status === "error") {
@@ -159,11 +169,6 @@ export class StackServerInterface extends StackClientInterface {
159
169
  refreshToken: result.refresh_token,
160
170
  };
161
171
  }
162
- async listServerTeamMemberPermissions(options) {
163
- const response = await this.sendServerRequest(`/team-permissions?team_id=${options.teamId}&user_id=${options.userId}&recursive=${options.recursive}`, {}, null);
164
- const result = await response.json();
165
- return result.items;
166
- }
167
172
  async grantServerTeamUserPermission(teamId, userId, permissionId) {
168
173
  await this.sendServerRequest(`/team-permissions/${teamId}/${userId}/${permissionId}`, {
169
174
  method: "POST",
@@ -26,6 +26,7 @@ export declare const webhookEvents: readonly [{
26
26
  signed_up_at_millis: number;
27
27
  has_password: NonNullable<boolean | undefined>;
28
28
  auth_with_email: NonNullable<boolean | undefined>;
29
+ requires_totp_mfa: NonNullable<boolean | undefined>;
29
30
  oauth_providers: {
30
31
  email?: string | null | undefined;
31
32
  id: string;
@@ -72,6 +73,7 @@ export declare const webhookEvents: readonly [{
72
73
  signed_up_at_millis: undefined;
73
74
  has_password: undefined;
74
75
  auth_with_email: undefined;
76
+ requires_totp_mfa: undefined;
75
77
  oauth_providers: undefined;
76
78
  auth_methods: undefined;
77
79
  connected_accounts: undefined;
@@ -101,6 +103,7 @@ export declare const webhookEvents: readonly [{
101
103
  signed_up_at_millis: number;
102
104
  has_password: NonNullable<boolean | undefined>;
103
105
  auth_with_email: NonNullable<boolean | undefined>;
106
+ requires_totp_mfa: NonNullable<boolean | undefined>;
104
107
  oauth_providers: {
105
108
  email?: string | null | undefined;
106
109
  id: string;
@@ -147,6 +150,7 @@ export declare const webhookEvents: readonly [{
147
150
  signed_up_at_millis: undefined;
148
151
  has_password: undefined;
149
152
  auth_with_email: undefined;
153
+ requires_totp_mfa: undefined;
150
154
  oauth_providers: undefined;
151
155
  auth_methods: undefined;
152
156
  connected_accounts: undefined;
@@ -245,6 +245,9 @@ export declare const KnownErrors: {
245
245
  ProjectNotFound: KnownErrorConstructor<KnownError & KnownErrorBrand<"PROJECT_NOT_FOUND">, [projectId: string]> & {
246
246
  errorCode: "PROJECT_NOT_FOUND";
247
247
  };
248
+ SignUpNotEnabled: KnownErrorConstructor<KnownError & KnownErrorBrand<"SIGN_UP_NOT_ENABLED">, []> & {
249
+ errorCode: "SIGN_UP_NOT_ENABLED";
250
+ };
248
251
  PasswordAuthenticationNotEnabled: KnownErrorConstructor<KnownError & KnownErrorBrand<"PASSWORD_AUTHENTICATION_NOT_ENABLED">, []> & {
249
252
  errorCode: "PASSWORD_AUTHENTICATION_NOT_ENABLED";
250
253
  };
@@ -345,6 +348,12 @@ export declare const KnownErrors: {
345
348
  OAuthProviderNotFoundOrNotEnabled: KnownErrorConstructor<KnownError & KnownErrorBrand<"OAUTH_PROVIDER_NOT_FOUND_OR_NOT_ENABLED">, []> & {
346
349
  errorCode: "OAUTH_PROVIDER_NOT_FOUND_OR_NOT_ENABLED";
347
350
  };
351
+ MultiFactorAuthenticationRequired: KnownErrorConstructor<KnownError & KnownErrorBrand<"MULTI_FACTOR_AUTHENTICATION_REQUIRED">, [attemptCode: string]> & {
352
+ errorCode: "MULTI_FACTOR_AUTHENTICATION_REQUIRED";
353
+ };
354
+ InvalidTotpCode: KnownErrorConstructor<KnownError & KnownErrorBrand<"INVALID_TOTP_CODE">, []> & {
355
+ errorCode: "INVALID_TOTP_CODE";
356
+ };
348
357
  UserAuthenticationRequired: KnownErrorConstructor<KnownError & KnownErrorBrand<"USER_AUTHENTICATION_REQUIRED">, []> & {
349
358
  errorCode: "USER_AUTHENTICATION_REQUIRED";
350
359
  };
@@ -363,5 +372,8 @@ export declare const KnownErrors: {
363
372
  InvalidAuthorizationCode: KnownErrorConstructor<KnownError & KnownErrorBrand<"INVALID_AUTHORIZATION_CODE">, []> & {
364
373
  errorCode: "INVALID_AUTHORIZATION_CODE";
365
374
  };
375
+ TeamPermissionNotFound: KnownErrorConstructor<KnownError & KnownErrorBrand<"TEAM_PERMISSION_NOT_FOUND">, [any, any, any]> & {
376
+ errorCode: "TEAM_PERMISSION_NOT_FOUND";
377
+ };
366
378
  };
367
379
  export {};
@@ -320,6 +320,10 @@ const ProjectNotFound = createKnownErrorConstructor(KnownError, "PROJECT_NOT_FOU
320
320
  },
321
321
  ];
322
322
  }, (json) => [json.project_id]);
323
+ const SignUpNotEnabled = createKnownErrorConstructor(KnownError, "SIGN_UP_NOT_ENABLED", () => [
324
+ 400,
325
+ "Creation of new accounts is not enabled for this project. Please ask the project owner to enable it.",
326
+ ], () => []);
323
327
  const PasswordAuthenticationNotEnabled = createKnownErrorConstructor(KnownError, "PASSWORD_AUTHENTICATION_NOT_ENABLED", () => [
324
328
  400,
325
329
  "Password authentication is not enabled for this project.",
@@ -471,6 +475,17 @@ const OAuthProviderNotFoundOrNotEnabled = createKnownErrorConstructor(KnownError
471
475
  400,
472
476
  "The OAuth provider is not found or not enabled.",
473
477
  ], () => []);
478
+ const MultiFactorAuthenticationRequired = createKnownErrorConstructor(KnownError, "MULTI_FACTOR_AUTHENTICATION_REQUIRED", (attemptCode) => [
479
+ 400,
480
+ `Multi-factor authentication is required for this user.`,
481
+ {
482
+ attempt_code: attemptCode,
483
+ },
484
+ ], (json) => [json.attempt_code]);
485
+ const InvalidTotpCode = createKnownErrorConstructor(KnownError, "INVALID_TOTP_CODE", () => [
486
+ 400,
487
+ "The TOTP code is invalid. Please try again.",
488
+ ], () => []);
474
489
  const UserAuthenticationRequired = createKnownErrorConstructor(KnownError, "USER_AUTHENTICATION_REQUIRED", () => [
475
490
  401,
476
491
  "User authentication required for this endpoint.",
@@ -488,6 +503,15 @@ const TeamPermissionRequired = createKnownErrorConstructor(KnownError, "TEAM_PER
488
503
  permission_id: permissionId,
489
504
  },
490
505
  ], (json) => [json.team_id, json.user_id, json.permission_id]);
506
+ const TeamPermissionNotFound = createKnownErrorConstructor(KnownError, "TEAM_PERMISSION_NOT_FOUND", (teamId, userId, permissionId) => [
507
+ 401,
508
+ `User ${userId} does not have permission ${permissionId} in team ${teamId}.`,
509
+ {
510
+ team_id: teamId,
511
+ user_id: userId,
512
+ permission_id: permissionId,
513
+ },
514
+ ], (json) => [json.team_id, json.user_id, json.permission_id]);
491
515
  const InvalidSharedOAuthProviderId = createKnownErrorConstructor(KnownError, "INVALID_SHARED_OAUTH_PROVIDER_ID", (providerId) => [
492
516
  400,
493
517
  `The shared OAuth provider with ID ${providerId} is not valid.`,
@@ -552,6 +576,7 @@ export const KnownErrors = {
552
576
  UserNotFound,
553
577
  ApiKeyNotFound,
554
578
  ProjectNotFound,
579
+ SignUpNotEnabled,
555
580
  PasswordAuthenticationNotEnabled,
556
581
  EmailPasswordMismatch,
557
582
  RedirectUrlNotWhitelisted,
@@ -582,12 +607,15 @@ export const KnownErrors = {
582
607
  UserAlreadyConnectedToAnotherOAuthConnection,
583
608
  OuterOAuthTimeout,
584
609
  OAuthProviderNotFoundOrNotEnabled,
610
+ MultiFactorAuthenticationRequired,
611
+ InvalidTotpCode,
585
612
  UserAuthenticationRequired,
586
613
  TeamMembershipAlreadyExists,
587
614
  TeamPermissionRequired,
588
615
  InvalidSharedOAuthProviderId,
589
616
  InvalidStandardOAuthProviderId,
590
617
  InvalidAuthorizationCode,
618
+ TeamPermissionNotFound,
591
619
  };
592
620
  // ensure that all known error codes are unique
593
621
  const knownErrorCodes = new Set();
@@ -22,6 +22,7 @@ export declare const jsonSchema: yup.MixedSchema<{} | null, yup.AnyObject, undef
22
22
  export declare const jsonStringSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
23
23
  export declare const jsonStringOrEmptySchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
24
24
  export declare const emailSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
25
+ export declare const base64Schema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
25
26
  export declare const clientOrHigherAuthTypeSchema: yup.StringSchema<"client" | "server" | "admin" | undefined, yup.AnyObject, undefined, "">;
26
27
  export declare const serverOrHigherAuthTypeSchema: yup.StringSchema<"server" | "admin" | undefined, yup.AnyObject, undefined, "">;
27
28
  export declare const adminAuthTypeSchema: yup.StringSchema<"admin" | undefined, yup.AnyObject, undefined, "">;
@@ -35,6 +36,7 @@ export declare const projectConfigIdSchema: yup.StringSchema<string | undefined,
35
36
  export declare const projectAllowLocalhostSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
36
37
  export declare const projectCreateTeamOnSignUpSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
37
38
  export declare const projectMagicLinkEnabledSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
39
+ export declare const projectSignUpEnabledSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
38
40
  export declare const projectCredentialEnabledSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
39
41
  export declare const oauthIdSchema: yup.StringSchema<"google" | "github" | "facebook" | "microsoft" | "spotify" | undefined, yup.AnyObject, undefined, "">;
40
42
  export declare const oauthEnabledSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
@@ -98,6 +100,8 @@ export declare const teamProfileImageUrlSchema: yup.StringSchema<string | undefi
98
100
  export declare const teamClientMetadataSchema: yup.MixedSchema<{} | null, yup.AnyObject, undefined, "">;
99
101
  export declare const teamServerMetadataSchema: yup.MixedSchema<{} | null, yup.AnyObject, undefined, "">;
100
102
  export declare const teamCreatedAtMillisSchema: yup.NumberSchema<number | undefined, yup.AnyObject, undefined, "">;
103
+ export declare const teamInvitationEmailSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
104
+ export declare const teamInvitationCallbackUrlSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
101
105
  export declare const teamMemberDisplayNameSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
102
106
  export declare const teamMemberProfileImageUrlSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
103
107
  export declare function yupRequiredWhen<S extends yup.AnyObject>(schema: S, triggerName: string, isValue: any): S;
@@ -1,4 +1,5 @@
1
1
  import * as yup from "yup";
2
+ import { isBase64 } from "./utils/bytes";
2
3
  import { StackAssertionError } from "./utils/errors";
3
4
  import { allProviders } from "./utils/oauth";
4
5
  import { isUuid } from "./utils/uuids";
@@ -124,6 +125,11 @@ export const jsonStringOrEmptySchema = yupString().test("json", "Invalid JSON fo
124
125
  }
125
126
  });
126
127
  export const emailSchema = yupString().email();
128
+ export const base64Schema = yupString().test("is-base64", "Invalid base64 format", (value) => {
129
+ if (value == null)
130
+ return true;
131
+ return isBase64(value);
132
+ });
127
133
  // Request auth
128
134
  export const clientOrHigherAuthTypeSchema = yupString().oneOf(['client', 'server', 'admin']);
129
135
  export const serverOrHigherAuthTypeSchema = yupString().oneOf(['server', 'admin']);
@@ -140,6 +146,7 @@ export const projectConfigIdSchema = yupString().meta({ openapiField: { descript
140
146
  export const projectAllowLocalhostSchema = yupBoolean().meta({ openapiField: { description: 'Whether localhost is allowed as a domain for this project. Should only be allowed in development mode', exampleValue: true } });
141
147
  export const projectCreateTeamOnSignUpSchema = yupBoolean().meta({ openapiField: { description: 'Whether a team should be created for each user that signs up', exampleValue: true } });
142
148
  export const projectMagicLinkEnabledSchema = yupBoolean().meta({ openapiField: { description: 'Whether magic link authentication is enabled for this project', exampleValue: true } });
149
+ export const projectSignUpEnabledSchema = yupBoolean().meta({ openapiField: { description: 'Whether users can sign up new accounts, or whether they are only allowed to sign in to existing accounts. Regardless of this option, the server API can always create new users with the `POST /users` endpoint.', exampleValue: true } });
143
150
  export const projectCredentialEnabledSchema = yupBoolean().meta({ openapiField: { description: 'Whether email password authentication is enabled for this project', exampleValue: true } });
144
151
  // Project OAuth config
145
152
  export const oauthIdSchema = yupString().oneOf(allProviders).meta({ openapiField: { description: `OAuth provider ID, one of ${allProviders.map(x => `\`${x}\``).join(', ')}`, exampleValue: 'google' } });
@@ -180,7 +187,7 @@ export const userIdSchema = yupString().uuid().meta({ openapiField: { descriptio
180
187
  export const primaryEmailSchema = emailSchema.meta({ openapiField: { description: 'Primary email', exampleValue: 'johndoe@example.com' } });
181
188
  export const primaryEmailVerifiedSchema = yupBoolean().meta({ openapiField: { description: 'Whether the primary email has been verified to belong to this user', exampleValue: true } });
182
189
  export const userDisplayNameSchema = yupString().nullable().meta({ openapiField: { description: _displayNameDescription('user'), exampleValue: 'John Doe' } });
183
- export const selectedTeamIdSchema = yupString().meta({ openapiField: { description: 'ID of the team currently selected by the user', exampleValue: 'team-id' } });
190
+ export const selectedTeamIdSchema = yupString().uuid().meta({ openapiField: { description: 'ID of the team currently selected by the user', exampleValue: 'team-id' } });
184
191
  export const profileImageUrlSchema = yupString().meta({ openapiField: { description: _profileImageUrlDescription('user'), exampleValue: 'https://example.com/image.jpg' } });
185
192
  export const signedUpAtMillisSchema = yupNumber().meta({ openapiField: { description: _signedUpAtMillisDescription, exampleValue: 1630000000000 } });
186
193
  export const userClientMetadataSchema = jsonSchema.meta({ openapiField: { description: _clientMetaDataDescription('user'), exampleValue: { key: 'value' } } });
@@ -232,6 +239,8 @@ export const teamProfileImageUrlSchema = yupString().meta({ openapiField: { desc
232
239
  export const teamClientMetadataSchema = jsonSchema.meta({ openapiField: { description: _clientMetaDataDescription('team'), exampleValue: { key: 'value' } } });
233
240
  export const teamServerMetadataSchema = jsonSchema.meta({ openapiField: { description: _serverMetaDataDescription('team'), exampleValue: { key: 'value' } } });
234
241
  export const teamCreatedAtMillisSchema = yupNumber().meta({ openapiField: { description: _createdAtMillisDescription('team'), exampleValue: 1630000000000 } });
242
+ export const teamInvitationEmailSchema = emailSchema.meta({ openapiField: { description: 'The email to sign in with.', exampleValue: 'johndoe@example.com' } });
243
+ export const teamInvitationCallbackUrlSchema = urlSchema.meta({ openapiField: { description: 'The base callback URL to construct a verification link for the verification e-mail. A query argument `code` with the verification code will be appended to it. The page should then make a request to the `/contact-channels/verify` endpoint.', exampleValue: 'https://example.com/handler/email-verification' } });
235
244
  // Team member profiles
236
245
  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' } });
237
246
  export const teamMemberProfileImageUrlSchema = yupString().meta({ openapiField: { description: _profileImageUrlDescription('team member'), exampleValue: 'https://example.com/image.jpg' } });
@@ -1,2 +1,6 @@
1
1
  export declare function encodeBase32(input: Uint8Array): string;
2
2
  export declare function decodeBase32(input: string): Uint8Array;
3
+ export declare function encodeBase64(input: Uint8Array): string;
4
+ export declare function decodeBase64(input: string): Uint8Array;
5
+ export declare function isBase32(input: string): boolean;
6
+ export declare function isBase64(input: string): boolean;
@@ -1,3 +1,4 @@
1
+ import { StackAssertionError } from "./errors";
1
2
  const crockfordAlphabet = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
2
3
  const crockfordReplacements = new Map([
3
4
  ["o", "0"],
@@ -19,9 +20,16 @@ export function encodeBase32(input) {
19
20
  if (bits > 0) {
20
21
  output += crockfordAlphabet[(value << (5 - bits)) & 31];
21
22
  }
23
+ // sanity check
24
+ if (!isBase32(output)) {
25
+ throw new StackAssertionError("Invalid base32 output; this should never happen");
26
+ }
22
27
  return output;
23
28
  }
24
29
  export function decodeBase32(input) {
30
+ if (!isBase32(input)) {
31
+ throw new StackAssertionError("Invalid base32 string");
32
+ }
25
33
  const output = new Uint8Array((input.length * 5 / 8) | 0);
26
34
  let bits = 0;
27
35
  let value = 0;
@@ -46,3 +54,31 @@ export function decodeBase32(input) {
46
54
  }
47
55
  return output;
48
56
  }
57
+ export function encodeBase64(input) {
58
+ const res = btoa(String.fromCharCode(...input));
59
+ // sanity check
60
+ if (!isBase64(res)) {
61
+ throw new StackAssertionError("Invalid base64 output; this should never happen");
62
+ }
63
+ return res;
64
+ }
65
+ export function decodeBase64(input) {
66
+ if (!isBase64(input)) {
67
+ throw new StackAssertionError("Invalid base64 string");
68
+ }
69
+ return new Uint8Array(atob(input).split("").map((char) => char.charCodeAt(0)));
70
+ }
71
+ export function isBase32(input) {
72
+ for (const char of input) {
73
+ if (char === " ")
74
+ continue;
75
+ if (!crockfordAlphabet.includes(char)) {
76
+ return false;
77
+ }
78
+ }
79
+ return true;
80
+ }
81
+ export function isBase64(input) {
82
+ const regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
83
+ return regex.test(input);
84
+ }
@@ -1,4 +1,4 @@
1
- export declare function generateRandomValues(array: Uint8Array): any;
1
+ export declare function generateRandomValues(array: Uint8Array): typeof array;
2
2
  /**
3
3
  * Generates a secure alphanumeric string using the system's cryptographically secure
4
4
  * random number generator.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackframe/stack-shared",
3
- "version": "2.5.17",
3
+ "version": "2.5.18",
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.17"
39
+ "@stackframe/stack-sc": "2.5.18"
40
40
  },
41
41
  "devDependencies": {
42
42
  "rimraf": "^5.0.5",