@stackframe/stack-shared 2.6.11 → 2.6.15

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,33 @@
1
1
  # @stackframe/stack-shared
2
2
 
3
+ ## 2.6.15
4
+
5
+ ### Patch Changes
6
+
7
+ - Passkeys
8
+ - @stackframe/stack-sc@2.6.15
9
+
10
+ ## 2.6.14
11
+
12
+ ### Patch Changes
13
+
14
+ - @stackframe/stack-sc@2.6.14
15
+
16
+ ## 2.6.13
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated docs
21
+ - @stackframe/stack-sc@2.6.13
22
+
23
+ ## 2.6.12
24
+
25
+ ### Patch Changes
26
+
27
+ - Updated account settings page
28
+ - Updated dependencies
29
+ - @stackframe/stack-sc@2.6.12
30
+
3
31
  ## 2.6.11
4
32
 
5
33
  ### Patch Changes
@@ -1,7 +1,9 @@
1
1
  import { KnownErrors } from '../known-errors';
2
2
  import { AccessToken, InternalSession, RefreshToken } from '../sessions';
3
3
  import { ReadonlyJson } from '../utils/json';
4
+ import { AuthenticationResponseJSON, PublicKeyCredentialCreationOptionsJSON, PublicKeyCredentialRequestOptionsJSON, RegistrationResponseJSON } from '../utils/passkey';
4
5
  import { Result } from "../utils/results";
6
+ import { ContactChannelsCrud } from './crud/contact-channels';
5
7
  import { CurrentUserCrud } from './crud/current-user';
6
8
  import { ConnectedAccountAccessTokenCrud } from './crud/oauth';
7
9
  import { InternalProjectsCrud, ProjectsCrud } from './crud/projects';
@@ -67,14 +69,29 @@ export declare class StackClientInterface {
67
69
  oldPassword: string;
68
70
  newPassword: string;
69
71
  }, session: InternalSession): Promise<KnownErrors["PasswordConfirmationMismatch"] | KnownErrors["PasswordRequirementsNotMet"] | undefined>;
72
+ setPassword(options: {
73
+ password: string;
74
+ }, session: InternalSession): Promise<KnownErrors["PasswordRequirementsNotMet"] | undefined>;
70
75
  verifyPasswordResetCode(code: string): Promise<Result<undefined, KnownErrors["VerificationCodeError"]>>;
71
76
  verifyEmail(code: string): Promise<Result<undefined, KnownErrors["VerificationCodeError"]>>;
