@@ -174,7 +174,7 @@ export default function getAPIImplementation(): APIInterface {
174174 // here to be on the safe side.
175175 if ( ! email ) {
176176 throw new Error (
177- "Should never come here since we already check that the email value is a string in validateEmailAddress"
177+ "Should never come here since we already check that the email value is a string in validateEmailAddress" ,
178178 ) ;
179179 }
180180
@@ -208,7 +208,7 @@ export default function getAPIImplementation(): APIInterface {
208208
209209 if (
210210 conflictingUsers . some ( ( u ) =>
211- u . loginMethods . some ( ( lm ) => lm . recipeId === "webauthn" && lm . hasSameEmailAs ( email ) )
211+ u . loginMethods . some ( ( lm ) => lm . recipeId === "webauthn" && lm . hasSameEmailAs ( email ) ) ,
212212 )
213213 ) {
214214 return {
@@ -355,7 +355,7 @@ export default function getAPIImplementation(): APIInterface {
355355
356356 // we find the email of the user that has the same credentialId as the one we are verifying
357357 const email = authenticatingUser . user . loginMethods . find (
358- ( lm ) => lm . recipeId === "webauthn" && lm . webauthn ?. credentialIds . includes ( credential . id )
358+ ( lm ) => lm . recipeId === "webauthn" && lm . webauthn ?. credentialIds . includes ( credential . id ) ,
359359 ) ?. email ;
360360 if ( email === undefined ) {
361361 throw new Error ( "This should never happen: webauthn user has no email" ) ;
@@ -472,14 +472,14 @@ export default function getAPIImplementation(): APIInterface {
472472 // in validation but kept here to be safe.
473473 if ( typeof email !== "string" ) {
474474 throw new Error (
475- "Should never come here since we already check that the email value is a string in validateFormFieldsOrThrowError"
475+ "Should never come here since we already check that the email value is a string in validateFormFieldsOrThrowError" ,
476476 ) ;
477477 }
478478
479479 // this function will be reused in different parts of the flow below..
480480 async function generateAndSendRecoverAccountToken (
481481 primaryUserId : string ,
482- recipeUserId : RecipeUserId | undefined
482+ recipeUserId : RecipeUserId | undefined ,
483483 ) : Promise < {
484484 status : "OK" ;
485485 } > {
@@ -495,7 +495,7 @@ export default function getAPIImplementation(): APIInterface {
495495 logDebugMessage (
496496 `Recover account email not sent, unknown user id: ${
497497 recipeUserId === undefined ? primaryUserId : recipeUserId . getAsString ( )
498- } `
498+ } `,
499499 ) ;
500500 return {
501501 status : "OK" ,
@@ -543,7 +543,7 @@ export default function getAPIImplementation(): APIInterface {
543543 let webauthnAccount : RecipeLevelUser | undefined = undefined ;
544544 for ( let i = 0 ; i < users . length ; i ++ ) {
545545 const webauthnAccountTmp = users [ i ] . loginMethods . find (
546- ( l ) => l . recipeId === "webauthn" && l . hasSameEmailAs ( email )
546+ ( l ) => l . recipeId === "webauthn" && l . hasSameEmailAs ( email ) ,
547547 ) ;
548548 if ( webauthnAccountTmp !== undefined ) {
549549 webauthnAccount = webauthnAccountTmp ;
@@ -565,7 +565,7 @@ export default function getAPIImplementation(): APIInterface {
565565 }
566566 return await generateAndSendRecoverAccountToken (
567567 webauthnAccount . recipeUserId . getAsString ( ) ,
568- webauthnAccount . recipeUserId
568+ webauthnAccount . recipeUserId ,
569569 ) ;
570570 }
571571
@@ -607,7 +607,7 @@ export default function getAPIImplementation(): APIInterface {
607607 primaryUserAssociatedWithEmail ,
608608 undefined ,
609609 tenantId ,
610- userContext
610+ userContext ,
611611 ) ;
612612
613613 // Now we need to check that if there exists any webauthn user at all
@@ -625,7 +625,7 @@ export default function getAPIImplementation(): APIInterface {
625625 // not generate a recover account reset token
626626 if ( ! shouldDoAccountLinkingResponse . shouldAutomaticallyLink ) {
627627 logDebugMessage (
628- `Recover account email not sent, since webauthn user didn't exist, and account linking not enabled`
628+ `Recover account email not sent, since webauthn user didn't exist, and account linking not enabled` ,
629629 ) ;
630630 return {
631631 status : "OK" ,
@@ -649,7 +649,7 @@ export default function getAPIImplementation(): APIInterface {
649649 return await generateAndSendRecoverAccountToken ( primaryUserAssociatedWithEmail . id , undefined ) ;
650650 } else {
651651 logDebugMessage (
652- `Recover account email not sent, isSignUpAllowed returned false for email: ${ email } `
652+ `Recover account email not sent, isSignUpAllowed returned false for email: ${ email } ` ,
653653 ) ;
654654 return {
655655 status : "OK" ,
@@ -669,7 +669,7 @@ export default function getAPIImplementation(): APIInterface {
669669 if ( areTheTwoAccountsLinked ) {
670670 return await generateAndSendRecoverAccountToken (
671671 primaryUserAssociatedWithEmail . id ,
672- webauthnAccount . recipeUserId
672+ webauthnAccount . recipeUserId ,
673673 ) ;
674674 }
675675
@@ -699,7 +699,7 @@ export default function getAPIImplementation(): APIInterface {
699699 // so no need to check for anything
700700 return await generateAndSendRecoverAccountToken (
701701 webauthnAccount . recipeUserId . getAsString ( ) ,
702- webauthnAccount . recipeUserId
702+ webauthnAccount . recipeUserId ,
703703 ) ;
704704 }
705705
@@ -708,13 +708,13 @@ export default function getAPIImplementation(): APIInterface {
708708 // does not care about that, then we should just continue with token generation
709709 return await generateAndSendRecoverAccountToken (
710710 primaryUserAssociatedWithEmail . id ,
711- webauthnAccount . recipeUserId
711+ webauthnAccount . recipeUserId ,
712712 ) ;
713713 }
714714
715715 return await generateAndSendRecoverAccountToken (
716716 primaryUserAssociatedWithEmail . id ,
717- webauthnAccount . recipeUserId
717+ webauthnAccount . recipeUserId ,
718718 ) ;
719719 } ,
720720
@@ -751,7 +751,7 @@ export default function getAPIImplementation(): APIInterface {
751751 }
752752
753753 async function doRegisterCredentialAndVerifyEmailAndTryLinkIfNotPrimary (
754- recipeUserId : RecipeUserId
754+ recipeUserId : RecipeUserId ,
755755 ) : Promise <
756756 | {
757757 status : "OK" ;
@@ -891,7 +891,7 @@ export default function getAPIImplementation(): APIInterface {
891891
892892 if ( webauthnUserIsLinkedToExistingUser ) {
893893 return doRegisterCredentialAndVerifyEmailAndTryLinkIfNotPrimary (
894- new RecipeUserId ( userIdForWhomTokenWasGenerated )
894+ new RecipeUserId ( userIdForWhomTokenWasGenerated ) ,
895895 ) ;
896896 } else {
897897 // this means that the existingUser does not have an webauthn user associated
@@ -937,7 +937,7 @@ export default function getAPIImplementation(): APIInterface {
937937 // as verified.
938938 await markEmailAsVerified (
939939 createUserResponse . user . loginMethods [ 0 ] . recipeUserId ,
940- tokenConsumptionResponse . email
940+ tokenConsumptionResponse . email ,
941941 ) ;
942942 const updatedUser = await getUser ( createUserResponse . user . id , userContext ) ;
943943 if ( updatedUser === undefined ) {
@@ -978,11 +978,31 @@ export default function getAPIImplementation(): APIInterface {
978978 // Linking to an existing account will be done after the user goes through the email
979979 // verification flow once they log in (if applicable).
980980 return doRegisterCredentialAndVerifyEmailAndTryLinkIfNotPrimary (
981- new RecipeUserId ( userIdForWhomTokenWasGenerated )
981+ new RecipeUserId ( userIdForWhomTokenWasGenerated ) ,
982982 ) ;
983983 }
984984 } ,
985985
986+ listCredentialsGET : async function ( { options, userContext, session } ) {
987+ const credentials = await options . recipeImplementation . listCredentials ( {
988+ recipeUserId : session . getRecipeUserId ( ) . getAsString ( ) ,
989+ userContext,
990+ } ) ;
991+ if ( credentials . status !== "OK" ) {
992+ // TODO BETTER ERROR HANDLING
993+ return { status : "GENERAL_ERROR" , message : "Internal server error" } ;
994+ }
995+
996+ return {
997+ status : "OK" ,
998+ credentials : credentials . credentials . map ( ( credential ) => ( {
999+ webauthnCredentialId : credential . webauthnCredentialId ,
1000+ relyingPartyId : credential . relyingPartyId ,
1001+ createdAt : credential . createdAt ,
1002+ } ) ) ,
1003+ } ;
1004+ } ,
1005+
9861006 registerCredentialPOST : async function ( {
9871007 webauthnGeneratedOptionsId,
9881008 credential,
@@ -1016,7 +1036,7 @@ export default function getAPIImplementation(): APIInterface {
10161036 // here to be on the safe side.
10171037 if ( ! email ) {
10181038 throw new Error (
1019- "Should never come here since we already check that the email value is a string in validateEmailAddress"
1039+ "Should never come here since we already check that the email value is a string in validateEmailAddress" ,
10201040 ) ;
10211041 }
10221042
@@ -1032,13 +1052,24 @@ export default function getAPIImplementation(): APIInterface {
10321052 return AuthUtils . getErrorStatusResponseWithReason (
10331053 registerCredentialResponse ,
10341054 errorCodeMap ,
1035- "REGISTER_CREDENTIAL_NOT_ALLOWED"
1055+ "REGISTER_CREDENTIAL_NOT_ALLOWED" ,
10361056 ) ;
10371057 }
10381058
10391059 return {
10401060 status : "OK" ,
10411061 } ;
10421062 } ,
1063+ removeCredentialPOST : async function ( { webauthnCredentialId, options, userContext, session } ) {
1064+ const removeCredentialResponse = await options . recipeImplementation . removeCredential ( {
1065+ webauthnCredentialId,
1066+ recipeUserId : session . getRecipeUserId ( ) . getAsString ( ) ,
1067+ userContext,
1068+ } ) ;
1069+ if ( removeCredentialResponse . status !== "OK" ) {
1070+ return removeCredentialResponse ;
1071+ }
1072+ return { status : "OK" } ;
1073+ } ,
10431074 } ;
10441075}
0 commit comments