From 3a9778496fe01a67bd9776bb9c72332b47144c76 Mon Sep 17 00:00:00 2001 From: danilo neves cruz Date: Mon, 13 Nov 2023 22:10:31 -0300 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20webauthn:=20serialize=20android=20r?= =?UTF-8?q?esponse?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../expo/modules/webauthn/ExpoWebauthn.kt | 5 ++-- webauthn/src/index.ts | 25 ++++++++++++++++--- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/webauthn/android/src/main/java/expo/modules/webauthn/ExpoWebauthn.kt b/webauthn/android/src/main/java/expo/modules/webauthn/ExpoWebauthn.kt index d8daffaf6..4c8bf3392 100644 --- a/webauthn/android/src/main/java/expo/modules/webauthn/ExpoWebauthn.kt +++ b/webauthn/android/src/main/java/expo/modules/webauthn/ExpoWebauthn.kt @@ -5,6 +5,7 @@ import androidx.credentials.CredentialManager import androidx.credentials.GetCredentialRequest import androidx.credentials.GetPasswordOption import androidx.credentials.GetPublicKeyCredentialOption +import androidx.credentials.PublicKeyCredential import expo.modules.kotlin.exception.Exceptions import expo.modules.kotlin.functions.Coroutine import expo.modules.kotlin.modules.Module @@ -22,10 +23,10 @@ class ExpoWebauthn : Module() { AsyncFunction("get") Coroutine { requestJSON: String -> val activity = appContext.currentActivity ?: throw Exceptions.MissingActivity() - CredentialManager.create(activity).getCredential( + (CredentialManager.create(activity).getCredential( activity, GetCredentialRequest(listOf(GetPublicKeyCredentialOption(requestJSON), GetPasswordOption())) - ) + ).credential as PublicKeyCredential).authenticationResponseJson } } } diff --git a/webauthn/src/index.ts b/webauthn/src/index.ts index ee02003f0..c0486f1d0 100644 --- a/webauthn/src/index.ts +++ b/webauthn/src/index.ts @@ -1,16 +1,16 @@ -import { encode } from "base64-arraybuffer"; +import { encode, decode } from "base64-arraybuffer"; import ExpoWebauthn from "./ExpoWebauthn"; // @ts-expect-error -- polyfill global.navigator.credentials ??= { - get(options) { + async get(options) { if (!options?.publicKey) throw new Error("publicKey required"); - return ExpoWebauthn.get(stringify(options.publicKey)); + return parse(await ExpoWebauthn.get(stringify(options.publicKey))); }, async create(options) { if (!options?.publicKey) throw new Error("publicKey required"); - return ExpoWebauthn.create(stringify(options.publicKey)); + return parse(await ExpoWebauthn.create(stringify(options.publicKey))); }, } as CredentialsContainer; @@ -22,3 +22,20 @@ function stringify(value: unknown) { return v as unknown; }); } + +function parse(text: string) { + return JSON.parse(text, (key, v) => { + if ( + typeof v === "string" && + (key === "rawId" || + key === "signature" || + key === "userHandle" || + key === "clientDataJSON" || + key === "authenticatorData" || + key === "clientExtensionResults") + ) { + return decode(v.replace(/-/g, "+").replace(/_/g, "/")); + } + return v as unknown; + }) as PublicKeyCredential; +}