80 lines
2.6 KiB
TypeScript
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,
|
|
};
|
|
}
|