Files
snort/packages/app/src/Hooks/useLoginHandler.tsx
2023-09-22 09:53:38 +01:00

80 lines
2.6 KiB
TypeScript

import { useIntl } from "react-intl";
import { Nip46Signer, PinEncrypted } from "@snort/system";
import { EmailRegex, MnemonicRegex } from "Const";
import { LoginSessionType, LoginStore } from "Login";
import { generateBip39Entropy, entropyToPrivateKey } from "nip6";
import { getNip05PubKey } from "Pages/LoginPage";
import { bech32ToHex } from "SnortUtils";
import { unwrap } from "@snort/shared";
export class PinRequiredError extends Error {}
export default function useLoginHandler() {
const { formatMessage } = useIntl();
const hasSubtleCrypto = window.crypto.subtle !== undefined;
async function doLogin(key: string, pin?: string) {
const insecureMsg = formatMessage({
defaultMessage:
"Can't login with private key on an insecure connection, please use a Nostr key manager extension instead",
});
// private key logins
if (key.startsWith("nsec")) {
if (!hasSubtleCrypto) {
throw new Error(insecureMsg);
}
const hexKey = bech32ToHex(key);
if (hexKey.length === 64) {
if (!pin) throw new PinRequiredError();
LoginStore.loginWithPrivateKey(await PinEncrypted.create(hexKey, pin));
} else {
throw new Error("INVALID PRIVATE KEY");
}
} else if (key.match(MnemonicRegex)?.length === 24) {
if (!hasSubtleCrypto) {
throw new Error(insecureMsg);
}
if (!pin) throw new PinRequiredError();
const ent = generateBip39Entropy(key);
const keyHex = entropyToPrivateKey(ent);
LoginStore.loginWithPrivateKey(await PinEncrypted.create(keyHex, pin));
} else if (key.length === 64) {
if (!hasSubtleCrypto) {
throw new Error(insecureMsg);
}
if (!pin) throw new PinRequiredError();
LoginStore.loginWithPrivateKey(await PinEncrypted.create(key, pin));
}
// public key logins
if (key.startsWith("npub")) {
const hexKey = bech32ToHex(key);
LoginStore.loginWithPubkey(hexKey, LoginSessionType.PublicKey);
} else if (key.match(EmailRegex)) {
const hexKey = await getNip05PubKey(key);
LoginStore.loginWithPubkey(hexKey, LoginSessionType.PublicKey);
} else if (key.startsWith("bunker://")) {
if (!pin) throw new PinRequiredError();
const nip46 = new Nip46Signer(key);
await nip46.init();
const loginPubkey = await nip46.getPubKey();
LoginStore.loginWithPubkey(
loginPubkey,
LoginSessionType.Nip46,
undefined,
nip46.relays,
await PinEncrypted.create(unwrap(nip46.privateKey), pin),
);
nip46.close();
} else {
throw new Error("INVALID PRIVATE KEY");
}
}
return {
doLogin,
};
}