mirror of
https://github.com/luminous-devs/lume.git
synced 2024-09-18 03:03:31 +00:00
update stronghold
This commit is contained in:
parent
a80477b40e
commit
bbfdb139c6
@ -28,7 +28,7 @@
|
||||
"cheerio": "1.0.0-rc.12",
|
||||
"dayjs": "^1.11.9",
|
||||
"destr": "^1.2.2",
|
||||
"framer-motion": "^10.12.22",
|
||||
"framer-motion": "^10.13.0",
|
||||
"get-urls": "^11.0.0",
|
||||
"immer": "^10.0.2",
|
||||
"light-bolt11-decoder": "^3.0.0",
|
||||
|
@ -38,8 +38,8 @@ dependencies:
|
||||
specifier: ^1.2.2
|
||||
version: 1.2.2
|
||||
framer-motion:
|
||||
specifier: ^10.12.22
|
||||
version: 10.12.22(react-dom@18.2.0)(react@18.2.0)
|
||||
specifier: ^10.13.0
|
||||
version: 10.13.0(react-dom@18.2.0)(react@18.2.0)
|
||||
get-urls:
|
||||
specifier: ^11.0.0
|
||||
version: 11.0.0
|
||||
@ -2210,7 +2210,7 @@ packages:
|
||||
postcss: ^8.1.0
|
||||
dependencies:
|
||||
browserslist: 4.21.9
|
||||
caniuse-lite: 1.0.30001516
|
||||
caniuse-lite: 1.0.30001517
|
||||
fraction.js: 4.2.0
|
||||
normalize-range: 0.1.2
|
||||
picocolors: 1.0.0
|
||||
@ -2272,8 +2272,8 @@ packages:
|
||||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001516
|
||||
electron-to-chromium: 1.4.464
|
||||
caniuse-lite: 1.0.30001517
|
||||
electron-to-chromium: 1.4.465
|
||||
node-releases: 2.0.13
|
||||
update-browserslist-db: 1.0.11(browserslist@4.21.9)
|
||||
dev: true
|
||||
@ -2333,8 +2333,8 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/caniuse-lite@1.0.30001516:
|
||||
resolution: {integrity: sha512-Wmec9pCBY8CWbmI4HsjBeQLqDTqV91nFVR83DnZpYyRnPI1wePDsTg0bGLPC5VU/3OIZV1fmxEea1b+tFKe86g==}
|
||||
/caniuse-lite@1.0.30001517:
|
||||
resolution: {integrity: sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==}
|
||||
dev: true
|
||||
|
||||
/ccount@2.0.1:
|
||||
@ -2735,8 +2735,8 @@ packages:
|
||||
/eastasianwidth@0.2.0:
|
||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||
|
||||
/electron-to-chromium@1.4.464:
|
||||
resolution: {integrity: sha512-guZ84yoou4+ILNdj0XEbmGs6DEWj6zpVOWYpY09GU66yEb0DSYvP/biBPzHn0GuW/3RC/pnaYNUWlQE1fJYtgA==}
|
||||
/electron-to-chromium@1.4.465:
|
||||
resolution: {integrity: sha512-XQcuHvEJRMU97UJ75e170mgcITZoz0lIyiaVjk6R+NMTJ8KBIvUHYd1779swgOppUlzxR+JsLpq59PumaXS1jQ==}
|
||||
dev: true
|
||||
|
||||
/emoji-regex@8.0.0:
|
||||
@ -3327,8 +3327,8 @@ packages:
|
||||
resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==}
|
||||
dev: true
|
||||
|
||||
/framer-motion@10.12.22(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-bBGYPOxvxcfzS7/py9MEqDucmXBkVl2g42HNlXXPieSTSGGkr8L7+MilCnrU6uX3HrNk/tcB++1SkWE8BosHFw==}
|
||||
/framer-motion@10.13.0(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-xKhw9VCizmwEHbopOfluaoVunGHSZyMztGbTvsgOYqCjaKu6qtlwWY1J+6GhL41NY1P157JgEikjDm67XCFnvQ==}
|
||||
peerDependencies:
|
||||
react: ^18.0.0
|
||||
react-dom: ^18.0.0
|
||||
@ -6025,8 +6025,8 @@ packages:
|
||||
inline-style-parser: 0.1.1
|
||||
dev: false
|
||||
|
||||
/sucrase@3.33.0:
|
||||
resolution: {integrity: sha512-ARGC7vbufOHfpvyGcZZXFaXCMZ9A4fffOGC5ucOW7+WHDGlAe8LJdf3Jts1sWhDeiI1RSWrKy5Hodl+JWGdW2A==}
|
||||
/sucrase@3.34.0:
|
||||
resolution: {integrity: sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==}
|
||||
engines: {node: '>=8'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
@ -6100,7 +6100,7 @@ packages:
|
||||
postcss-nested: 6.0.1(postcss@8.4.26)
|
||||
postcss-selector-parser: 6.0.13
|
||||
resolve: 1.22.2
|
||||
sucrase: 3.33.0
|
||||
sucrase: 3.34.0
|
||||
transitivePeerDependencies:
|
||||
- ts-node
|
||||
dev: true
|
||||
|
@ -121,8 +121,8 @@ fn main() {
|
||||
tauri_plugin_stronghold::Builder::new(|password| {
|
||||
let config = argon2::Config {
|
||||
lanes: 2,
|
||||
mem_cost: 50_000,
|
||||
time_cost: 30,
|
||||
mem_cost: 10_000,
|
||||
time_cost: 10,
|
||||
thread_mode: argon2::ThreadMode::from_threads(2),
|
||||
variant: argon2::Variant::Argon2id,
|
||||
..Default::default()
|
||||
|
@ -32,12 +32,9 @@ export function CreateStep2Screen() {
|
||||
|
||||
const [passwordInput, setPasswordInput] = useState('password');
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [privkey, setPassword] = useStronghold((state) => [
|
||||
state.privkey,
|
||||
state.setPassword,
|
||||
]);
|
||||
|
||||
const pubkey = useOnboarding((state) => state.privkey);
|
||||
const privkey = useStronghold((state) => state.privkey);
|
||||
const pubkey = useOnboarding((state) => state.pubkey);
|
||||
|
||||
const { save } = useSecureStorage();
|
||||
|
||||
@ -60,9 +57,6 @@ export function CreateStep2Screen() {
|
||||
const onSubmit = async (data: { [x: string]: string }) => {
|
||||
setLoading(true);
|
||||
if (data.password.length > 3) {
|
||||
// add password to local state
|
||||
setPassword(data.password);
|
||||
|
||||
// save privkey to secure storage
|
||||
await save(pubkey, privkey, data.password);
|
||||
|
||||
|
@ -137,7 +137,7 @@ export function CreateStep5Screen() {
|
||||
};
|
||||
|
||||
const update = useMutation({
|
||||
mutationFn: (follows: any) => {
|
||||
mutationFn: (follows: string[]) => {
|
||||
return updateAccount('follows', follows, account.pubkey);
|
||||
},
|
||||
onSuccess: () => {
|
||||
|
@ -32,11 +32,8 @@ export function ImportStep2Screen() {
|
||||
|
||||
const [passwordInput, setPasswordInput] = useState('password');
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [privkey, setPassword] = useStronghold((state) => [
|
||||
state.privkey,
|
||||
state.setPassword,
|
||||
]);
|
||||
|
||||
const privkey = useStronghold((state) => state.privkey);
|
||||
const pubkey = useOnboarding((state) => state.pubkey);
|
||||
|
||||
const { save } = useSecureStorage();
|
||||
@ -60,9 +57,6 @@ export function ImportStep2Screen() {
|
||||
const onSubmit = async (data: { [x: string]: string }) => {
|
||||
setLoading(true);
|
||||
if (data.password.length > 3) {
|
||||
// add password to local state
|
||||
setPassword(data.password);
|
||||
|
||||
// save privkey to secure storage
|
||||
await save(pubkey, privkey, data.password);
|
||||
|
||||
@ -115,9 +109,9 @@ export function ImportStep2Screen() {
|
||||
</div>
|
||||
<div className="text-sm text-zinc-500">
|
||||
<p>
|
||||
Password is use to secure your key store in local machine, when you move
|
||||
to other clients, you just need to copy your private key as nsec or
|
||||
hexstring
|
||||
Password is use to unlock app and secure your key store in local machine.
|
||||
When you move to other clients, you just need to copy your private key as
|
||||
nsec or hexstring
|
||||
</p>
|
||||
</div>
|
||||
<span className="text-sm text-red-400">
|
||||
|
@ -33,13 +33,10 @@ const resolver: Resolver<FormValues> = async (values) => {
|
||||
export function MigrateScreen() {
|
||||
const queryClient = useQueryClient();
|
||||
const navigate = useNavigate();
|
||||
const setPrivkey = useStronghold((state) => state.setPrivkey);
|
||||
|
||||
const [passwordInput, setPasswordInput] = useState('password');
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [setPassword, setPrivkey] = useStronghold((state) => [
|
||||
state.setPassword,
|
||||
state.setPrivkey,
|
||||
]);
|
||||
|
||||
const { account } = useAccount();
|
||||
const { save } = useSecureStorage();
|
||||
@ -63,9 +60,6 @@ export function MigrateScreen() {
|
||||
const onSubmit = async (data: { [x: string]: string }) => {
|
||||
setLoading(true);
|
||||
if (data.password.length > 3) {
|
||||
// add password to local state
|
||||
setPassword(data.password);
|
||||
|
||||
// load private in secure storage
|
||||
try {
|
||||
// save privkey to secure storage
|
||||
|
@ -21,8 +21,7 @@ export function OnboardingScreen() {
|
||||
|
||||
// publish event
|
||||
publish({
|
||||
content:
|
||||
'Running Lume, fighting for better future, join us here: https://lume.nu',
|
||||
content: 'Running Lume, join with me: https://lume.nu',
|
||||
kind: 1,
|
||||
tags: [],
|
||||
});
|
||||
@ -55,18 +54,15 @@ export function OnboardingScreen() {
|
||||
<User pubkey={account.pubkey} time={Math.floor(Date.now() / 1000)} />
|
||||
)}
|
||||
<div className="-mt-6 select-text whitespace-pre-line break-words pl-[49px] text-base text-zinc-100">
|
||||
<p>Running Lume, fighting for better future</p>
|
||||
<p>
|
||||
join us here:{' '}
|
||||
<a
|
||||
href="https://lume.nu"
|
||||
className="font-normal text-fuchsia-500 no-underline hover:text-fuchsia-600"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
https://lume.nu
|
||||
</a>
|
||||
</p>
|
||||
<p>Running Lume, join with me</p>
|
||||
<a
|
||||
href="https://lume.nu"
|
||||
className="font-normal text-fuchsia-500 no-underline hover:text-fuchsia-600"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
https://lume.nu
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -29,13 +29,10 @@ const resolver: Resolver<FormValues> = async (values) => {
|
||||
|
||||
export function UnlockScreen() {
|
||||
const navigate = useNavigate();
|
||||
const setPrivkey = useStronghold((state) => state.setPrivkey);
|
||||
|
||||
const [passwordInput, setPasswordInput] = useState('password');
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [setPrivkey, setPassword] = useStronghold((state) => [
|
||||
state.setPrivkey,
|
||||
state.setPassword,
|
||||
]);
|
||||
|
||||
const { account } = useAccount();
|
||||
const { load } = useSecureStorage();
|
||||
@ -59,9 +56,6 @@ export function UnlockScreen() {
|
||||
const onSubmit = async (data: { [x: string]: string }) => {
|
||||
setLoading(true);
|
||||
if (data.password.length > 3) {
|
||||
// add password to local state
|
||||
setPassword(data.password);
|
||||
|
||||
// load private in secure storage
|
||||
try {
|
||||
const privkey = await load(account.pubkey, data.password);
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
updateLastLogin,
|
||||
} from '@libs/storage';
|
||||
|
||||
import { LoaderIcon, LumeIcon } from '@shared/icons';
|
||||
import { LoaderIcon } from '@shared/icons';
|
||||
|
||||
import { nHoursAgo } from '@utils/date';
|
||||
import { useAccount } from '@utils/hooks/useAccount';
|
||||
@ -175,27 +175,24 @@ export function Root() {
|
||||
}, [status]);
|
||||
|
||||
return (
|
||||
<div className="h-screen w-screen bg-zinc-50 text-zinc-900 dark:bg-black dark:text-zinc-100">
|
||||
<div className="relative h-full overflow-hidden">
|
||||
<div className="h-screen w-screen bg-zinc-50 text-zinc-900 dark:bg-zinc-950 dark:text-zinc-100">
|
||||
<div className="flex h-screen w-full flex-col">
|
||||
<div
|
||||
data-tauri-drag-region
|
||||
className="absolute left-0 top-0 z-20 h-16 w-full bg-transparent"
|
||||
className="relative h-11 shrink-0 border border-zinc-100 bg-white dark:border-zinc-900 dark:bg-black"
|
||||
/>
|
||||
<div className="relative flex h-full flex-col items-center justify-center">
|
||||
<div className="flex flex-col items-center gap-2">
|
||||
<LumeIcon className="h-16 w-16 text-black dark:text-zinc-100" />
|
||||
<div className="relative flex min-h-0 w-full flex-1 items-center justify-center">
|
||||
<div className="flex flex-col items-center justify-center gap-4">
|
||||
<LoaderIcon className="h-6 w-6 animate-spin text-zinc-100" />
|
||||
<div className="text-center">
|
||||
<h3 className="text-lg font-semibold leading-tight text-zinc-900 dark:text-zinc-100">
|
||||
Here's an interesting fact:
|
||||
<h3 className="text-lg font-semibold leading-tight text-zinc-100">
|
||||
Prefetching data...
|
||||
</h3>
|
||||
<p className="font-medium text-zinc-300 dark:text-zinc-600">
|
||||
Bitcoin and Nostr can be used by anyone, and no one can stop you!
|
||||
<p className="text-zinc-600">
|
||||
This may take a few seconds, please don't close app.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute bottom-16 left-1/2 -translate-x-1/2 transform">
|
||||
<LoaderIcon className="h-5 w-5 animate-spin text-black dark:text-zinc-100" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -19,7 +19,7 @@ export function useNewsfeed() {
|
||||
|
||||
useEffect(() => {
|
||||
if (status === 'success' && account) {
|
||||
const follows = account ? JSON.parse(account.follows) : [];
|
||||
const follows = account ? JSON.parse(account.follows as string) : [];
|
||||
|
||||
const filter: NDKFilter = {
|
||||
kinds: [1, 6],
|
||||
@ -30,7 +30,6 @@ export function useNewsfeed() {
|
||||
sub.current = ndk.subscribe(filter, { closeOnEose: false });
|
||||
|
||||
sub.current.addListener('event', (event: NDKEvent) => {
|
||||
console.log('new note: ', event);
|
||||
// add to db
|
||||
createNote(
|
||||
event.id,
|
||||
@ -46,7 +45,9 @@ export function useNewsfeed() {
|
||||
}
|
||||
|
||||
return () => {
|
||||
sub.current.stop();
|
||||
if (sub.current) {
|
||||
sub.current.stop();
|
||||
}
|
||||
};
|
||||
}, [status]);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import { useStronghold } from '@stores/stronghold';
|
||||
import { useAccount } from '@utils/hooks/useAccount';
|
||||
|
||||
export function Protected({ children }: { children: ReactNode }) {
|
||||
const password = useStronghold((state) => state.password);
|
||||
const privkey = useStronghold((state) => state.privkey);
|
||||
const { status, account } = useAccount();
|
||||
|
||||
if (status === 'success' && !account) {
|
||||
@ -17,7 +17,7 @@ export function Protected({ children }: { children: ReactNode }) {
|
||||
return <Navigate to="/auth/migrate" replace />;
|
||||
}
|
||||
|
||||
if (status === 'success' && account && !password) {
|
||||
if (status === 'success' && account && !privkey) {
|
||||
return <Navigate to="/auth/unlock" replace />;
|
||||
}
|
||||
|
||||
|
@ -3,11 +3,8 @@ import { create } from 'zustand';
|
||||
interface OnboardingState {
|
||||
profile: { [x: string]: string };
|
||||
pubkey: string;
|
||||
privkey: string;
|
||||
createProfile: (data: { [x: string]: string }) => void;
|
||||
setPubkey: (pubkey: string) => void;
|
||||
setPrivkey: (privkey: string) => void;
|
||||
clearPrivkey: (privkey: string) => void;
|
||||
}
|
||||
|
||||
export const useOnboarding = create<OnboardingState>((set) => ({
|
||||
@ -20,10 +17,4 @@ export const useOnboarding = create<OnboardingState>((set) => ({
|
||||
setPubkey: (pubkey: string) => {
|
||||
set({ pubkey: pubkey });
|
||||
},
|
||||
setPrivkey: (privkey: string) => {
|
||||
set({ privkey: privkey });
|
||||
},
|
||||
clearPrivkey: () => {
|
||||
set({ privkey: '' });
|
||||
},
|
||||
}));
|
||||
|
@ -1,19 +1,22 @@
|
||||
import { create } from 'zustand';
|
||||
import { createJSONStorage, persist } from 'zustand/middleware';
|
||||
|
||||
interface StrongholdState {
|
||||
password: null | string;
|
||||
privkey: null | string;
|
||||
setPassword: (password: string) => void;
|
||||
setPrivkey: (privkey: string) => void;
|
||||
}
|
||||
|
||||
export const useStronghold = create<StrongholdState>((set) => ({
|
||||
password: null,
|
||||
privkey: null,
|
||||
setPassword: (password: string) => {
|
||||
set({ password: password });
|
||||
},
|
||||
setPrivkey: (privkey: string) => {
|
||||
set({ privkey: privkey });
|
||||
},
|
||||
}));
|
||||
export const useStronghold = create<StrongholdState>()(
|
||||
persist(
|
||||
(set) => ({
|
||||
privkey: null,
|
||||
setPrivkey: (privkey: string) => {
|
||||
set({ privkey: privkey });
|
||||
},
|
||||
}),
|
||||
{
|
||||
name: 'stronghold',
|
||||
storage: createJSONStorage(() => sessionStorage),
|
||||
}
|
||||
)
|
||||
);
|
||||
|
@ -5,14 +5,12 @@ import { useNDK } from '@libs/ndk/provider';
|
||||
import { useStronghold } from '@stores/stronghold';
|
||||
|
||||
import { useAccount } from '@utils/hooks/useAccount';
|
||||
import { useSecureStorage } from '@utils/hooks/useSecureStorage';
|
||||
|
||||
export function usePublish() {
|
||||
const { ndk } = useNDK();
|
||||
const { account } = useAccount();
|
||||
const { load } = useSecureStorage();
|
||||
|
||||
const cachePrivkey = useStronghold((state) => state.privkey);
|
||||
const privkey = useStronghold((state) => state.privkey);
|
||||
|
||||
const publish = async ({
|
||||
content,
|
||||
@ -23,12 +21,7 @@ export function usePublish() {
|
||||
kind: NDKKind | number;
|
||||
tags: string[][];
|
||||
}): Promise<NDKEvent> => {
|
||||
let privkey: string;
|
||||
if (cachePrivkey) {
|
||||
privkey = cachePrivkey;
|
||||
} else {
|
||||
privkey = await load(account.pubkey);
|
||||
}
|
||||
if (!privkey) throw new Error('Private key not found');
|
||||
|
||||
const event = new NDKEvent(ndk);
|
||||
const signer = new NDKPrivateKeySigner(privkey);
|
||||
|
@ -1,13 +1,9 @@
|
||||
import { appConfigDir } from '@tauri-apps/api/path';
|
||||
import { Stronghold } from 'tauri-plugin-stronghold-api';
|
||||
|
||||
import { useStronghold } from '@stores/stronghold';
|
||||
|
||||
const dir = await appConfigDir();
|
||||
|
||||
export function useSecureStorage() {
|
||||
const password = useStronghold((state) => state.password);
|
||||
|
||||
async function getClient(stronghold: Stronghold) {
|
||||
try {
|
||||
return await stronghold.loadClient('lume');
|
||||
@ -16,22 +12,16 @@ export function useSecureStorage() {
|
||||
}
|
||||
}
|
||||
|
||||
const save = async (key: string, value: string, userpass?: string) => {
|
||||
const stronghold = await Stronghold.load(
|
||||
`${dir}lume.stronghold`,
|
||||
userpass ? userpass : password
|
||||
);
|
||||
const save = async (key: string, value: string, password: string) => {
|
||||
const stronghold = await Stronghold.load(`${dir}lume.stronghold`, password);
|
||||
const client = await getClient(stronghold);
|
||||
const store = client.getStore();
|
||||
await store.insert(key, Array.from(new TextEncoder().encode(value)));
|
||||
return await stronghold.save();
|
||||
};
|
||||
|
||||
const load = async (key: string, userpass?: string) => {
|
||||
const stronghold = await Stronghold.load(
|
||||
`${dir}lume.stronghold`,
|
||||
userpass ? userpass : password
|
||||
);
|
||||
const load = async (key: string, password: string) => {
|
||||
const stronghold = await Stronghold.load(`${dir}lume.stronghold`, password);
|
||||
const client = await getClient(stronghold);
|
||||
const store = client.getStore();
|
||||
const value = await store.get(key);
|
||||
|
Loading…
Reference in New Issue
Block a user