Replace usages of privateKey

This commit is contained in:
Kieran 2023-09-21 22:34:36 +01:00
parent 96d4e4bcc5
commit 01b3fd559b
No known key found for this signature in database
GPG Key ID: DE71CEB3925BE941
8 changed files with 70 additions and 59 deletions

View File

@ -119,6 +119,10 @@ export function LoginUnlock() {
pub.pow(login.preferences.pow, DefaultPowWorker); pub.pow(login.preferences.pow, DefaultPowWorker);
} }
LoginStore.setPublisher(login.id, pub); LoginStore.setPublisher(login.id, pub);
LoginStore.updateSession({
...login,
privateKeyData: key,
});
} }
} }
@ -142,7 +146,7 @@ export function LoginUnlock() {
<PinPrompt <PinPrompt
subTitle={ subTitle={
<p> <p>
<FormattedMessage defaultMessage="Enter pin to unlock private key" /> <FormattedMessage defaultMessage="Enter pin to unlock your private key" />
</p> </p>
} }
onResult={unlockSession} onResult={unlockSession}

View File

@ -6,6 +6,7 @@ import { LoginSessionType, LoginStore } from "Login";
import { generateBip39Entropy, entropyToPrivateKey } from "nip6"; import { generateBip39Entropy, entropyToPrivateKey } from "nip6";
import { getNip05PubKey } from "Pages/LoginPage"; import { getNip05PubKey } from "Pages/LoginPage";
import { bech32ToHex } from "SnortUtils"; import { bech32ToHex } from "SnortUtils";
import { unwrap } from "@snort/shared";
export class PinRequiredError extends Error {} export class PinRequiredError extends Error {}
@ -54,11 +55,18 @@ export default function useLoginHandler() {
const hexKey = await getNip05PubKey(key); const hexKey = await getNip05PubKey(key);
LoginStore.loginWithPubkey(hexKey, LoginSessionType.PublicKey); LoginStore.loginWithPubkey(hexKey, LoginSessionType.PublicKey);
} else if (key.startsWith("bunker://")) { } else if (key.startsWith("bunker://")) {
if (!pin) throw new PinRequiredError();
const nip46 = new Nip46Signer(key); const nip46 = new Nip46Signer(key);
await nip46.init(); await nip46.init();
const loginPubkey = await nip46.getPubKey(); const loginPubkey = await nip46.getPubKey();
LoginStore.loginWithPubkey(loginPubkey, LoginSessionType.Nip46, undefined, nip46.relays, nip46.privateKey); LoginStore.loginWithPubkey(
loginPubkey,
LoginSessionType.Nip46,
undefined,
nip46.relays,
await PinEncrypted.create(unwrap(nip46.privateKey), pin),
);
nip46.close(); nip46.close();
} else { } else {
throw new Error("INVALID PRIVATE KEY"); throw new Error("INVALID PRIVATE KEY");

View File

@ -96,7 +96,7 @@ export class MultiAccountStore extends ExternalStore<LoginSession> {
type: LoginSessionType, type: LoginSessionType,
relays?: Record<string, RelaySettings>, relays?: Record<string, RelaySettings>,
remoteSignerRelays?: Array<string>, remoteSignerRelays?: Array<string>,
privateKey?: string, privateKey?: PinEncrypted,
) { ) {
if (this.#accounts.has(key)) { if (this.#accounts.has(key)) {
throw new Error("Already logged in with this pubkey"); throw new Error("Already logged in with this pubkey");
@ -113,7 +113,7 @@ export class MultiAccountStore extends ExternalStore<LoginSession> {
}, },
preferences: deepClone(DefaultPreferences), preferences: deepClone(DefaultPreferences),
remoteSignerRelays, remoteSignerRelays,
privateKey, privateKeyData: privateKey,
} as LoginSession; } as LoginSession;
const pub = createPublisher(newSession); const pub = createPublisher(newSession);
@ -228,10 +228,15 @@ export class MultiAccountStore extends ExternalStore<LoginSession> {
if (!this.#activeAccount && this.#accounts.size > 0) { if (!this.#activeAccount && this.#accounts.size > 0) {
this.#activeAccount = this.#accounts.keys().next().value; this.#activeAccount = this.#accounts.keys().next().value;
} }
const toSave = [...this.#accounts.values()]; const toSave = [];
for (const v of toSave) { for (const v of this.#accounts.values()) {
if (v.privateKeyData instanceof PinEncrypted) { if (v.privateKeyData instanceof PinEncrypted) {
v.privateKeyData = v.privateKeyData.toPayload(); toSave.push({
...v,
privateKeyData: v.privateKeyData.toPayload(),
});
} else {
toSave.push({ ...v });
} }
} }

View File

@ -9,7 +9,6 @@ import { bech32ToHex, getPublicKey, unwrap } from "SnortUtils";
import ZapButton from "Element/ZapButton"; import ZapButton from "Element/ZapButton";
import useImgProxy from "Hooks/useImgProxy"; import useImgProxy from "Hooks/useImgProxy";
import Icon from "Icons/Icon"; import Icon from "Icons/Icon";
import useLogin from "Hooks/useLogin";
import { generateNewLogin, LoginSessionType, LoginStore } from "Login"; import { generateNewLogin, LoginSessionType, LoginStore } from "Login";
import AsyncButton from "Element/AsyncButton"; import AsyncButton from "Element/AsyncButton";
import useLoginHandler, { PinRequiredError } from "Hooks/useLoginHandler"; import useLoginHandler, { PinRequiredError } from "Hooks/useLoginHandler";
@ -76,7 +75,6 @@ export async function getNip05PubKey(addr: string): Promise<string> {
export default function LoginPage() { export default function LoginPage() {
const navigate = useNavigate(); const navigate = useNavigate();
const login = useLogin();
const [key, setKey] = useState(""); const [key, setKey] = useState("");
const [error, setError] = useState(""); const [error, setError] = useState("");
const [pin, setPin] = useState(false); const [pin, setPin] = useState(false);
@ -89,12 +87,6 @@ export default function LoginPage() {
const hasSubtleCrypto = window.crypto.subtle !== undefined; const hasSubtleCrypto = window.crypto.subtle !== undefined;
const [nostrConnect, setNostrConnect] = useState(""); const [nostrConnect, setNostrConnect] = useState("");
useEffect(() => {
if (login.publicKey) {
navigate("/");
}
}, [login, navigate]);
useEffect(() => { useEffect(() => {
const ret = unwrap(Artwork.at(Artwork.length * Math.random())); const ret = unwrap(Artwork.at(Artwork.length * Math.random()));
const url = proxy(ret.link); const url = proxy(ret.link);
@ -161,18 +153,25 @@ export default function LoginPage() {
} }
function nip46Buttons() { function nip46Buttons() {
return null;
return ( return (
<> <>
<AsyncButton type="button" onClick={startNip46}> <AsyncButton type="button" onClick={startNip46}>
<FormattedMessage defaultMessage="Nostr Connect (NIP-46)" description="Login button for NIP-46 signer app" /> <FormattedMessage defaultMessage="Nostr Connect" description="Login button for NIP-46 signer app" />
</AsyncButton> </AsyncButton>
{nostrConnect && ( {nostrConnect && (
<Modal id="nostr-connect" onClose={() => setNostrConnect("")}> <Modal id="nostr-connect" onClose={() => setNostrConnect("")}>
<div className="flex f-col"> <>
<QrCode data={nostrConnect} /> <h2>
<Copy text={nostrConnect} /> <FormattedMessage defaultMessage="Nostr Connect" />
</div> </h2>
<p>
<FormattedMessage defaultMessage="Scan this QR code with your signer app to get started" />
</p>
<div className="flex-column f-center g12">
<QrCode data={nostrConnect} />
<Copy text={nostrConnect} />
</div>
</>
</Modal> </Modal>
)} )}
</> </>
@ -188,7 +187,7 @@ export default function LoginPage() {
<> <>
<AsyncButton type="button" onClick={doNip07Login}> <AsyncButton type="button" onClick={doNip07Login}>
<FormattedMessage <FormattedMessage
defaultMessage="Login with Extension (NIP-07)" defaultMessage="Nostr Extension"
description="Login button for NIP7 key manager extension" description="Login button for NIP7 key manager extension"
/> />
</AsyncButton> </AsyncButton>
@ -269,7 +268,7 @@ export default function LoginPage() {
<p dir="auto"> <p dir="auto">
<FormattedMessage defaultMessage="Your key" description="Label for key input" /> <FormattedMessage defaultMessage="Your key" description="Label for key input" />
</p> </p>
<div className="flex"> <div className="flex f-center g8">
<input <input
dir="auto" dir="auto"
type={isMasking ? "password" : "text"} type={isMasking ? "password" : "text"}
@ -282,7 +281,7 @@ export default function LoginPage() {
<Icon <Icon
name={isMasking ? "openeye" : "closedeye"} name={isMasking ? "openeye" : "closedeye"}
size={30} size={30}
className="highlight btn-sm pointer" className="highlight pointer"
onClick={() => setMasking(!isMasking)} onClick={() => setMasking(!isMasking)}
/> />
</div> </div>

View File

@ -1,6 +1,6 @@
import "./Keys.css"; import "./Keys.css";
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from "react-intl";
import { encodeTLV, NostrPrefix } from "@snort/system"; import { encodeTLV, NostrPrefix, PinEncrypted } from "@snort/system";
import Copy from "Element/Copy"; import Copy from "Element/Copy";
import useLogin from "Hooks/useLogin"; import useLogin from "Hooks/useLogin";
@ -8,7 +8,7 @@ import { hexToMnemonic } from "nip6";
import { hexToBech32 } from "SnortUtils"; import { hexToBech32 } from "SnortUtils";
export default function ExportKeys() { export default function ExportKeys() {
const { publicKey, privateKey, generatedEntropy } = useLogin(); const { publicKey, privateKeyData, generatedEntropy } = useLogin();
return ( return (
<div className="flex-column g12"> <div className="flex-column g12">
<h3> <h3>
@ -16,12 +16,12 @@ export default function ExportKeys() {
</h3> </h3>
<Copy text={hexToBech32("npub", publicKey ?? "")} className="dashed" /> <Copy text={hexToBech32("npub", publicKey ?? "")} className="dashed" />
<Copy text={encodeTLV(NostrPrefix.Profile, publicKey ?? "")} className="dashed" /> <Copy text={encodeTLV(NostrPrefix.Profile, publicKey ?? "")} className="dashed" />
{privateKey && ( {privateKeyData instanceof PinEncrypted && (
<> <>
<h3> <h3>
<FormattedMessage defaultMessage="Private Key" /> <FormattedMessage defaultMessage="Private Key" />
</h3> </h3>
<Copy text={hexToBech32("nsec", privateKey)} className="dashed" /> <Copy text={hexToBech32("nsec", privateKeyData.value)} className="dashed" />
</> </>
)} )}
{generatedEntropy && ( {generatedEntropy && (

View File

@ -8,16 +8,7 @@ import WasmPath from "@snort/system-query/pkg/system_query_bg.wasm";
import { StrictMode } from "react"; import { StrictMode } from "react";
import * as ReactDOM from "react-dom/client"; import * as ReactDOM from "react-dom/client";
import { createBrowserRouter, RouterProvider } from "react-router-dom"; import { createBrowserRouter, RouterProvider } from "react-router-dom";
import { import { NostrSystem, ProfileLoaderService, PowWorker, QueryOptimizer, FlatReqFilter, ReqFilter } from "@snort/system";
EventPublisher,
NostrSystem,
ProfileLoaderService,
Nip7Signer,
PowWorker,
QueryOptimizer,
FlatReqFilter,
ReqFilter,
} from "@snort/system";
import { SnortContext } from "@snort/system-react"; import { SnortContext } from "@snort/system-react";
import * as serviceWorkerRegistration from "serviceWorkerRegistration"; import * as serviceWorkerRegistration from "serviceWorkerRegistration";
@ -71,13 +62,9 @@ export const System = new NostrSystem({
relayMetrics: RelayMetrics, relayMetrics: RelayMetrics,
queryOptimizer: WasmQueryOptimizer, queryOptimizer: WasmQueryOptimizer,
authHandler: async (c, r) => { authHandler: async (c, r) => {
const { publicKey, privateKey } = LoginStore.snapshot(); const { id } = LoginStore.snapshot();
if (privateKey) { const pub = LoginStore.getPublisher(id);
const pub = EventPublisher.privateKey(privateKey); if (pub) {
return await pub.nip42Auth(c, r);
}
if (publicKey) {
const pub = new EventPublisher(new Nip7Signer(), publicKey);
return await pub.nip42Auth(c, r); return await pub.nip42Auth(c, r);
} }
}, },

View File

@ -99,9 +99,6 @@
"25V4l1": { "25V4l1": {
"defaultMessage": "Banner" "defaultMessage": "Banner"
}, },
"27jzYm": {
"defaultMessage": "Enter pin to unlock private key"
},
"2IFGap": { "2IFGap": {
"defaultMessage": "Donate" "defaultMessage": "Donate"
}, },
@ -145,6 +142,9 @@
"3yk8fB": { "3yk8fB": {
"defaultMessage": "Wallet" "defaultMessage": "Wallet"
}, },
"40VR6s": {
"defaultMessage": "Nostr Connect"
},
"450Fty": { "450Fty": {
"defaultMessage": "None" "defaultMessage": "None"
}, },
@ -226,6 +226,9 @@
"89q5wc": { "89q5wc": {
"defaultMessage": "Confirm Reposts" "defaultMessage": "Confirm Reposts"
}, },
"8Kboo2": {
"defaultMessage": "Scan this QR code with your signer app to get started"
},
"8QDesP": { "8QDesP": {
"defaultMessage": "Zap {n} sats" "defaultMessage": "Zap {n} sats"
}, },
@ -241,6 +244,10 @@
"8v1NN+": { "8v1NN+": {
"defaultMessage": "Pairing phrase" "defaultMessage": "Pairing phrase"
}, },
"8xNnhi": {
"defaultMessage": "Nostr Extension",
"description": "Login button for NIP7 key manager extension"
},
"9+Ddtu": { "9+Ddtu": {
"defaultMessage": "Next" "defaultMessage": "Next"
}, },
@ -563,6 +570,10 @@
"LwYmVi": { "LwYmVi": {
"defaultMessage": "Zaps on this note will be split to the following users." "defaultMessage": "Zaps on this note will be split to the following users."
}, },
"M10zFV": {
"defaultMessage": "Nostr Connect",
"description": "Login button for NIP-46 signer app"
},
"M3Oirc": { "M3Oirc": {
"defaultMessage": "Debug Menus" "defaultMessage": "Debug Menus"
}, },
@ -779,10 +790,6 @@
"VnXp8Z": { "VnXp8Z": {
"defaultMessage": "Avatar" "defaultMessage": "Avatar"
}, },
"VtPV/B": {
"defaultMessage": "Login with Extension (NIP-07)",
"description": "Login button for NIP7 key manager extension"
},
"VvaJst": { "VvaJst": {
"defaultMessage": "View Wallets" "defaultMessage": "View Wallets"
}, },
@ -940,6 +947,9 @@
"e61Jf3": { "e61Jf3": {
"defaultMessage": "Coming soon" "defaultMessage": "Coming soon"
}, },
"e7VmYP": {
"defaultMessage": "Enter pin to unlock your private key"
},
"e7qqly": { "e7qqly": {
"defaultMessage": "Mark All Read" "defaultMessage": "Mark All Read"
}, },
@ -1009,10 +1019,6 @@
"hMzcSq": { "hMzcSq": {
"defaultMessage": "Messages" "defaultMessage": "Messages"
}, },
"hWSp+B": {
"defaultMessage": "Nostr Connect (NIP-46)",
"description": "Login button for NIP-46 signer app"
},
"hY4lzx": { "hY4lzx": {
"defaultMessage": "Supports" "defaultMessage": "Supports"
}, },

View File

@ -32,7 +32,6 @@
"1udzha": "Conversations", "1udzha": "Conversations",
"2/2yg+": "Add", "2/2yg+": "Add",
"25V4l1": "Banner", "25V4l1": "Banner",
"27jzYm": "Enter pin to unlock private key",
"2IFGap": "Donate", "2IFGap": "Donate",
"2LbrkB": "Enter password", "2LbrkB": "Enter password",
"2a2YiP": "{n} Bookmarks", "2a2YiP": "{n} Bookmarks",
@ -47,6 +46,7 @@
"3tVy+Z": "{n} Followers", "3tVy+Z": "{n} Followers",
"3xCwbZ": "OR", "3xCwbZ": "OR",
"3yk8fB": "Wallet", "3yk8fB": "Wallet",
"40VR6s": "Nostr Connect",
"450Fty": "None", "450Fty": "None",
"47FYwb": "Cancel", "47FYwb": "Cancel",
"4IPzdn": "Primary Developers", "4IPzdn": "Primary Developers",
@ -74,11 +74,13 @@
"7hp70g": "NIP-05", "7hp70g": "NIP-05",
"8/vBbP": "Reposts ({n})", "8/vBbP": "Reposts ({n})",
"89q5wc": "Confirm Reposts", "89q5wc": "Confirm Reposts",
"8Kboo2": "Scan this QR code with your signer app to get started",
"8QDesP": "Zap {n} sats", "8QDesP": "Zap {n} sats",
"8Rkoyb": "Recipient", "8Rkoyb": "Recipient",
"8Y6bZQ": "Invalid zap split: {input}", "8Y6bZQ": "Invalid zap split: {input}",
"8g2vyB": "name too long", "8g2vyB": "name too long",
"8v1NN+": "Pairing phrase", "8v1NN+": "Pairing phrase",
"8xNnhi": "Nostr Extension",
"9+Ddtu": "Next", "9+Ddtu": "Next",
"9HU8vw": "Reply", "9HU8vw": "Reply",
"9SvQep": "Follows {n}", "9SvQep": "Follows {n}",
@ -185,6 +187,7 @@
"Lu5/Bj": "Open on Zapstr", "Lu5/Bj": "Open on Zapstr",
"Lw+I+J": "{n,plural,=0{{name} zapped} other{{name} & {n} others zapped}}", "Lw+I+J": "{n,plural,=0{{name} zapped} other{{name} & {n} others zapped}}",
"LwYmVi": "Zaps on this note will be split to the following users.", "LwYmVi": "Zaps on this note will be split to the following users.",
"M10zFV": "Nostr Connect",
"M3Oirc": "Debug Menus", "M3Oirc": "Debug Menus",
"MBAYRO": "Shows \"Copy ID\" and \"Copy Event JSON\" in the context menu on each message", "MBAYRO": "Shows \"Copy ID\" and \"Copy Event JSON\" in the context menu on each message",
"MI2jkA": "Not available:", "MI2jkA": "Not available:",
@ -255,7 +258,6 @@
"VR5eHw": "Public key (npub/nprofile)", "VR5eHw": "Public key (npub/nprofile)",
"VlJkSk": "{n} muted", "VlJkSk": "{n} muted",
"VnXp8Z": "Avatar", "VnXp8Z": "Avatar",
"VtPV/B": "Login with Extension (NIP-07)",
"VvaJst": "View Wallets", "VvaJst": "View Wallets",
"Vx7Zm2": "How do keys work?", "Vx7Zm2": "How do keys work?",
"W1yoZY": "It looks like you dont have any subscriptions, you can get one {link}", "W1yoZY": "It looks like you dont have any subscriptions, you can get one {link}",
@ -307,6 +309,7 @@
"d7d0/x": "LN Address", "d7d0/x": "LN Address",
"dOQCL8": "Display name", "dOQCL8": "Display name",
"e61Jf3": "Coming soon", "e61Jf3": "Coming soon",
"e7VmYP": "Enter pin to unlock your private key",
"e7qqly": "Mark All Read", "e7qqly": "Mark All Read",
"eHAneD": "Reaction emoji", "eHAneD": "Reaction emoji",
"eJj8HD": "Get Verified", "eJj8HD": "Get Verified",
@ -330,7 +333,6 @@
"h8XMJL": "Badges", "h8XMJL": "Badges",
"hK5ZDk": "the world", "hK5ZDk": "the world",
"hMzcSq": "Messages", "hMzcSq": "Messages",
"hWSp+B": "Nostr Connect (NIP-46)",
"hY4lzx": "Supports", "hY4lzx": "Supports",
"hicxcO": "Show replies", "hicxcO": "Show replies",
"hmZ3Bz": "Media", "hmZ3Bz": "Media",