77
+ initiatePasskeyRegistration(options: {}, session: InternalSession): Promise<Result<{
78
+ options_json: PublicKeyCredentialCreationOptionsJSON;
79
+ code: string;
80
+ }, KnownErrors[]>>;
81
+ registerPasskey(options: {
82
+ credential: RegistrationResponseJSON;
83
+ code: string;
84
+ }, session: InternalSession): Promise<Result<undefined, KnownErrors["PasskeyRegistrationFailed"]>>;
85
+ initiatePasskeyAuthentication(options: {}, session: InternalSession): Promise<Result<{
86
+ options_json: PublicKeyCredentialRequestOptionsJSON;
87
+ code: string;
88
+ }, KnownErrors[]>>;
72
89
  sendTeamInvitation(options: {
73
90
  email: string;
74
91
  teamId: string;
75
92
  callbackUrl: string;
76
93
  session: InternalSession | null;
77
- }): Promise<Result<undefined, KnownErrors["TeamPermissionRequired"]>>;
94
+ }): Promise<void>;
78
95
  acceptTeamInvitation<T extends 'use' | 'details' | 'check'>(options: {
79
96
  code: string;
80
97
  session: InternalSession;
@@ -100,6 +117,13 @@ export declare class StackClientInterface {
100
117
  accessToken: string;
101
118
  refreshToken: string;
102
119
  }, KnownErrors["VerificationCodeError"]>>;
120
+ signInWithPasskey(body: {
121
+ authentication_response: AuthenticationResponseJSON;
122
+ code: string;
123
+ }): Promise<Result<{
124
+ accessToken: string;
125
+ refreshToken: string;
126
+ }, KnownErrors["PasskeyAuthenticationFailed"]>>;
103
127
  getOAuthUrl(options: {
104
128
  provider: string;
105
129
  redirectUrl: string;
@@ -158,4 +182,9 @@ export declare class StackClientInterface {
158
182
  createProviderAccessToken(provider: string, scope: string, session: InternalSession): Promise<ConnectedAccountAccessTokenCrud['Client']['Read']>;
159
183
  createClientTeam(data: TeamsCrud['Client']['Create'], session: InternalSession): Promise<TeamsCrud['Client']['Read']>;
160
184
  deleteCurrentUser(session: InternalSession): Promise<void>;
185
+ createClientContactChannel(data: ContactChannelsCrud['Client']['Create'], session: InternalSession): Promise<ContactChannelsCrud['Client']['Read']>;
186
+ updateClientContactChannel(id: string, data: ContactChannelsCrud['Client']['Update'], session: InternalSession): Promise<ContactChannelsCrud['Client']['Read']>;
187
+ deleteClientContactChannel(id: string, session: InternalSession): Promise<void>;
188
+ listClientContactChannels(session: InternalSession): Promise<ContactChannelsCrud['Client']['Read'][]>;
189
+ sendCurrentUserContactChannelVerificationEmail(contactChannelId: string, callbackUrl: string, session: InternalSession): Promise<Result<undefined, KnownErrors["EmailAlreadyVerified"]>>;
161
190
  }
@@ -375,6 +375,18 @@ export class StackClientInterface {
375
375
  return res.error;
376
376
  }
377
377
  }
378
+ async setPassword(options, session) {
379
+ const res = await this.sendClientRequestAndCatchKnownError("/auth/password/set", {
380
+ method: "POST",
381
+ headers: {
382
+ "Content-Type": "application/json"
383
+ },
384
+ body: JSON.stringify(options),
385
+ }, session, [KnownErrors.PasswordRequirementsNotMet]);
386
+ if (res.status === "error") {
387
+ return res.error;
388
+ }
389
+ }
378
390
  async verifyPasswordResetCode(code) {
379
391
  const res = await this.resetPassword({ code, onlyVerifyCode: true });
380
392
  if (res.status === "error") {
@@ -401,8 +413,47 @@ export class StackClientInterface {
401
413
  return Result.ok(undefined);
402
414
  }
403
415
  }
416
+ async initiatePasskeyRegistration(options, session) {
417
+ const res = await this.sendClientRequestAndCatchKnownError("/auth/passkey/initiate-passkey-registration", {
418
+ method: "POST",
419
+ headers: {
420
+ "Content-Type": "application/json"
421
+ },
422
+ body: JSON.stringify(options),
423
+ }, session, []);
424
+ if (res.status === "error") {
425
+ return Result.error(res.error);
426
+ }
427
+ return Result.ok(await res.data.json());
428
+ }
429
+ async registerPasskey(options, session) {
430
+ const res = await this.sendClientRequestAndCatchKnownError("/auth/passkey/register", {
431
+ method: "POST",
432
+ headers: {
433
+ "Content-Type": "application/json"
434
+ },
435
+ body: JSON.stringify(options),
436
+ }, session, [KnownErrors.PasskeyRegistrationFailed]);
437
+ if (res.status === "error") {
438
+ return Result.error(res.error);
439
+ }
440
+ return Result.ok(undefined);
441
+ }
442
+ async initiatePasskeyAuthentication(options, session) {
443
+ const res = await this.sendClientRequestAndCatchKnownError("/auth/passkey/initiate-passkey-authentication", {
444
+ method: "POST",
445
+ headers: {
446
+ "Content-Type": "application/json"
447
+ },
448
+ body: JSON.stringify(options),
449
+ }, session, []);
450
+ if (res.status === "error") {
451
+ return Result.error(res.error);
452
+ }
453
+ return Result.ok(await res.data.json());
454
+ }
404
455
  async sendTeamInvitation(options) {
405
- const res = await this.sendClientRequestAndCatchKnownError("/team-invitations/send-code", {
456
+ await this.sendClientRequest("/team-invitations/send-code", {
406
457
  method: "POST",
407
458
  headers: {
408
459
  "Content-Type": "application/json"
@@ -412,13 +463,7 @@ export class StackClientInterface {
412
463
  team_id: options.teamId,
413
464
  callback_url: options.callbackUrl,
414
465
  }),
415
- }, options.session, [KnownErrors.TeamPermissionRequired]);
416
- if (res.status === "error") {
417
- return Result.error(res.error);
418
- }
419
- else {
420
- return Result.ok(undefined);
421
- }
466
+ }, options.session);
422
467
  }
423
468
  async acceptTeamInvitation(options) {
424
469
  const res = await this.sendClientRequestAndCatchKnownError(options.type === 'check' ?
@@ -521,6 +566,23 @@ export class StackClientInterface {
521
566
  newUser: result.is_new_user,
522
567
  });
523
568
  }
569
+ async signInWithPasskey(body) {
570
+ const res = await this.sendClientRequestAndCatchKnownError("/auth/passkey/sign-in", {
571
+ method: "POST",
572
+ headers: {
573
+ "Content-Type": "application/json"
574
+ },
575
+ body: JSON.stringify(body),
576
+ }, null, [KnownErrors.PasskeyAuthenticationFailed]);
577
+ if (res.status === "error") {
578
+ return Result.error(res.error);
579
+ }
580
+ const result = await res.data.json();
581
+ return Result.ok({
582
+ accessToken: result.access_token,
583
+ refreshToken: result.refresh_token,
584
+ });
585
+ }
524
586
  async getOAuthUrl(options) {
525
587
  const updatedRedirectUrl = new URL(options.redirectUrl);
526
588
  for (const key of ["code", "state"]) {
@@ -747,4 +809,49 @@ export class StackClientInterface {
747
809
  method: "DELETE",
748
810
  }, session);
749
811
  }
812
+ async createClientContactChannel(data, session) {
813
+ const response = await this.sendClientRequest("/contact-channels", {
814
+ method: "POST",
815
+ headers: {
816
+ "content-type": "application/json",
817
+ },
818
+ body: JSON.stringify(data),
819
+ }, session);
820
+ return await response.json();
821
+ }
822
+ async updateClientContactChannel(id, data, session) {
823
+ const response = await this.sendClientRequest(`/contact-channels/me/${id}`, {
824
+ method: "PATCH",
825
+ headers: {
826
+ "content-type": "application/json",
827
+ },
828
+ body: JSON.stringify(data),
829
+ }, session);
830
+ return await response.json();
831
+ }
832
+ async deleteClientContactChannel(id, session) {
833
+ await this.sendClientRequest(`/contact-channels/me/${id}`, {
834
+ method: "DELETE",
835
+ }, session);
836
+ }
837
+ async listClientContactChannels(session) {
838
+ const response = await this.sendClientRequest("/contact-channels?user_id=me", {
839
+ method: "GET",
840
+ }, session);
841
+ const json = await response.json();
842
+ return json.items;
843
+ }
844
+ async sendCurrentUserContactChannelVerificationEmail(contactChannelId, callbackUrl, session) {
845
+ const responseOrError = await this.sendClientRequestAndCatchKnownError(`/contact-channels/me/${contactChannelId}/send-verification-code`, {
846
+ method: "POST",
847
+ headers: {
848
+ "content-type": "application/json",
849
+ },
850
+ body: JSON.stringify({ callback_url: callbackUrl }),
851
+ }, session, [KnownErrors.EmailAlreadyVerified]);
852
+ if (responseOrError.status === "error") {
853
+ return Result.error(responseOrError.error);
854
+ }
855
+ return Result.ok(undefined);
856
+ }
750
857
  }
@@ -13,6 +13,8 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
13
13
  client_metadata: {} | null;
14
14
  client_read_only_metadata: {} | null;
15
15
  primary_email_verified: NonNullable<boolean | undefined>;
16
+ passkey_auth_enabled: NonNullable<boolean | undefined>;
17
+ otp_auth_enabled: NonNullable<boolean | undefined>;
16
18
  selected_team_id: string | null;
17
19
  signed_up_at_millis: number;
18
20
  has_password: NonNullable<boolean | undefined>;
@@ -30,6 +32,7 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
30
32
  id: undefined;
31
33
  primary_email: undefined;
32
34
  primary_email_verified: undefined;
35
+ primary_email_auth_enabled: undefined;
33
36
  display_name: undefined;
34
37
  selected_team: {
35
38
  id: undefined;
@@ -42,6 +45,8 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
42
45
  profile_image_url: undefined;
43
46
  signed_up_at_millis: undefined;
44
47
  has_password: undefined;
48
+ otp_auth_enabled: undefined;
49
+ passkey_auth_enabled: undefined;
45
50
  client_metadata: undefined;
46
51
  client_read_only_metadata: undefined;
47
52
  server_metadata: undefined;
@@ -54,6 +59,7 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
54
59
  id: string;
55
60
  primary_email: string | null;
56
61
  primary_email_verified: NonNullable<boolean | undefined>;
62
+ primary_email_auth_enabled: NonNullable<boolean | undefined>;
57
63
  display_name: string | null;
58
64
  selected_team: {
59
65
  client_metadata?: {} | null | undefined;
@@ -68,6 +74,8 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
68
74
  profile_image_url: string | null;
69
75
  signed_up_at_millis: number;
70
76
  has_password: NonNullable<boolean | undefined>;
77
+ otp_auth_enabled: NonNullable<boolean | undefined>;
78
+ passkey_auth_enabled: NonNullable<boolean | undefined>;
71
79
  client_metadata: {} | null;
72
80
  client_read_only_metadata: {} | null;
73
81
  server_metadata: {} | null;
@@ -83,6 +91,7 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
83
91
  id: undefined;
84
92
  primary_email: undefined;
85
93
  primary_email_verified: undefined;
94
+ primary_email_auth_enabled: undefined;
86
95
  display_name: undefined;
87
96
  selected_team: {
88
97
  id: undefined;
@@ -97,6 +106,8 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
97
106
  profile_image_url: undefined;
98
107
  signed_up_at_millis: undefined;
99
108
  has_password: undefined;
109
+ otp_auth_enabled: undefined;
110
+ passkey_auth_enabled: undefined;
100
111
  client_metadata: undefined;
101
112
  client_read_only_metadata: undefined;
102
113
  server_metadata: undefined;
@@ -109,6 +120,8 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
109
120
  display_name: string | null | undefined;
110
121
  profile_image_url: string | null | undefined;
111
122
  client_metadata: {} | null | undefined;
123
+ passkey_auth_enabled: boolean | undefined;
124
+ otp_auth_enabled: boolean | undefined;
112
125
  totp_secret_base64: string | null | undefined;
113
126
  selected_team_id: string | null | undefined;
114
127
  }, import("yup").AnyObject, {
@@ -120,7 +133,9 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
120
133
  primary_email: undefined;
121
134
  primary_email_verified: undefined;
122
135
  primary_email_auth_enabled: undefined;
136
+ passkey_auth_enabled: undefined;
123
137
  password: undefined;
138
+ otp_auth_enabled: undefined;
124
139
  totp_secret_base64: undefined;
125
140
  selected_team_id: undefined;
126
141
  }, "">;
@@ -133,7 +148,9 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
133
148
  primary_email: string | null | undefined;
134
149
  primary_email_verified: boolean | undefined;
135
150
  primary_email_auth_enabled: boolean | undefined;
151
+ passkey_auth_enabled: boolean | undefined;
136
152
  password: string | null | undefined;
153
+ otp_auth_enabled: boolean | undefined;
137
154
  totp_secret_base64: string | null | undefined;
138
155
  selected_team_id: string | null | undefined;
139
156
  }, import("yup").AnyObject, {
@@ -145,7 +162,9 @@ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions
145
162
  primary_email: undefined;
146
163
  primary_email_verified: undefined;
147
164
  primary_email_auth_enabled: undefined;
165
+ passkey_auth_enabled: undefined;
148
166
  password: undefined;
167
+ otp_auth_enabled: undefined;
149
168
  totp_secret_base64: undefined;
150
169
  selected_team_id: undefined;
151
170
  }, "">;
@@ -8,6 +8,8 @@ const clientUpdateSchema = usersCrudServerUpdateSchema.pick([
8
8
  "client_metadata",
9
9
  "selected_team_id",
10
10
  "totp_secret_base64",
11
+ "otp_auth_enabled",
12
+ "passkey_auth_enabled",
11
13
  ]).required();
12
14
  const serverUpdateSchema = usersCrudServerUpdateSchema;
13
15
  const clientReadSchema = usersCrudServerReadSchema.pick([
@@ -24,6 +26,8 @@ const clientReadSchema = usersCrudServerReadSchema.pick([
24
26
  "oauth_providers",
25
27
  "selected_team_id",
26
28
  "requires_totp_mfa",
29
+ "otp_auth_enabled",
30
+ "passkey_auth_enabled",
27
31
  ]).concat(yupObject({
28
32
  selected_team: teamsCrudClientReadSchema.nullable().defined(),
29
33
  })).nullable().defined(); // TODO: next-release: make required
@@ -12,6 +12,7 @@ export declare const projectsCrudAdminReadSchema: import("yup").ObjectSchema<{
12
12
  sign_up_enabled: NonNullable<boolean | undefined>;
13
13
  credential_enabled: NonNullable<boolean | undefined>;
14
14
  magic_link_enabled: NonNullable<boolean | undefined>;
15
+ passkey_enabled: NonNullable<boolean | undefined>;
15
16
  legacy_global_jwt_signing: NonNullable<boolean | undefined>;
16
17
  client_team_creation_enabled: NonNullable<boolean | undefined>;
17
18
  client_user_deletion_enabled: NonNullable<boolean | undefined>;
@@ -61,6 +62,7 @@ export declare const projectsCrudAdminReadSchema: import("yup").ObjectSchema<{
61
62
  sign_up_enabled: undefined;
62
63
  credential_enabled: undefined;
63
64
  magic_link_enabled: undefined;
65
+ passkey_enabled: undefined;
64
66
  legacy_global_jwt_signing: undefined;
65
67
  client_team_creation_enabled: undefined;
66
68
  client_user_deletion_enabled: undefined;
@@ -88,6 +90,7 @@ export declare const projectsCrudClientReadSchema: import("yup").ObjectSchema<{
88
90
  sign_up_enabled: NonNullable<boolean | undefined>;
89
91
  credential_enabled: NonNullable<boolean | undefined>;
90
92
  magic_link_enabled: NonNullable<boolean | undefined>;
93
+ passkey_enabled: NonNullable<boolean | undefined>;
91
94
  client_team_creation_enabled: NonNullable<boolean | undefined>;
92
95
  client_user_deletion_enabled: NonNullable<boolean | undefined>;
93
96
  enabled_oauth_providers: {
@@ -101,6 +104,7 @@ export declare const projectsCrudClientReadSchema: import("yup").ObjectSchema<{
101
104
  sign_up_enabled: undefined;
102
105
  credential_enabled: undefined;
103
106
  magic_link_enabled: undefined;
107
+ passkey_enabled: undefined;
104
108
  client_team_creation_enabled: undefined;
105
109
  client_user_deletion_enabled: undefined;
106
110
  enabled_oauth_providers: undefined;
@@ -115,6 +119,7 @@ export declare const projectsCrudAdminUpdateSchema: import("yup").ObjectSchema<{
115
119
  sign_up_enabled?: boolean | undefined;
116
120
  credential_enabled?: boolean | undefined;
117
121
  magic_link_enabled?: boolean | undefined;
122
+ passkey_enabled?: boolean | undefined;
118
123
  legacy_global_jwt_signing?: false | undefined;
119
124
  client_team_creation_enabled?: boolean | undefined;
120
125
  client_user_deletion_enabled?: boolean | undefined;
@@ -163,6 +168,7 @@ export declare const projectsCrudAdminCreateSchema: import("yup").ObjectSchema<{
163
168
  sign_up_enabled?: boolean | undefined;
164
169
  credential_enabled?: boolean | undefined;
165
170
  magic_link_enabled?: boolean | undefined;
171
+ passkey_enabled?: boolean | undefined;
166
172
  legacy_global_jwt_signing?: false | undefined;
167
173
  client_team_creation_enabled?: boolean | undefined;
168
174
  client_user_deletion_enabled?: boolean | undefined;
@@ -213,6 +219,7 @@ export declare const projectsCrud: import("../../crud").CrudSchemaFromOptions<{
213
219
  sign_up_enabled: NonNullable<boolean | undefined>;
214
220
  credential_enabled: NonNullable<boolean | undefined>;
215
221
  magic_link_enabled: NonNullable<boolean | undefined>;
222
+ passkey_enabled: NonNullable<boolean | undefined>;
216
223
  client_team_creation_enabled: NonNullable<boolean | undefined>;
217
224
  client_user_deletion_enabled: NonNullable<boolean | undefined>;
218
225
  enabled_oauth_providers: {
@@ -226,6 +233,7 @@ export declare const projectsCrud: import("../../crud").CrudSchemaFromOptions<{
226
233
  sign_up_enabled: undefined;
227
234
  credential_enabled: undefined;
228
235
  magic_link_enabled: undefined;
236
+ passkey_enabled: undefined;
229
237
  client_team_creation_enabled: undefined;
230
238
  client_user_deletion_enabled: undefined;
231
239
  enabled_oauth_providers: undefined;
@@ -244,6 +252,7 @@ export declare const projectsCrud: import("../../crud").CrudSchemaFromOptions<{
244
252
  sign_up_enabled: NonNullable<boolean | undefined>;
245
253
  credential_enabled: NonNullable<boolean | undefined>;
246
254
  magic_link_enabled: NonNullable<boolean | undefined>;
255
+ passkey_enabled: NonNullable<boolean | undefined>;
247
256
  legacy_global_jwt_signing: NonNullable<boolean | undefined>;
248
257
  client_team_creation_enabled: NonNullable<boolean | undefined>;
249
258
  client_user_deletion_enabled: NonNullable<boolean | undefined>;
@@ -293,6 +302,7 @@ export declare const projectsCrud: import("../../crud").CrudSchemaFromOptions<{
293
302
  sign_up_enabled: undefined;
294
303
  credential_enabled: undefined;
295
304
  magic_link_enabled: undefined;
305
+ passkey_enabled: undefined;
296
306
  legacy_global_jwt_signing: undefined;
297
307
  client_team_creation_enabled: undefined;
298
308
  client_user_deletion_enabled: undefined;
@@ -322,6 +332,7 @@ export declare const projectsCrud: import("../../crud").CrudSchemaFromOptions<{
322
332
  sign_up_enabled?: boolean | undefined;
323
333
  credential_enabled?: boolean | undefined;
324
334
  magic_link_enabled?: boolean | undefined;
335
+ passkey_enabled?: boolean | undefined;
325
336
  legacy_global_jwt_signing?: false | undefined;
326
337
  client_team_creation_enabled?: boolean | undefined;
327
338
  client_user_deletion_enabled?: boolean | undefined;
@@ -400,6 +411,7 @@ export declare const internalProjectsCrud: import("../../crud").CrudSchemaFromOp
400
411
  sign_up_enabled: NonNullable<boolean | undefined>;
401
412
  credential_enabled: NonNullable<boolean | undefined>;
402
413
  magic_link_enabled: NonNullable<boolean | undefined>;
414
+ passkey_enabled: NonNullable<boolean | undefined>;
403
415
  legacy_global_jwt_signing: NonNullable<boolean | undefined>;
404
416
  client_team_creation_enabled: NonNullable<boolean | undefined>;
405
417
  client_user_deletion_enabled: NonNullable<boolean | undefined>;
@@ -449,6 +461,7 @@ export declare const internalProjectsCrud: import("../../crud").CrudSchemaFromOp
449
461
  sign_up_enabled: undefined;
450
462
  credential_enabled: undefined;
451
463
  magic_link_enabled: undefined;
464
+ passkey_enabled: undefined;
452
465
  legacy_global_jwt_signing: undefined;
453
466
  client_team_creation_enabled: undefined;
454
467
  client_user_deletion_enabled: undefined;
@@ -478,6 +491,7 @@ export declare const internalProjectsCrud: import("../../crud").CrudSchemaFromOp
478
491
  sign_up_enabled?: boolean | undefined;
479
492
  credential_enabled?: boolean | undefined;
480
493
  magic_link_enabled?: boolean | undefined;
494
+ passkey_enabled?: boolean | undefined;
481
495
  legacy_global_jwt_signing?: false | undefined;
482
496
  client_team_creation_enabled?: boolean | undefined;
483
497
  client_user_deletion_enabled?: boolean | undefined;
@@ -43,12 +43,13 @@ export const projectsCrudAdminReadSchema = yupObject({
43
43
  sign_up_enabled: schemaFields.projectSignUpEnabledSchema.required(),
44
44
  credential_enabled: schemaFields.projectCredentialEnabledSchema.required(),
45
45
  magic_link_enabled: schemaFields.projectMagicLinkEnabledSchema.required(),
46
+ passkey_enabled: schemaFields.projectPasskeyEnabledSchema.required(),
46
47
  // TODO: remove this
47
48
  legacy_global_jwt_signing: schemaFields.yupBoolean().required(),
48
49
  client_team_creation_enabled: schemaFields.projectClientTeamCreationEnabledSchema.required(),
49
50
  client_user_deletion_enabled: schemaFields.projectClientUserDeletionEnabledSchema.required(),
50
51
  oauth_providers: yupArray(oauthProviderSchema.required()).required(),
51
- enabled_oauth_providers: yupArray(enabledOAuthProviderSchema.required()).required(),
52
+ enabled_oauth_providers: yupArray(enabledOAuthProviderSchema.required()).required().meta({ openapiField: { hidden: true } }),
52
53
  domains: yupArray(domainSchema.required()).required(),
53
54
  email_config: emailConfigSchema.required(),
54
55
  create_team_on_sign_up: schemaFields.projectCreateTeamOnSignUpSchema.required(),
@@ -63,9 +64,10 @@ export const projectsCrudClientReadSchema = yupObject({
63
64
  sign_up_enabled: schemaFields.projectSignUpEnabledSchema.required(),
64
65
  credential_enabled: schemaFields.projectCredentialEnabledSchema.required(),
65
66
  magic_link_enabled: schemaFields.projectMagicLinkEnabledSchema.required(),
67
+ passkey_enabled: schemaFields.projectPasskeyEnabledSchema.required(),
66
68
  client_team_creation_enabled: schemaFields.projectClientTeamCreationEnabledSchema.required(),
67
69
  client_user_deletion_enabled: schemaFields.projectClientUserDeletionEnabledSchema.required(),
68
- enabled_oauth_providers: yupArray(enabledOAuthProviderSchema.required()).required(),
70
+ enabled_oauth_providers: yupArray(enabledOAuthProviderSchema.required()).required().meta({ openapiField: { hidden: true } }),
69
71
  }).required(),
70
72
  }).required();
71
73
  export const projectsCrudAdminUpdateSchema = yupObject({
@@ -76,6 +78,7 @@ export const projectsCrudAdminUpdateSchema = yupObject({
76
78
  sign_up_enabled: schemaFields.projectSignUpEnabledSchema.optional(),
77
79
  credential_enabled: schemaFields.projectCredentialEnabledSchema.optional(),
78
80
  magic_link_enabled: schemaFields.projectMagicLinkEnabledSchema.optional(),
81
+ passkey_enabled: schemaFields.projectPasskeyEnabledSchema.optional(),
79
82
  client_team_creation_enabled: schemaFields.projectClientTeamCreationEnabledSchema.optional(),
80
83
  client_user_deletion_enabled: schemaFields.projectClientUserDeletionEnabledSchema.optional(),
81
84
  legacy_global_jwt_signing: schemaFields.yupBoolean().isFalse().optional(),
@@ -30,6 +30,9 @@ export declare const teamMemberProfilesCrudServerReadSchema: import("yup").Objec
30
30
  client_read_only_metadata: {} | null;
31
31
  server_metadata: {} | null;
32
32
  primary_email_verified: NonNullable<boolean | undefined>;
33
+ primary_email_auth_enabled: NonNullable<boolean | undefined>;
34
+ passkey_auth_enabled: NonNullable<boolean | undefined>;
35
+ otp_auth_enabled: NonNullable<boolean | undefined>;
33
36
  selected_team_id: string | null;
34
37
  selected_team: {
35
38
  client_metadata?: {} | null | undefined;
@@ -55,6 +58,7 @@ export declare const teamMemberProfilesCrudServerReadSchema: import("yup").Objec
55
58
  id: undefined;
56
59
  primary_email: undefined;
57
60
  primary_email_verified: undefined;
61
+ primary_email_auth_enabled: undefined;
58
62
  display_name: undefined;
59
63
  selected_team: {
60
64
  id: undefined;
@@ -69,6 +73,8 @@ export declare const teamMemberProfilesCrudServerReadSchema: import("yup").Objec
69
73
  profile_image_url: undefined;
70
74
  signed_up_at_millis: undefined;
71
75
  has_password: undefined;
76
+ otp_auth_enabled: undefined;
77
+ passkey_auth_enabled: undefined;
72
78
  client_metadata: undefined;
73
79
  client_read_only_metadata: undefined;
74
80
  server_metadata: undefined;
@@ -117,6 +123,9 @@ export declare const teamMemberProfilesCrud: import("../../crud").CrudSchemaFrom
117
123
  client_read_only_metadata: {} | null;
118
124
  server_metadata: {} | null;
119
125
  primary_email_verified: NonNullable<boolean | undefined>;
126
+ primary_email_auth_enabled: NonNullable<boolean | undefined>;
127
+ passkey_auth_enabled: NonNullable<boolean | undefined>;
128
+ otp_auth_enabled: NonNullable<boolean | undefined>;
120
129
  selected_team_id: string | null;
121
130
  selected_team: {
122
131
  client_metadata?: {} | null | undefined;
@@ -142,6 +151,7 @@ export declare const teamMemberProfilesCrud: import("../../crud").CrudSchemaFrom
142
151
  id: undefined;
143
152
  primary_email: undefined;
144
153
  primary_email_verified: undefined;
154
+ primary_email_auth_enabled: undefined;
145
155
  display_name: undefined;
146
156
  selected_team: {
147
157
  id: undefined;
@@ -156,6 +166,8 @@ export declare const teamMemberProfilesCrud: import("../../crud").CrudSchemaFrom
156
166
  profile_image_url: undefined;
157
167
  signed_up_at_millis: undefined;
158
168
  has_password: undefined;
169
+ otp_auth_enabled: undefined;
170
+ passkey_auth_enabled: undefined;
159
171
  client_metadata: undefined;
160
172
  client_read_only_metadata: undefined;
161
173
  server_metadata: undefined;
@@ -8,7 +8,9 @@ export declare const usersCrudServerUpdateSchema: import("yup").ObjectSchema<{
8
8
  primary_email: string | null | undefined;
9
9
  primary_email_verified: boolean | undefined;
10
10
  primary_email_auth_enabled: boolean | undefined;
11
+ passkey_auth_enabled: boolean | undefined;
11
12
  password: string | null | undefined;
13
+ otp_auth_enabled: boolean | undefined;
12
14
  totp_secret_base64: string | null | undefined;
13
15
  selected_team_id: string | null | undefined;
14
16
  }, import("yup").AnyObject, {
@@ -20,7 +22,9 @@ export declare const usersCrudServerUpdateSchema: import("yup").ObjectSchema<{
20
22
  primary_email: undefined;
21
23
  primary_email_verified: undefined;
22
24
  primary_email_auth_enabled: undefined;
25
+ passkey_auth_enabled: undefined;
23
26
  password: undefined;
27
+ otp_auth_enabled: undefined;
24
28
  totp_secret_base64: undefined;
25
29
  selected_team_id: undefined;
26
30
  }, "">;
@@ -28,6 +32,7 @@ export declare const usersCrudServerReadSchema: import("yup").ObjectSchema<{
28
32
  id: string;
29
33
  primary_email: string | null;
30
34
  primary_email_verified: NonNullable<boolean | undefined>;
35
+ primary_email_auth_enabled: NonNullable<boolean | undefined>;
31
36
  display_name: string | null;
32
37
  selected_team: {
33
38
  client_metadata?: {} | null | undefined;
@@ -42,6 +47,8 @@ export declare const usersCrudServerReadSchema: import("yup").ObjectSchema<{
42
47
  profile_image_url: string | null;
43
48
  signed_up_at_millis: number;
44
49
  has_password: NonNullable<boolean | undefined>;
50
+ otp_auth_enabled: NonNullable<boolean | undefined>;
51
+ passkey_auth_enabled: NonNullable<boolean | undefined>;
45
52
  client_metadata: {} | null;
46
53
  client_read_only_metadata: {} | null;
47
54
  server_metadata: {} | null;
@@ -57,6 +64,7 @@ export declare const usersCrudServerReadSchema: import("yup").ObjectSchema<{
57
64
  id: undefined;
58
65
  primary_email: undefined;
59
66
  primary_email_verified: undefined;
67
+ primary_email_auth_enabled: undefined;
60
68
  display_name: undefined;
61
69
  selected_team: {
62
70
  id: undefined;
@@ -71,6 +79,8 @@ export declare const usersCrudServerReadSchema: import("yup").ObjectSchema<{
71
79
  profile_image_url: undefined;
72
80
  signed_up_at_millis: undefined;
73
81
  has_password: undefined;
82
+ otp_auth_enabled: undefined;
83
+ passkey_auth_enabled: undefined;
74
84
  client_metadata: undefined;
75
85
  client_read_only_metadata: undefined;
76
86
  server_metadata: undefined;
@@ -89,6 +99,8 @@ export declare const usersCrudServerCreateSchema: import("yup").ObjectSchema<{
89
99
  server_metadata: {} | null | undefined;
90
100
  primary_email_verified: boolean | undefined;
91
101
  primary_email_auth_enabled: boolean | undefined;
102
+ passkey_auth_enabled: boolean | undefined;
103
+ otp_auth_enabled: boolean | undefined;
92
104
  totp_secret_base64: string | null | undefined;
93
105
  } & {
94
106
  oauth_providers: {
@@ -105,7 +117,9 @@ export declare const usersCrudServerCreateSchema: import("yup").ObjectSchema<{
105
117
  primary_email: undefined;
106
118
  primary_email_verified: undefined;
107
119
  primary_email_auth_enabled: undefined;
120
+ passkey_auth_enabled: undefined;
108
121
  password: undefined;
122
+ otp_auth_enabled: undefined;
109
123
  totp_secret_base64: undefined;
110
124
  selected_team_id: undefined;
111
125
  oauth_providers: undefined;
@@ -116,6 +130,7 @@ export declare const usersCrud: import("../../crud").CrudSchemaFromOptions<{
116
130
  id: string;
117
131
  primary_email: string | null;
118
132
  primary_email_verified: NonNullable<boolean | undefined>;
133
+ primary_email_auth_enabled: NonNullable<boolean | undefined>;
119
134
  display_name: string | null;
120
135
  selected_team: {
121
136
  client_metadata?: {} | null | undefined;
@@ -130,6 +145,8 @@ export declare const usersCrud: import("../../crud").CrudSchemaFromOptions<{
130
145
  profile_image_url: string | null;
131
146
  signed_up_at_millis: number;
132
147
  has_password: NonNullable<boolean | undefined>;
148
+ otp_auth_enabled: NonNullable<boolean | undefined>;
149
+ passkey_auth_enabled: NonNullable<boolean | undefined>;
133
150
  client_metadata: {} | null;
134
151
  client_read_only_metadata: {} | null;
135
152
  server_metadata: {} | null;
@@ -145,6 +162,7 @@ export declare const usersCrud: import("../../crud").CrudSchemaFromOptions<{
145
162
  id: undefined;
146
163
  primary_email: undefined;
147
164
  primary_email_verified: undefined;
165
+ primary_email_auth_enabled: undefined;
148
166
  display_name: undefined;
149
167
  selected_team: {
150
168
  id: undefined;
@@ -159,6 +177,8 @@ export declare const usersCrud: import("../../crud").CrudSchemaFromOptions<{
159
177
  profile_image_url: undefined;
160
178
  signed_up_at_millis: undefined;
161
179
  has_password: undefined;
180
+ otp_auth_enabled: undefined;
181
+ passkey_auth_enabled: undefined;
162
182
  client_metadata: undefined;
163
183
  client_read_only_metadata: undefined;
164
184
  server_metadata: undefined;
@@ -176,7 +196,9 @@ export declare const usersCrud: import("../../crud").CrudSchemaFromOptions<{
176
196
  primary_email: string | null | undefined;
177
197
  primary_email_verified: boolean | undefined;
178
198
  primary_email_auth_enabled: boolean | undefined;
199
+ passkey_auth_enabled: boolean | undefined;
179
200
  password: string | null | undefined;
201
+ otp_auth_enabled: boolean | undefined;
180
202
  totp_secret_base64: string | null | undefined;
181
203
  selected_team_id: string | null | undefined;
182
204
  }, import("yup").AnyObject, {
@@ -188,7 +210,9 @@ export declare const usersCrud: import("../../crud").CrudSchemaFromOptions<{
188
210
  primary_email: undefined;
189
211
  primary_email_verified: undefined;
190
212
  primary_email_auth_enabled: undefined;
213
+ passkey_auth_enabled: undefined;
191
214
  password: undefined;
215
+ otp_auth_enabled: undefined;
192
216
  totp_secret_base64: undefined;
193
217
  selected_team_id: undefined;
194
218
  }, "">;
@@ -202,6 +226,8 @@ export declare const usersCrud: import("../../crud").CrudSchemaFromOptions<{
202
226
  server_metadata: {} | null | undefined;
203
227
  primary_email_verified: boolean | undefined;
204
228
  primary_email_auth_enabled: boolean | undefined;
229
+ passkey_auth_enabled: boolean | undefined;
230
+ otp_auth_enabled: boolean | undefined;
205
231
  totp_secret_base64: string | null | undefined;
206
232
  } & {
207
233
  oauth_providers: {
@@ -218,7 +244,9 @@ export declare const usersCrud: import("../../crud").CrudSchemaFromOptions<{
218
244
  primary_email: undefined;
219
245
  primary_email_verified: undefined;
220
246
  primary_email_auth_enabled: undefined;
247
+ passkey_auth_enabled: undefined;
221
248
  password: undefined;
249
+ otp_auth_enabled: undefined;
222
250
  totp_secret_base64: undefined;
223
251
  selected_team_id: undefined;
224
252
  oauth_providers: undefined;
@@ -259,6 +287,7 @@ export declare const userCreatedWebhookEvent: {
259
287
  id: string;
260
288
  primary_email: string | null;
261
289
  primary_email_verified: NonNullable<boolean | undefined>;
290
+ primary_email_auth_enabled: NonNullable<boolean | undefined>;
262
291
  display_name: string | null;
263
292
  selected_team: {
264
293
  client_metadata?: {} | null | undefined;
@@ -273,6 +302,8 @@ export declare const userCreatedWebhookEvent: {
273
302
  profile_image_url: string | null;
274
303
  signed_up_at_millis: number;
275
304
  has_password: NonNullable<boolean | undefined>;
305
+ otp_auth_enabled: NonNullable<boolean | undefined>;
306
+ passkey_auth_enabled: NonNullable<boolean | undefined>;
276
307
  client_metadata: {} | null;
277
308
  client_read_only_metadata: {} | null;
278
309
  server_metadata: {} | null;
@@ -288,6 +319,7 @@ export declare const userCreatedWebhookEvent: {
288
319
  id: undefined;
289
320
  primary_email: undefined;
290
321
  primary_email_verified: undefined;
322
+ primary_email_auth_enabled: undefined;
291
323
  display_name: undefined;
292
324
  selected_team: {
293
325
  id: undefined;
@@ -302,6 +334,8 @@ export declare const userCreatedWebhookEvent: {
302
334
  profile_image_url: undefined;
303
335
  signed_up_at_millis: undefined;
304
336
  has_password: undefined;
337
+ otp_auth_enabled: undefined;
338
+ passkey_auth_enabled: undefined;
305
339
  client_metadata: undefined;
306
340
  client_read_only_metadata: undefined;
307
341
  server_metadata: undefined;
@@ -322,6 +356,7 @@ export declare const userUpdatedWebhookEvent: {
322
356
  id: string;
323
357
  primary_email: string | null;
324
358
  primary_email_verified: NonNullable<boolean | undefined>;
359
+ primary_email_auth_enabled: NonNullable<boolean | undefined>;
325
360
  display_name: string | null;
326
361
  selected_team: {
327
362
  client_metadata?: {} | null | undefined;
@@ -336,6 +371,8 @@ export declare const userUpdatedWebhookEvent: {
336
371
  profile_image_url: string | null;
337
372
  signed_up_at_millis: number;
338
373
  has_password: NonNullable<boolean | undefined>;
374
+ otp_auth_enabled: NonNullable<boolean | undefined>;
375
+ passkey_auth_enabled: NonNullable<boolean | undefined>;
339
376
  client_metadata: {} | null;
340
377
  client_read_only_metadata: {} | null;
341
378
  server_metadata: {} | null;
@@ -351,6 +388,7 @@ export declare const userUpdatedWebhookEvent: {
351
388
  id: undefined;
352
389
  primary_email: undefined;
353
390
  primary_email_verified: undefined;
391
+ primary_email_auth_enabled: undefined;
354
392
  display_name: undefined;
355
393
  selected_team: {
356
394
  id: undefined;
@@ -365,6 +403,8 @@ export declare const userUpdatedWebhookEvent: {
365
403
  profile_image_url: undefined;
366
404
  signed_up_at_millis: undefined;
367
405
  has_password: undefined;
406
+ otp_auth_enabled: undefined;
407
+ passkey_auth_enabled: undefined;
368
408
  client_metadata: undefined;
369
409
  client_read_only_metadata: undefined;
370
410
  server_metadata: undefined;
@@ -9,29 +9,26 @@ export const usersCrudServerUpdateSchema = fieldSchema.yupObject({
9
9
  server_metadata: fieldSchema.userServerMetadataSchema.optional(),
10
10
  primary_email: fieldSchema.primaryEmailSchema.nullable().optional(),
11
11
  primary_email_verified: fieldSchema.primaryEmailVerifiedSchema.optional(),
12
- 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 } }),
13
- password: fieldSchema.yupString().nullable().meta({ openapiField: { description: 'A new password for the user, overwriting the old one (if it exists). Specifying this option revokes all current sessions.', exampleValue: 'my-new-password' } }),
14
- 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=' } }),
12
+ primary_email_auth_enabled: fieldSchema.primaryEmailAuthEnabledSchema.optional(),
13
+ passkey_auth_enabled: fieldSchema.userOtpAuthEnabledSchema.optional(),
14
+ password: fieldSchema.userPasswordMutationSchema.optional(),
15
+ otp_auth_enabled: fieldSchema.userOtpAuthEnabledMutationSchema.optional(),
16
+ totp_secret_base64: fieldSchema.userTotpSecretMutationSchema.optional(),
15
17
  selected_team_id: fieldSchema.selectedTeamIdSchema.nullable().optional(),
16
18
  }).required();
17
- const contactChannelSchema = fieldSchema.yupObject({
18
- id: fieldSchema.yupString().required(),
19
- type: fieldSchema.yupString().required(),
20
- value: fieldSchema.yupString().required(),
21
- is_primary: fieldSchema.yupBoolean().required(),
22
- is_verified: fieldSchema.yupBoolean().required(),
23
- used_for_auth: fieldSchema.yupBoolean().required(),
24
- }).required();
25
19
  export const usersCrudServerReadSchema = fieldSchema.yupObject({
26
20
  id: fieldSchema.userIdSchema.required(),
27
21
  primary_email: fieldSchema.primaryEmailSchema.nullable().defined(),
28
22
  primary_email_verified: fieldSchema.primaryEmailVerifiedSchema.required(),
23
+ primary_email_auth_enabled: fieldSchema.primaryEmailAuthEnabledSchema.required(),
29
24
  display_name: fieldSchema.userDisplayNameSchema.nullable().defined(),
30
25
  selected_team: teamsCrudServerReadSchema.nullable().defined(),
31
26
  selected_team_id: fieldSchema.selectedTeamIdSchema.nullable().defined(),
32
27
  profile_image_url: fieldSchema.profileImageUrlSchema.nullable().defined(),
33
28
  signed_up_at_millis: fieldSchema.signedUpAtMillisSchema.required(),
34
- has_password: fieldSchema.yupBoolean().required().meta({ openapiField: { description: 'Whether the user has a password associated with their account', exampleValue: true } }),
29
+ has_password: fieldSchema.userHasPasswordSchema.required(),
30
+ otp_auth_enabled: fieldSchema.userOtpAuthEnabledSchema.required(),
31
+ passkey_auth_enabled: fieldSchema.userOtpAuthEnabledSchema.required(),
35
32
  client_metadata: fieldSchema.userClientMetadataSchema,
36
33
  client_read_only_metadata: fieldSchema.userClientReadOnlyMetadataSchema,
37
34
  server_metadata: fieldSchema.userServerMetadataSchema,
@@ -40,7 +37,7 @@ export const usersCrudServerReadSchema = fieldSchema.yupObject({
40
37
  id: fieldSchema.yupString().required(),
41
38
  account_id: fieldSchema.yupString().required(),
42
39
  email: fieldSchema.yupString().nullable(),
43
- }).required()).required().meta({ openapiField: { hidden: true, description: 'A list of OAuth providers connected to this account', exampleValue: [{ id: 'google', account_id: '12345', email: 'john.doe@gmail.com' }] } }),
40
+ }).required()).required().meta({ openapiField: { hidden: true } }),
44
41
  /**
45
42
  * @deprecated
46
43
  */
@@ -55,7 +52,7 @@ export const usersCrudServerCreateSchema = usersCrudServerUpdateSchema.omit(['se
55
52
  id: fieldSchema.yupString().required(),
56
53
  account_id: fieldSchema.yupString().required(),
57
54
  email: fieldSchema.yupString().nullable().defined().default(null),
58
- }).required()).optional(),
55
+ }).required()).optional().meta({ openapiField: { hidden: true } }),
59
56
  }).required());
60
57
  export const usersCrudServerDeleteSchema = fieldSchema.yupMixed();
61
58
  export const usersCrud = createCrud({
@@ -2,6 +2,7 @@ import { KnownErrors } from "../known-errors";
2
2
  import { AccessToken, InternalSession, RefreshToken } from "../sessions";
3
3
  import { Result } from "../utils/results";
4
4
  import { ClientInterfaceOptions, StackClientInterface } from "./clientInterface";
5
+ import { ContactChannelsCrud } from "./crud/contact-channels";
5
6
  import { CurrentUserCrud } from "./crud/current-user";
6
7
  import { ConnectedAccountAccessTokenCrud } from "./crud/oauth";
7
8
  import { TeamMemberProfilesCrud } from "./crud/team-member-profiles";
@@ -73,4 +74,9 @@ export declare class StackServerInterface extends StackClientInterface {
73
74
  grantServerTeamUserPermission(teamId: string, userId: string, permissionId: string): Promise<void>;
74
75
  revokeServerTeamUserPermission(teamId: string, userId: string, permissionId: string): Promise<void>;
75
76
  deleteServerServerUser(userId: string): Promise<void>;
77
+ createServerContactChannel(data: ContactChannelsCrud['Server']['Create']): Promise<ContactChannelsCrud['Server']['Read']>;
78
+ updateServerContactChannel(userId: string, contactChannelId: string, data: ContactChannelsCrud['Server']['Update']): Promise<ContactChannelsCrud['Server']['Read']>;
79
+ deleteServerContactChannel(userId: string, contactChannelId: string): Promise<void>;
80
+ listServerContactChannels(userId: string): Promise<ContactChannelsCrud['Server']['Read'][]>;
81
+ sendServerContactChannelVerificationEmail(userId: string, contactChannelId: string, callbackUrl: string): Promise<Result<undefined, KnownErrors["EmailAlreadyVerified"]>>;
76
82
  }
@@ -214,4 +214,49 @@ export class StackServerInterface extends StackClientInterface {
214
214
  body: JSON.stringify({}),
215
215
  }, null);
216
216
  }
217
+ async createServerContactChannel(data) {
218
+ const response = await this.sendServerRequest("/contact-channels", {
219
+ method: "POST",
220
+ headers: {
221
+ "content-type": "application/json",
222
+ },
223
+ body: JSON.stringify(data),
224
+ }, null);
225
+ return await response.json();
226
+ }
227
+ async updateServerContactChannel(userId, contactChannelId, data) {
228
+ const response = await this.sendServerRequest(`/contact-channels/${userId}/${contactChannelId}`, {
229
+ method: "PATCH",
230
+ headers: {
231
+ "content-type": "application/json",
232
+ },
233
+ body: JSON.stringify(data),
234
+ }, null);
235
+ return await response.json();
236
+ }
237
+ async deleteServerContactChannel(userId, contactChannelId) {
238
+ await this.sendServerRequest(`/contact-channels/${userId}/${contactChannelId}`, {
239
+ method: "DELETE",
240
+ }, null);
241
+ }
242
+ async listServerContactChannels(userId) {
243
+ const response = await this.sendServerRequest(`/contact-channels?user_id=${userId}`, {
244
+ method: "GET",
245
+ }, null);
246
+ const json = await response.json();
247
+ return json.items;
248
+ }
249
+ async sendServerContactChannelVerificationEmail(userId, contactChannelId, callbackUrl) {
250
+ const responseOrError = await this.sendServerRequestAndCatchKnownError(`/contact-channels/${userId}/${contactChannelId}/send-verification-code`, {
251
+ method: "POST",
252
+ headers: {
253
+ "content-type": "application/json",
254
+ },
255
+ body: JSON.stringify({ callback_url: callbackUrl }),
256
+ }, null, [KnownErrors.EmailAlreadyVerified]);
257
+ if (responseOrError.status === "error") {
258
+ return Result.error(responseOrError.error);
259
+ }
260
+ return Result.ok(undefined);
261
+ }
217
262
  }
@@ -14,6 +14,7 @@ export declare const webhookEvents: readonly [{
14
14
  id: string;
15
15
  primary_email: string | null;
16
16
  primary_email_verified: NonNullable<boolean | undefined>;
17
+ primary_email_auth_enabled: NonNullable<boolean | undefined>;
17
18
  display_name: string | null;
18
19
  selected_team: {
19
20
  client_metadata?: {} | null | undefined;
@@ -28,6 +29,8 @@ export declare const webhookEvents: readonly [{
28
29
  profile_image_url: string | null;
29
30
  signed_up_at_millis: number;
30
31
  has_password: NonNullable<boolean | undefined>;
32
+ otp_auth_enabled: NonNullable<boolean | undefined>;
33
+ passkey_auth_enabled: NonNullable<boolean | undefined>;
31
34
  client_metadata: {} | null;
32
35
  client_read_only_metadata: {} | null;
33
36
  server_metadata: {} | null;
@@ -43,6 +46,7 @@ export declare const webhookEvents: readonly [{
43
46
  id: undefined;
44
47
  primary_email: undefined;
45
48
  primary_email_verified: undefined;
49
+ primary_email_auth_enabled: undefined;
46
50
  display_name: undefined;
47
51
  selected_team: {
48
52
  id: undefined;
@@ -57,6 +61,8 @@ export declare const webhookEvents: readonly [{
57
61
  profile_image_url: undefined;
58
62
  signed_up_at_millis: undefined;
59
63
  has_password: undefined;
64
+ otp_auth_enabled: undefined;
65
+ passkey_auth_enabled: undefined;
60
66
  client_metadata: undefined;
61
67
  client_read_only_metadata: undefined;
62
68
  server_metadata: undefined;
@@ -76,6 +82,7 @@ export declare const webhookEvents: readonly [{
76
82
  id: string;
77
83
  primary_email: string | null;
78
84
  primary_email_verified: NonNullable<boolean | undefined>;
85
+ primary_email_auth_enabled: NonNullable<boolean | undefined>;
79
86
  display_name: string | null;
80
87
  selected_team: {
81
88
  client_metadata?: {} | null | undefined;
@@ -90,6 +97,8 @@ export declare const webhookEvents: readonly [{
90
97
  profile_image_url: string | null;
91
98
  signed_up_at_millis: number;
92
99
  has_password: NonNullable<boolean | undefined>;
100
+ otp_auth_enabled: NonNullable<boolean | undefined>;
101
+ passkey_auth_enabled: NonNullable<boolean | undefined>;
93
102
  client_metadata: {} | null;
94
103
  client_read_only_metadata: {} | null;
95
104
  server_metadata: {} | null;
@@ -105,6 +114,7 @@ export declare const webhookEvents: readonly [{
105
114
  id: undefined;
106
115
  primary_email: undefined;
107
116
  primary_email_verified: undefined;
117
+ primary_email_auth_enabled: undefined;
108
118
  display_name: undefined;
109
119
  selected_team: {
110
120
  id: undefined;
@@ -119,6 +129,8 @@ export declare const webhookEvents: readonly [{
119
129
  profile_image_url: undefined;
120
130
  signed_up_at_millis: undefined;
121
131
  has_password: undefined;
132
+ otp_auth_enabled: undefined;
133
+ passkey_auth_enabled: undefined;
122
134
  client_metadata: undefined;
123
135
  client_read_only_metadata: undefined;
124
136
  server_metadata: undefined;
@@ -251,6 +251,9 @@ export declare const KnownErrors: {
251
251
  PasswordAuthenticationNotEnabled: KnownErrorConstructor<KnownError & KnownErrorBrand<"PASSWORD_AUTHENTICATION_NOT_ENABLED">, []> & {
252
252
  errorCode: "PASSWORD_AUTHENTICATION_NOT_ENABLED";
253
253
  };
254
+ PasskeyAuthenticationNotEnabled: KnownErrorConstructor<KnownError & KnownErrorBrand<"PASSKEY_AUTHENTICATION_NOT_ENABLED">, []> & {
255
+ errorCode: "PASSKEY_AUTHENTICATION_NOT_ENABLED";
256
+ };
254
257
  EmailPasswordMismatch: KnownErrorConstructor<KnownError & KnownErrorBrand<"EMAIL_PASSWORD_MISMATCH">, []> & {
255
258
  errorCode: "EMAIL_PASSWORD_MISMATCH";
256
259
  };
@@ -308,6 +311,15 @@ export declare const KnownErrors: {
308
311
  EmailIsNotPrimaryEmail: KnownErrorConstructor<KnownError & KnownErrorBrand<"EMAIL_IS_NOT_PRIMARY_EMAIL">, [email: string, primaryEmail: string | null]> & {
309
312
  errorCode: "EMAIL_IS_NOT_PRIMARY_EMAIL";
310
313
  };
314
+ PasskeyRegistrationFailed: KnownErrorConstructor<KnownError & KnownErrorBrand<"PASSKEY_REGISTRATION_FAILED">, [message: string]> & {
315
+ errorCode: "PASSKEY_REGISTRATION_FAILED";
316
+ };
317
+ PasskeyWebAuthnError: KnownErrorConstructor<KnownError & KnownErrorBrand<"PASSKEY_WEBAUTHN_ERROR">, [message: string, code: string]> & {
318
+ errorCode: "PASSKEY_WEBAUTHN_ERROR";
319
+ };
320
+ PasskeyAuthenticationFailed: KnownErrorConstructor<KnownError & KnownErrorBrand<"PASSKEY_AUTHENTICATION_FAILED">, [message: string]> & {
321
+ errorCode: "PASSKEY_AUTHENTICATION_FAILED";
322
+ };
311
323
  PermissionNotFound: KnownErrorConstructor<KnownError & KnownErrorBrand<"PERMISSION_NOT_FOUND">, [permissionId: string]> & {
312
324
  errorCode: "PERMISSION_NOT_FOUND";
313
325
  };
@@ -328,6 +328,10 @@ const PasswordAuthenticationNotEnabled = createKnownErrorConstructor(KnownError,
328
328
  400,
329
329
  "Password authentication is not enabled for this project.",
330
330
  ], () => []);
331
+ const PasskeyAuthenticationNotEnabled = createKnownErrorConstructor(KnownError, "PASSKEY_AUTHENTICATION_NOT_ENABLED", () => [
332
+ 400,
333
+ "Passkey authentication is not enabled for this project.",
334
+ ], () => []);
331
335
  const EmailPasswordMismatch = createKnownErrorConstructor(KnownError, "EMAIL_PASSWORD_MISMATCH", () => [
332
336
  400,
333
337
  "Wrong e-mail or password.",
@@ -396,6 +400,22 @@ const EmailIsNotPrimaryEmail = createKnownErrorConstructor(KnownError, "EMAIL_IS
396
400
  primary_email: primaryEmail,
397
401
  },
398
402
  ], (json) => [json.email, json.primary_email]);
403
+ const PasskeyRegistrationFailed = createKnownErrorConstructor(KnownError, "PASSKEY_REGISTRATION_FAILED", (message) => [
404
+ 400,
405
+ message,
406
+ ], (json) => [json.message]);
407
+ const PasskeyWebAuthnError = createKnownErrorConstructor(KnownError, "PASSKEY_WEBAUTHN_ERROR", (message, code) => [
408
+ 400,
409
+ message,
410
+ {
411
+ message,
412
+ code,
413
+ },
414
+ ], (json) => [json.message, json.code]);
415
+ const PasskeyAuthenticationFailed = createKnownErrorConstructor(KnownError, "PASSKEY_AUTHENTICATION_FAILED", (message) => [
416
+ 400,
417
+ message,
418
+ ], (json) => [json.message]);
399
419
  const PermissionNotFound = createKnownErrorConstructor(KnownError, "PERMISSION_NOT_FOUND", (permissionId) => [
400
420
  404,
401
421
  `Permission "${permissionId}" not found. Make sure you created it on the dashboard.`,
@@ -586,6 +606,7 @@ export const KnownErrors = {
586
606
  ProjectNotFound,
587
607
  SignUpNotEnabled,
588
608
  PasswordAuthenticationNotEnabled,
609
+ PasskeyAuthenticationNotEnabled,
589
610
  EmailPasswordMismatch,
590
611
  RedirectUrlNotWhitelisted,
591
612
  PasswordRequirementsNotMet,
@@ -601,6 +622,9 @@ export const KnownErrors = {
601
622
  EmailAlreadyVerified,
602
623
  EmailNotAssociatedWithUser,
603
624
  EmailIsNotPrimaryEmail,
625
+ PasskeyRegistrationFailed,
626
+ PasskeyWebAuthnError,
627
+ PasskeyAuthenticationFailed,
604
628
  PermissionNotFound,
605
629
  ContainedPermissionNotFound,
606
630
  TeamNotFound,
@@ -39,6 +39,7 @@ export declare const projectConfigIdSchema: yup.StringSchema<string | undefined,
39
39
  export declare const projectAllowLocalhostSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
40
40
  export declare const projectCreateTeamOnSignUpSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
41
41
  export declare const projectMagicLinkEnabledSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
42
+ export declare const projectPasskeyEnabledSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
42
43
  export declare const projectClientTeamCreationEnabledSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
43
44
  export declare const projectClientUserDeletionEnabledSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
44
45
  export declare const projectSignUpEnabledSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
@@ -64,6 +65,7 @@ export declare class ReplaceFieldWithOwnUserId extends Error {
64
65
  export declare const userIdOrMeSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
65
66
  export declare const userIdSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
66
67
  export declare const primaryEmailSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
68
+ export declare const primaryEmailAuthEnabledSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
67
69
  export declare const primaryEmailVerifiedSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
68
70
  export declare const userDisplayNameSchema: yup.StringSchema<string | null | undefined, yup.AnyObject, undefined, "">;
69
71
  export declare const selectedTeamIdSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
@@ -82,6 +84,12 @@ export declare const userOAuthProviderSchema: yup.ObjectSchema<{
82
84
  provider_user_id: undefined;
83
85
  }, "">;
84
86
  export declare const userLastActiveAtMillisSchema: yup.NumberSchema<number | null | undefined, yup.AnyObject, undefined, "">;
87
+ export declare const userPasskeyAuthEnabledSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
88
+ export declare const userOtpAuthEnabledSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
89
+ export declare const userOtpAuthEnabledMutationSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
90
+ export declare const userHasPasswordSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
91
+ export declare const userPasswordMutationSchema: yup.StringSchema<string | null | undefined, yup.AnyObject, undefined, "">;
92
+ export declare const userTotpSecretMutationSchema: yup.StringSchema<string | null | undefined, yup.AnyObject, undefined, "">;
85
93
  export declare const signInEmailSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
86
94
  export declare const emailOtpSignInCallbackUrlSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
87
95
  export declare const emailVerificationCallbackUrlSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
@@ -203,6 +203,7 @@ export const projectConfigIdSchema = yupString().meta({ openapiField: { descript
203
203
  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 } });
204
204
  export const projectCreateTeamOnSignUpSchema = yupBoolean().meta({ openapiField: { description: 'Whether a team should be created for each user that signs up', exampleValue: true } });
205
205
  export const projectMagicLinkEnabledSchema = yupBoolean().meta({ openapiField: { description: 'Whether magic link authentication is enabled for this project', exampleValue: true } });
206
+ export const projectPasskeyEnabledSchema = yupBoolean().meta({ openapiField: { description: 'Whether passkey authentication is enabled for this project', exampleValue: true } });
206
207
  export const projectClientTeamCreationEnabledSchema = yupBoolean().meta({ openapiField: { description: 'Whether client users can create teams', exampleValue: true } });
207
208
  export const projectClientUserDeletionEnabledSchema = yupBoolean().meta({ openapiField: { description: 'Whether client users can delete their own account from the client', exampleValue: true } });
208
209
  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 } });
@@ -248,6 +249,7 @@ export const userIdOrMeSchema = yupString().uuid().transform(v => {
248
249
  }).meta({ openapiField: { description: 'The ID of the user, or the special value `me` for the currently authenticated user', exampleValue: '3241a285-8329-4d69-8f3d-316e08cf140c' } });
249
250
  export const userIdSchema = yupString().uuid().meta({ openapiField: { description: _idDescription('user'), exampleValue: '3241a285-8329-4d69-8f3d-316e08cf140c' } });
250
251
  export const primaryEmailSchema = emailSchema.meta({ openapiField: { description: 'Primary email', exampleValue: 'johndoe@example.com' } });
252
+ export const primaryEmailAuthEnabledSchema = yupBoolean().meta({ openapiField: { description: 'Whether the primary email is used for authentication. If this is set to `false`, the user will not be able to sign in with the primary email with password or OTP', exampleValue: true } });
251
253
  export const primaryEmailVerifiedSchema = yupBoolean().meta({ openapiField: { description: 'Whether the primary email has been verified to belong to this user', exampleValue: true } });
252
254
  export const userDisplayNameSchema = yupString().nullable().meta({ openapiField: { description: _displayNameDescription('user'), exampleValue: 'John Doe' } });
253
255
  export const selectedTeamIdSchema = yupString().uuid().meta({ openapiField: { description: 'ID of the team currently selected by the user', exampleValue: 'team-id' } });
@@ -262,6 +264,12 @@ export const userOAuthProviderSchema = yupObject({
262
264
  provider_user_id: yupString().required(),
263
265
  });
264
266
  export const userLastActiveAtMillisSchema = yupNumber().nullable().meta({ openapiField: { description: _lastActiveAtMillisDescription, exampleValue: 1630000000000 } });
267
+ export const userPasskeyAuthEnabledSchema = yupBoolean().meta({ openapiField: { hidden: true, description: 'Whether the user has passkeys enabled', exampleValue: false } });
268
+ export const userOtpAuthEnabledSchema = yupBoolean().meta({ openapiField: { hidden: true, description: 'Whether the user has OTP/magic link enabled. ', exampleValue: true } });
269
+ export const userOtpAuthEnabledMutationSchema = yupBoolean().meta({ openapiField: { hidden: true, description: 'Whether the user has OTP/magic link enabled. Note that only accounts with verified emails can sign-in with OTP.', exampleValue: true } });
270
+ export const userHasPasswordSchema = yupBoolean().meta({ openapiField: { hidden: true, description: 'Whether the user has a password set. If the user does not have a password set, they will not be able to sign in with email/password.', exampleValue: true } });
271
+ export const userPasswordMutationSchema = yupString().nullable().meta({ openapiField: { description: 'Sets the user\'s password. Doing so revokes all current sessions.', exampleValue: 'my-new-password' } });
272
+ export const userTotpSecretMutationSchema = base64Schema.nullable().meta({ openapiField: { description: 'Enables 2FA and sets a TOTP secret for the user. Set to null to disable 2FA.', exampleValue: 'dG90cC1zZWNyZXQ=' } });
265
273
  // Auth
266
274
  export const signInEmailSchema = emailSchema.meta({ openapiField: { description: 'The email to sign in with.', exampleValue: 'johndoe@example.com' } });
267
275
  export const emailOtpSignInCallbackUrlSchema = urlSchema.meta({ openapiField: { description: 'The base callback URL to construct the magic link from. A query parameter `code` with the verification code will be appended to it. The page should then make a request to the `/auth/otp/sign-in` endpoint.', exampleValue: 'https://example.com/handler/magic-link-callback' } });
@@ -0,0 +1 @@
1
+ export type { AuthenticationResponseJSON, RegistrationResponseJSON, PublicKeyCredentialCreationOptionsJSON, PublicKeyCredentialRequestOptionsJSON, AuthenticatorAttestationResponseJSON } from "@simplewebauthn/types";
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackframe/stack-shared",
3
- "version": "2.6.11",
3
+ "version": "2.6.15",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "files": [
@@ -32,15 +32,17 @@
32
32
  }
33
33
  },
34
34
  "dependencies": {
35
+ "@simplewebauthn/browser": "^11.0.0",
35
36
  "bcrypt": "^5.1.1",
36
37
  "elliptic": "^6.5.7",
37
38
  "jose": "^5.2.2",
38
39
  "oauth4webapi": "^2.10.3",
39
40
  "semver": "^7.6.3",
40
41
  "uuid": "^9.0.1",
41
- "@stackframe/stack-sc": "2.6.11"
42
+ "@stackframe/stack-sc": "2.6.15"
42
43
  },
43
44
  "devDependencies": {
45
+ "@simplewebauthn/types": "^11.0.0",
44
46
  "@types/bcrypt": "^5.0.2",
45
47
  "@types/elliptic": "^6.4.18",
46
48
  "@types/react": "^18.2.66",