diff --git a/packages/app/src/Pages/Login.css b/packages/app/src/Pages/Login.css index fd7a7bfb..85cf3010 100644 --- a/packages/app/src/Pages/Login.css +++ b/packages/app/src/Pages/Login.css @@ -6,6 +6,10 @@ font-weight: 400; font-size: 14px; line-height: 24px; +} + +.login p, +.login a { color: #999999; } @@ -21,7 +25,7 @@ .login .logo { margin-top: 16px; - margin-bottom: 67px; + margin-bottom: 50px; } .login > div:nth-child(1) { @@ -73,14 +77,16 @@ } @media (max-width: 1024px) { + .login { + width: unset; + height: unset; + } + .login > div:nth-child(2) { display: none; } } -.login .login-note { -} - .login .login-actions { margin-top: 32px; } @@ -99,20 +105,14 @@ font-weight: 400; font-size: 14px; line-height: 24px; - margin-top: 56px; - margin-bottom: 64px; -} - -@media (max-width: 520px) { - .login .login-or { - margin-top: 32px; - margin-bottom: 32px; - } + margin-top: 40px; + margin-bottom: 40px; } .light .login-or { color: #a1a1aa; } + .login-container input[type="text"] { border: none; background-color: var(--gray-secondary); diff --git a/packages/app/src/Pages/Login.tsx b/packages/app/src/Pages/Login.tsx index 26903901..f27d37cc 100644 --- a/packages/app/src/Pages/Login.tsx +++ b/packages/app/src/Pages/Login.tsx @@ -5,14 +5,14 @@ import { useDispatch, useSelector } from "react-redux"; import { useNavigate } from "react-router-dom"; import * as secp from "@noble/secp256k1"; import { useIntl, FormattedMessage } from "react-intl"; +import { HexKey } from "@snort/nostr"; import { RootState } from "State/Store"; import { setPrivateKey, setPublicKey, setRelays, setGeneratedPrivateKey } from "State/Login"; import { DefaultRelays, EmailRegex, MnemonicRegex } from "Const"; import { bech32ToHex, generateBip39Entropy, entropyToDerivedKey, unwrap } from "Util"; -import { HexKey } from "@snort/nostr"; import ZapButton from "Element/ZapButton"; -// import useImgProxy from "Feed/ImgProxy"; +import useImgProxy from "Hooks/useImgProxy"; import messages from "./messages"; @@ -67,7 +67,9 @@ export default function LoginPage() { const [error, setError] = useState(""); const [art, setArt] = useState(); const { formatMessage } = useIntl(); - //const { proxy } = useImgProxy(); + const { proxy } = useImgProxy(); + const hasNip7 = "nostr" in window; + const isSecure = window.location.protocol === "https:"; useEffect(() => { if (publicKey) { @@ -77,14 +79,19 @@ export default function LoginPage() { useEffect(() => { const ret = unwrap(Artwork.at(Artwork.length * Math.random())); - // disable for now because imgproxy is ded - // proxy(ret.link).then(a => setArt({ ...ret, link: a })); - setArt(ret); + proxy(ret.link).then(a => setArt({ ...ret, link: a })); }, []); async function doLogin() { + const insecureMsg = formatMessage({ + defaultMessage: + "Can't login with private key on an insecure connection, please use a Nostr key manager extension instead", + }); try { if (key.startsWith("nsec")) { + if (!isSecure) { + throw new Error(insecureMsg); + } const hexKey = bech32ToHex(key); if (secp.utils.isValidPrivateKey(hexKey)) { dispatch(setPrivateKey(hexKey)); @@ -98,16 +105,30 @@ export default function LoginPage() { const hexKey = await getNip05PubKey(key); dispatch(setPublicKey(hexKey)); } else if (key.match(MnemonicRegex)) { + if (!isSecure) { + throw new Error(insecureMsg); + } const ent = generateBip39Entropy(key); const keyHex = entropyToDerivedKey(ent); dispatch(setPrivateKey(keyHex)); } else if (secp.utils.isValidPrivateKey(key)) { + if (!isSecure) { + throw new Error(insecureMsg); + } dispatch(setPrivateKey(key)); } else { throw new Error("INVALID PRIVATE KEY"); } } catch (e) { - setError(`Failed to load NIP-05 pub key (${e})`); + if (e instanceof Error) { + setError(e.message); + } else { + setError( + formatMessage({ + defaultMessage: "Unknown login error", + }) + ); + } console.error(e); } } @@ -139,9 +160,8 @@ export default function LoginPage() { } function altLogins() { - const nip07 = "nostr" in window; - if (!nip07) { - return null; + if (!hasNip7) { + return; } return ( @@ -154,6 +174,92 @@ export default function LoginPage() { ); } + function generateKey() { + if (!isSecure) return; + + return ( + <> +
+ +
+
+

+ +

+

+ +

+
+ +
+ + ); + } + + function installExtension() { + if (isSecure) return; + + return ( + <> +
+ +
+
+

+ +

+

+ +

+ +

+ awesome-nostr, + }} + /> +

