mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-08-04 22:40:11 +00:00
feat: add support for excluding PRF extensions in credential options
This commit is contained in:
@@ -136,6 +136,19 @@ function withPrfExtension(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function withoutPrfExtension<T extends PublicKeyCredentialCreationOptions | PublicKeyCredentialRequestOptions>(options: T): T {
|
||||||
|
const extensions = { ...(((options as any).extensions || {}) as Record<string, unknown>) };
|
||||||
|
delete extensions.prf;
|
||||||
|
if (!Object.keys(extensions).length) {
|
||||||
|
const { extensions: _extensions, ...rest } = options as any;
|
||||||
|
return rest as T;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...options,
|
||||||
|
extensions: extensions as any,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function readPrfFirstResult(credential: PublicKeyCredential): ArrayBuffer | undefined {
|
function readPrfFirstResult(credential: PublicKeyCredential): ArrayBuffer | undefined {
|
||||||
const result = (credential.getClientExtensionResults() as any).prf?.results?.first;
|
const result = (credential.getClientExtensionResults() as any).prf?.results?.first;
|
||||||
return result instanceof ArrayBuffer ? result : undefined;
|
return result instanceof ArrayBuffer ? result : undefined;
|
||||||
@@ -171,6 +184,14 @@ async function getPublicKeyCredentialWithPrf(
|
|||||||
salt: Uint8Array,
|
salt: Uint8Array,
|
||||||
credentialIds: string[] = []
|
credentialIds: string[] = []
|
||||||
): Promise<PublicKeyCredential> {
|
): Promise<PublicKeyCredential> {
|
||||||
|
const baseOptions = withoutPrfExtension(options);
|
||||||
|
if (!(await canRequestPrfExtension())) {
|
||||||
|
const credential = await navigator.credentials.get({ publicKey: baseOptions });
|
||||||
|
if (!(credential instanceof PublicKeyCredential)) {
|
||||||
|
throw new Error(t('txt_no_passkey_selected'));
|
||||||
|
}
|
||||||
|
return credential;
|
||||||
|
}
|
||||||
const attempts = credentialIds.length
|
const attempts = credentialIds.length
|
||||||
? [
|
? [
|
||||||
buildCredentialPrfExtension(salt, credentialIds),
|
buildCredentialPrfExtension(salt, credentialIds),
|
||||||
@@ -181,7 +202,7 @@ async function getPublicKeyCredentialWithPrf(
|
|||||||
for (let index = 0; index < attempts.length; index += 1) {
|
for (let index = 0; index < attempts.length; index += 1) {
|
||||||
try {
|
try {
|
||||||
const credential = await navigator.credentials.get({
|
const credential = await navigator.credentials.get({
|
||||||
publicKey: withPrfExtension(options, attempts[index]),
|
publicKey: withPrfExtension(baseOptions, attempts[index]),
|
||||||
});
|
});
|
||||||
if (!(credential instanceof PublicKeyCredential)) {
|
if (!(credential instanceof PublicKeyCredential)) {
|
||||||
throw new Error(t('txt_no_passkey_selected'));
|
throw new Error(t('txt_no_passkey_selected'));
|
||||||
@@ -287,7 +308,7 @@ export async function createAccountPasskeyCredential(
|
|||||||
if (!window.PublicKeyCredential || !navigator.credentials) {
|
if (!window.PublicKeyCredential || !navigator.credentials) {
|
||||||
throw new Error(t('txt_passkey_browser_not_supported'));
|
throw new Error(t('txt_passkey_browser_not_supported'));
|
||||||
}
|
}
|
||||||
const nativeOptions = cloneCreationOptions(response.options);
|
const nativeOptions = withoutPrfExtension(cloneCreationOptions(response.options));
|
||||||
const createWithOptions = async (options: PublicKeyCredentialCreationOptions): Promise<PublicKeyCredential> => {
|
const createWithOptions = async (options: PublicKeyCredentialCreationOptions): Promise<PublicKeyCredential> => {
|
||||||
const credential = await navigator.credentials.create({ publicKey: options });
|
const credential = await navigator.credentials.create({ publicKey: options });
|
||||||
if (!(credential instanceof PublicKeyCredential)) {
|
if (!(credential instanceof PublicKeyCredential)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user