diff options
author | polwex <polwex@sortug.com> | 2025-07-16 10:46:39 +0700 |
---|---|---|
committer | polwex <polwex@sortug.com> | 2025-07-16 10:46:39 +0700 |
commit | 8ae0d2779c26f74e64a1db2b028bd2ac2f599cb4 (patch) | |
tree | 8add90087aae10a57817b3ef0bfc9fa884646d00 | |
parent | dc0ad21f0e857adb87d710dd0f2f9affd0a9cbc9 (diff) |
encryption done if heavy
-rw-r--r-- | components/login/ShipCredsForm.tsx | 33 | ||||
-rw-r--r-- | lib/passkey.ts | 22 |
2 files changed, 53 insertions, 2 deletions
diff --git a/components/login/ShipCredsForm.tsx b/components/login/ShipCredsForm.tsx index 15712c2..ac58e86 100644 --- a/components/login/ShipCredsForm.tsx +++ b/components/login/ShipCredsForm.tsx @@ -1,6 +1,5 @@ "use client"; import { ColorScheme, lightColors } from "@/constants"; -import { BottomTabBarButtonProps } from "@react-navigation/bottom-tabs"; import { StyleSheet, TextInput, @@ -10,15 +9,32 @@ import { } from "react-native"; import PrimaryButton from "../PrimaryButton"; import { useState } from "react"; +import { createFancyPasskey, pkDecrypt, pkEncrypt } from "@/lib/passkey"; +import toast, { Toaster } from "react-hot-toast"; export function ShipForm() { const colors = lightColors; const styles = getStyles(colors); const [patp, setPatp] = useState("~mirtyl-wacdec"); const [ticket, setTicket] = useState("~posseg-winnub-fogluc-dirmes"); + const [encryptedTicket, setenc] = useState(""); const [isLoading, setIsLoading] = useState(false); async function onSubmit() { - console.log({ patp, ticket }); + console.log("running", { patp, ticket }); + const passkey = await createFancyPasskey(); + console.log({ passkey }); + toast(passkey); + } + async function enc() { + const done = await pkEncrypt(ticket); + console.log({ encryptedTicket }); + setenc(done); + toast(done); + } + async function dec() { + const decryptedTicket = await pkDecrypt(encryptedTicket); + console.log({ decryptedTicket }); + toast(decryptedTicket); } return ( <View style={styles.bottomSection}> @@ -48,10 +64,23 @@ export function ShipForm() { style={{ marginTop: 0 }} isLoading={isLoading} /> + <PrimaryButton + label="Encrypt" + onPress={enc} + style={{ marginTop: 0 }} + isLoading={isLoading} + /> + <PrimaryButton + label="Decrypt" + onPress={dec} + style={{ marginTop: 0 }} + isLoading={isLoading} + /> <TouchableOpacity style={styles.footer}> <Text style={styles.footerText}>No Urbit ID? Get yours.</Text> </TouchableOpacity> + <Toaster position={"top-center"} /> </View> ); } diff --git a/lib/passkey.ts b/lib/passkey.ts index 81a21a5..6deb656 100644 --- a/lib/passkey.ts +++ b/lib/passkey.ts @@ -1,5 +1,6 @@ "use client"; +import * as age from "age-encryption"; import { Platform } from "react-native"; import * as SecureStore from "expo-secure-store"; import type { AsyncRes } from "./types"; @@ -8,6 +9,27 @@ const PASSKEY_CREDENTIAL_ID_KEY = "urbit_wallet_passkey_id"; const RELYING_PARTY_ID = "wallet.urbit.org"; // Change this to your domain const RELYING_PARTY_NAME = "Urbit Wallet"; +export async function createFancyPasskey() { + const credential = await age.webauthn.createCredential({ + keyName: "pasukii", + }); + return credential; +} +export async function pkEncrypt(mticket: string) { + const e = new age.Encrypter(); + e.addRecipient(new age.webauthn.WebAuthnRecipient()); + const ciphertext = await e.encrypt(mticket); + const armored = age.armor.encode(ciphertext); + return armored; +} +export async function pkDecrypt(data: string) { + const d = new age.Decrypter(); + d.addIdentity(new age.webauthn.WebAuthnIdentity()); + const decoded = age.armor.decode(data); + const out = await d.decrypt(decoded, "text"); + return out; +} + export async function createPasskey(): AsyncRes<PublicKeyCredential> { const pkok = await window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable(); |