@@ -30,7 +30,7 @@ import type {
3030 SignInIdentifier ,
3131 SignInJSON ,
3232 SignInJSONSnapshot ,
33- SignInBetaResource ,
33+ SignInFutureResource ,
3434 SignInResource ,
3535 SignInSecondFactor ,
3636 SignInStartEmailLinkFlowParams ,
@@ -39,6 +39,7 @@ import type {
3939 Web3Provider ,
4040 Web3SignatureConfig ,
4141 Web3SignatureFactor ,
42+ OAuthStrategy ,
4243} from '@clerk/types' ;
4344
4445import {
@@ -84,7 +85,7 @@ export class SignIn extends BaseResource implements SignInResource {
8485 createdSessionId : string | null = null ;
8586 userData : UserData = new UserData ( null ) ;
8687
87- __internal_beta : SignInBeta | null = new SignInBeta ( this ) ;
88+ __internal_beta : SignInFuture | null = new SignInFuture ( this ) ;
8889 __internal_basePost ;
8990
9091 constructor ( data : SignInJSON | SignInJSONSnapshot | null = null ) {
@@ -459,7 +460,7 @@ export class SignIn extends BaseResource implements SignInResource {
459460 this . userData = new UserData ( data . user_data ) ;
460461 }
461462
462- eventBus . emit ( 'signin :update' , { resource : this } ) ;
463+ eventBus . emit ( 'resource :update' , { resource : this } ) ;
463464 return this ;
464465 }
465466
@@ -480,22 +481,128 @@ export class SignIn extends BaseResource implements SignInResource {
480481 }
481482}
482483
483- class SignInBeta implements SignInBetaResource {
484+ class SignInFuture implements SignInFutureResource {
485+ emailCode = {
486+ sendCode : this . sendEmailCode . bind ( this ) ,
487+ verifyCode : this . verifyEmailCode . bind ( this ) ,
488+ } ;
489+
484490 constructor ( readonly resource : SignIn ) { }
485491
486492 get status ( ) {
487493 return this . resource . status ;
488494 }
489495
496+ async create ( params : {
497+ identifier ?: string ;
498+ strategy ?: OAuthStrategy | 'saml' | 'enterprise_sso' ;
499+ redirectUrl ?: string ;
500+ actionCompleteRedirectUrl ?: string ;
501+ } ) : Promise < { error : unknown } > {
502+ eventBus . emit ( 'resource:error' , { resource : this . resource , error : null } ) ;
503+ try {
504+ await this . resource . __internal_basePost ( {
505+ path : this . resource . pathRoot ,
506+ body : params ,
507+ } ) ;
508+
509+ return { error : null } ;
510+ } catch ( err ) {
511+ eventBus . emit ( 'resource:error' , { resource : this . resource , error : err } ) ;
512+ return { error : err } ;
513+ }
514+ }
515+
490516 async password ( { identifier, password } : { identifier : string ; password : string } ) : Promise < { error : unknown } > {
491- eventBus . emit ( 'signin :error' , null ) ;
517+ eventBus . emit ( 'resource :error' , { resource : this . resource , error : null } ) ;
492518 try {
493519 await this . resource . __internal_basePost ( {
494520 path : this . resource . pathRoot ,
495521 body : { identifier, password } ,
496522 } ) ;
497523 } catch ( err ) {
498- eventBus . emit ( 'signin:error' , err ) ;
524+ eventBus . emit ( 'resource:error' , { resource : this . resource , error : err } ) ;
525+ return { error : err } ;
526+ }
527+
528+ return { error : null } ;
529+ }
530+
531+ async sendEmailCode ( { email } : { email : string } ) : Promise < { error : unknown } > {
532+ eventBus . emit ( 'resource:error' , { resource : this . resource , error : null } ) ;
533+ try {
534+ if ( ! this . resource . id ) {
535+ await this . create ( { identifier : email } ) ;
536+ }
537+
538+ const emailCodeFactor = this . resource . supportedFirstFactors ?. find ( f => f . strategy === 'email_code' ) ;
539+
540+ if ( ! emailCodeFactor ) {
541+ throw new Error ( 'Email code factor not found' ) ;
542+ }
543+
544+ const { emailAddressId } = emailCodeFactor ;
545+ await this . resource . __internal_basePost ( {
546+ body : { emailAddressId, strategy : 'email_code' } ,
547+ action : 'prepare_first_factor' ,
548+ } ) ;
549+ } catch ( err : unknown ) {
550+ eventBus . emit ( 'resource:error' , { resource : this . resource , error : err } ) ;
551+ return { error : err } ;
552+ }
553+
554+ return { error : null } ;
555+ }
556+
557+ async verifyEmailCode ( { code } : { code : string } ) : Promise < { error : unknown } > {
558+ eventBus . emit ( 'resource:error' , { resource : this . resource , error : null } ) ;
559+ try {
560+ await this . resource . __internal_basePost ( {
561+ body : { code, strategy : 'email_code' } ,
562+ action : 'attempt_first_factor' ,
563+ } ) ;
564+ } catch ( err : unknown ) {
565+ eventBus . emit ( 'resource:error' , { resource : this . resource , error : err } ) ;
566+ return { error : err } ;
567+ }
568+
569+ return { error : null } ;
570+ }
571+
572+ async sso ( {
573+ flow = 'auto' ,
574+ strategy,
575+ redirectUrl,
576+ redirectUrlComplete,
577+ } : {
578+ flow ?: 'auto' | 'modal' ;
579+ strategy : OAuthStrategy | 'saml' | 'enterprise_sso' ;
580+ redirectUrl : string ;
581+ redirectUrlComplete : string ;
582+ } ) : Promise < { error : unknown } > {
583+ eventBus . emit ( 'resource:error' , { resource : this . resource , error : null } ) ;
584+ try {
585+ if ( flow !== 'auto' ) {
586+ throw new Error ( 'modal flow is not supported yet' ) ;
587+ }
588+
589+ const redirectUrlWithAuthToken = SignIn . clerk . buildUrlWithAuth ( redirectUrl ) ;
590+
591+ if ( ! this . resource . id ) {
592+ await this . create ( {
593+ strategy,
594+ redirectUrl : redirectUrlWithAuthToken ,
595+ actionCompleteRedirectUrl : redirectUrlComplete ,
596+ } ) ;
597+ }
598+
599+ const { status, externalVerificationRedirectURL } = this . resource . firstFactorVerification ;
600+
601+ if ( status === 'unverified' && externalVerificationRedirectURL ) {
602+ windowNavigate ( externalVerificationRedirectURL ) ;
603+ }
604+ } catch ( err : unknown ) {
605+ eventBus . emit ( 'resource:error' , { resource : this . resource , error : err } ) ;
499606 return { error : err } ;
500607 }
501608
0 commit comments