feat: install extension on insecure connections

This commit is contained in:
Kieran 2023-03-16 18:30:50 +00:00
parent 424c7c79d7
commit ff0f6efa29
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
4 changed files with 165 additions and 48 deletions

View File

@ -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);

View File

@ -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<ArtworkEntry>();
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 (
<>
<div className="flex login-or">
<FormattedMessage defaultMessage="OR" description="Seperator text for Login / Generate Key" />
<div className="divider w-max"></div>
</div>
<h1 dir="auto">
<FormattedMessage defaultMessage="Create an Account" description="Heading for generate key flow" />
</h1>
<p>
<FormattedMessage
defaultMessage="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!"
description="Note about key security before generating a new key"
/>
</p>
<div className="login-actions">
<button type="button" onClick={() => makeRandomKey()}>
<FormattedMessage defaultMessage="Generate Key" description="Button: Generate a new key" />
</button>
</div>
</>
);
}
function installExtension() {
if (isSecure) return;
return (
<>
<div className="flex login-or">
<FormattedMessage defaultMessage="OR" description="Seperator text for Login / Generate Key" />
<div className="divider w-max"></div>
</div>
<h1 dir="auto">
<FormattedMessage
defaultMessage="Install Extension"
description="Heading for install key manager extension"
/>
</h1>
<p>
<FormattedMessage defaultMessage="Key manager extensions are more secure and allow you to easily login to any Nostr client, here are some well known extensions:" />
</p>
<ul>
<li>
<a href="https://getalby.com/" target="_blank" rel="noreferrer">
Alby
</a>
</li>
<li>
<a
href="https://chrome.google.com/webstore/detail/nos2x/kpgefcfmnafjgpblomihpgmejjdanjjp"
target="_blank"
rel="noreferrer">
nos2x
</a>
</li>
</ul>
<p>
<FormattedMessage
defaultMessage="If you want to try out some others, check out {link} for more!"
values={{
link: <a href="https://github.com/aljazceru/awesome-nostr#browser-extensions">awesome-nostr</a>,
}}
/>
</p>
<p>
<FormattedMessage 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." />
</p>
{hasNip7 ? (
<div className="login-actions">
<button type="button" onClick={() => doNip07Login().then(() => navigate("/new/username"))}>
<FormattedMessage defaultMessage="Setup Profile" />
</button>
</div>
) : (
<b className="error">
<FormattedMessage defaultMessage="Hmm, can't find a key manager extension.. try reloading the page." />
</b>
)}
</>
);
}
return (
<div className="login">
<div>
@ -183,36 +289,14 @@ export default function LoginPage() {
description="Explanation for public key only login is read-only"
/>
</p>
{/* <a href="">
<FormattedMessage
defaultMessage="Why is there no password field?"
description="Link to why your private key is your password"
/>
</a>*/}
<div dir="auto" className="login-actions">
<button type="button" onClick={doLogin}>
<FormattedMessage defaultMessage="Login" description="Login button" />
</button>
{altLogins()}
</div>
<div className="flex login-or">
<FormattedMessage defaultMessage="OR" description="Seperator text for Login / Generate Key" />
<div className="divider w-max"></div>
</div>
<h1 dir="auto">
<FormattedMessage defaultMessage="Create an Account" description="Heading for generate key flow" />
</h1>
<p>
<FormattedMessage
defaultMessage="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!"
description="Note about key security before generating a new key"
/>
</p>
<div className="login-actions">
<button type="button" onClick={() => makeRandomKey()}>
<FormattedMessage defaultMessage="Generate Key" description="Button: Generate a new key" />
</button>
</div>
{generateKey()}
{installExtension()}
</div>
</div>
<div>

View File

@ -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"
},

View File

@ -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"
}
}