Skip to content

Commit

Permalink
unenroll passkey
Browse files Browse the repository at this point in the history
  • Loading branch information
renkelvin committed Nov 9, 2023
1 parent 90f1b13 commit 1d5d4df
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 3 deletions.
3 changes: 3 additions & 0 deletions common/api-review/auth.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,9 @@ export class TwitterAuthProvider extends BaseOAuthProvider {
static readonly TWITTER_SIGN_IN_METHOD: 'twitter.com';
}

// @public
export function unenrollPasskey(user: User, credentialId: string): Promise<void>;

// @public
export function unlink(user: User, providerId: string): Promise<User>;

Expand Down
7 changes: 7 additions & 0 deletions packages/auth/demo/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,13 @@
id="enroll-passkey">
Enroll Passkey
</button>
<button class="btn btn-block btn-primary" id="get-enrolled-passkey">
Get Enrolled Passkeys
</button>
<input type="test" name="unenroll-passkey-credential-id" id="unenroll-passkey-credential-id" class="form-control" placeholder="Passkey Credential ID" />
<button class="btn btn-block btn-primary" id="unenroll-passkey">
Unenroll Passkey
</button>
</form>

<!-- Linking/Unlinking -->
Expand Down
16 changes: 15 additions & 1 deletion packages/auth/demo/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ import {
initializeRecaptchaConfig,
validatePassword,
enrollPasskey,
signInWithPasskey
signInWithPasskey,
unenrollPasskey
} from '@firebase/auth';

import { config } from './config';
Expand Down Expand Up @@ -529,6 +530,17 @@ function onEnrollPasskey() {
);
}

function onGetEnrolledPasskeys() {
console.log('Getting enrolled passkeys');
const passkeys = activeUser().enrolledPasskeys;
console.log(passkeys);
}

function onUnenrollPasskey() {
const credId = $('#unenroll-passkey-credential-id').val();
unenrollPasskey(activeUser(), credId);
}

function onSignInWithPasskey() {
const name = $('#signin-passkey-name').val();
signInWithPasskey(auth, name).then(onAuthSuccess, onAuthError);
Expand Down Expand Up @@ -2272,6 +2284,8 @@ function initApp() {

$('#get-provider-data').click(onGetProviderData);
$('#enroll-passkey').click(onEnrollPasskey);
$('#get-enrolled-passkey').click(onGetEnrolledPasskeys);
$('#unenroll-passkey').click(onUnenrollPasskey);
$('#link-with-email-and-password').click(onLinkWithEmailAndPassword);
$('#link-with-generic-idp-credential').click(onLinkWithGenericIdPCredential);
$('#unlink-provider').click(onUnlinkProvider);
Expand Down
18 changes: 18 additions & 0 deletions packages/auth/src/api/account_management/passkey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,21 @@ export async function finalizePasskeySignIn(
_addTidIfNecessary(auth, request)
);
}

export interface PasskeyUnenrollRequest {
deletePasskey: string[];
}

export interface PasskeyUnenrollResponse {}

export async function passkeyUnenroll(
auth: Auth,
request: PasskeyUnenrollRequest
): Promise<PasskeyUnenrollResponse> {
return _performApiRequest<PasskeyUnenrollRequest, PasskeyUnenrollResponse>(
auth,
HttpMethod.POST,
Endpoint.SET_ACCOUNT_INFO,
request
);
}
6 changes: 5 additions & 1 deletion packages/auth/src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,11 @@ export {
sendEmailVerification,
verifyBeforeUpdateEmail
} from './strategies/email';
export { signInWithPasskey, enrollPasskey } from './strategies/passkey';
export {
signInWithPasskey,
enrollPasskey,
unenrollPasskey
} from './strategies/passkey';

// core
export { ActionCodeURL, parseActionCodeURL } from './action_code_url';
Expand Down
25 changes: 24 additions & 1 deletion packages/auth/src/core/strategies/passkey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ import {
finalizePasskeySignIn,
FinalizePasskeySignInRequest,
FinalizePasskeySignInResponse,
publicKeyCredentialToJSON
publicKeyCredentialToJSON,
PasskeyUnenrollRequest,
PasskeyUnenrollResponse,
passkeyUnenroll
} from '../../api/account_management/passkey';
import { UserInternal } from '../../model/user';
import { _castAuth } from '../auth/auth_impl';
Expand Down Expand Up @@ -164,6 +167,26 @@ export async function enrollPasskey(
}
}

/**
* Unenrolls a passkey for the user account.
* @param user - The user to unenroll the passkey for.
* @param credentialId - The ID of the passkey to unenroll.
* @returns A promise that resolves when the passkey is successfully unenrolled.
* @public
*/
export async function unenrollPasskey(
user: User,
credentialId: string
): Promise<void> {
const userInternal = getModularInstance(user) as UserInternal;
const authInternal = _castAuth(userInternal.auth);

const request: PasskeyUnenrollRequest = {
deletePasskey: [credentialId]
};
await passkeyUnenroll(authInternal, request);
}

// Converts an array of credential IDs of `excludeCredentials` field to an array of `PublicKeyCredentialDescriptor` objects.
function convertExcludeCredentials(
options:
Expand Down

0 comments on commit 1d5d4df

Please sign in to comment.