+

+ +

+ {hasNip7 ? ( +
+ +
+ ) : ( + + + + )} + + ); + } + return (
@@ -183,36 +289,14 @@ export default function LoginPage() { description="Explanation for public key only login is read-only" />

- {/* - - */}
{altLogins()}
-
- -
-
-

- -

-

- -

-
- -
+ {generateKey()} + {installExtension()}
diff --git a/packages/app/src/lang.json b/packages/app/src/lang.json index 7380af2b..bcaaa8a2 100644 --- a/packages/app/src/lang.json +++ b/packages/app/src/lang.json @@ -118,6 +118,9 @@ "4rYCjn": { "defaultMessage": "Note to Self" }, + "5rOdPG": { + "defaultMessage": "Once you setup your key manager extension and generated a key, you can follow our new users flow to setup your profile and help you find some interesting people on Nostr to follow." + }, "5ykRmX": { "defaultMessage": "Send zap" }, @@ -410,6 +413,9 @@ "OKhRC6": { "defaultMessage": "Share" }, + "OLEm6z": { + "defaultMessage": "Unknown login error" + }, "P61BTu": { "defaultMessage": "Copy Event JSON" }, @@ -479,6 +485,9 @@ "Up5U7K": { "defaultMessage": "Block" }, + "VBadwB": { + "defaultMessage": "Hmm, can't find a key manager extension.. try reloading the page." + }, "VN0+Fz": { "defaultMessage": "Balance: {amount} sats" }, @@ -516,6 +525,9 @@ "XgWvGA": { "defaultMessage": "Reactions" }, + "XzF0aC": { + "defaultMessage": "Key manager extensions are more secure and allow you to easily login to any Nostr client, here are some well known extensions:" + }, "Y31HTH": { "defaultMessage": "Help fund the development of Snort" }, @@ -549,6 +561,10 @@ "bxv59V": { "defaultMessage": "Just now" }, + "c+oiJe": { + "defaultMessage": "Install Extension", + "description": "Heading for install key manager extension" + }, "c35bj2": { "defaultMessage": "If you have an enquiry about your NIP-05 order please DM {link}" }, @@ -687,6 +703,9 @@ "kaaf1E": { "defaultMessage": "now" }, + "lBboHo": { + "defaultMessage": "If you want to try out some others, check out {link} for more!" + }, "lCILNz": { "defaultMessage": "Buy Now" }, @@ -735,6 +754,9 @@ "nN9XTz": { "defaultMessage": "Share your thoughts with {link}" }, + "nOaArs": { + "defaultMessage": "Setup Profile" + }, "nn1qb3": { "defaultMessage": "Your donations are greatly appreciated" }, @@ -833,6 +855,9 @@ "uSV4Ti": { "defaultMessage": "Reposts need to be manually confirmed" }, + "ubtr9S": { + "defaultMessage": "Can't login with private key on 'http://' connection, please use a Nostr key manager extension instead" + }, "usAvMr": { "defaultMessage": "Edit Profile" }, diff --git a/packages/app/src/translations/en.json b/packages/app/src/translations/en.json index d149cdc7..a3907b2e 100644 --- a/packages/app/src/translations/en.json +++ b/packages/app/src/translations/en.json @@ -38,6 +38,7 @@ "4Vmpt4": "Nostr Plebs is one of the first NIP-05 providers in the space and offers a good collection of domains at reasonable prices", "4Z3t5i": "Use imgproxy to compress images", "4rYCjn": "Note to Self", + "5rOdPG": "Once you setup your key manager extension and generated a key, you can follow our new users flow to setup your profile and help you find some interesting people on Nostr to follow.", "5ykRmX": "Send zap", "6ewQqw": "Likes ({n})", "6tUqAb": "Generate a public / private key pair. Do not share your private key with anyone, this acts as your password. Once lost, it cannot be “reset” or recovered. Keep safe!", @@ -133,6 +134,7 @@ "NndBJE": "New users page", "OEW7yJ": "Zaps", "OKhRC6": "Share", + "OLEm6z": "Unknown login error", "P61BTu": "Copy Event JSON", "P7FD0F": "System (Default)", "P7nJT9": "Total today (UTC): {amount} sats", @@ -155,6 +157,7 @@ "TpgeGw": "Hex Salt..", "UQ3pOC": "On Nostr, many people have the same username. User names and identity are separate things. You can get a unique identifier in the next step.", "Up5U7K": "Block", + "VBadwB": "Hmm, can't find a key manager extension.. try reloading the page.", "VN0+Fz": "Balance: {amount} sats", "VOjC1i": "Pick which upload service you want to upload attachments to", "VlJkSk": "{n} muted", @@ -167,6 +170,7 @@ "WxthCV": "e.g. Jack", "X7xU8J": "nsec, npub, nip-05, hex, mnemonic", "XgWvGA": "Reactions", + "XzF0aC": "Key manager extensions are more secure and allow you to easily login to any Nostr client, here are some well known extensions:", "Y31HTH": "Help fund the development of Snort", "YDURw6": "Service URL", "YXA3AH": "Enable reactions", @@ -178,6 +182,7 @@ "aWpBzj": "Show more", "brAXSu": "Pick a username", "bxv59V": "Just now", + "c+oiJe": "Install Extension", "c35bj2": "If you have an enquiry about your NIP-05 order please DM {link}", "cPIKU2": "Following", "cQfLWb": "URL..", @@ -223,6 +228,7 @@ "k2veDA": "Write", "k7sKNy": "Our very own NIP-05 verification service, help support the development of this site and get a shiny special badge on our site!", "kaaf1E": "now", + "lBboHo": "If you want to try out some others, check out {link} for more!", "lCILNz": "Buy Now", "lD3+8a": "Pay", "lTbT3s": "Wallet password", @@ -239,6 +245,7 @@ "nDejmx": "Unblock", "nGBrvw": "Bookmarks", "nN9XTz": "Share your thoughts with {link}", + "nOaArs": "Setup Profile", "nn1qb3": "Your donations are greatly appreciated", "nwZXeh": "{n} blocked", "o6Uy3d": "Only the secret key can be used to publish (sign events), everything else logs you in read-only mode.", @@ -271,6 +278,7 @@ "u4bHcR": "Check out the code here: {link}", "uD/N6c": "Zap {target} {n} sats", "uSV4Ti": "Reposts need to be manually confirmed", + "ubtr9S": "Can't login with private key on 'http://' connection, please use a Nostr key manager extension instead", "usAvMr": "Edit Profile", "ut+2Cd": "Get a partner identifier", "vOKedj": "{n,plural,=1{& {n} other} other{& {n} others}}", @@ -301,4 +309,4 @@ "zjJZBd": "You're ready!", "zonsdq": "Failed to load LNURL service", "zvCDao": "Automatically show latest notes" -} +} \ No newline at end of file