mirror of
https://github.com/lumehq/lume.git
synced 2025-03-28 02:31:49 +01:00
wip: multi account
This commit is contained in:
parent
0e6fc65b08
commit
4f4e2f5ccd
BIN
public/wallpapers/1.png
Normal file
BIN
public/wallpapers/1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.8 MiB |
11
src/app.tsx
11
src/app.tsx
@ -24,7 +24,7 @@ export default function App() {
|
||||
|
||||
const accountLoader = async () => {
|
||||
try {
|
||||
const account = await db.checkAccount();
|
||||
const totalAccount = await db.checkAccount();
|
||||
|
||||
const stronghold = sessionStorage.getItem('stronghold');
|
||||
const privkey = JSON.parse(stronghold).state.privkey || null;
|
||||
@ -32,7 +32,7 @@ export default function App() {
|
||||
const onboarding = localStorage.getItem('onboarding');
|
||||
const step = JSON.parse(onboarding).state.step || null;
|
||||
|
||||
if (!account) {
|
||||
if (totalAccount === 0) {
|
||||
return redirect('/auth/welcome');
|
||||
} else {
|
||||
if (step) {
|
||||
@ -251,6 +251,13 @@ export default function App() {
|
||||
return { Component: UnlockScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'lock',
|
||||
async lazy() {
|
||||
const { LockScreen } = await import('@app/auth/lock');
|
||||
return { Component: LockScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'migrate',
|
||||
async lazy() {
|
||||
|
@ -66,7 +66,7 @@ export function CreateStep2Screen() {
|
||||
if (!db.secureDB) db.secureDB = stronghold;
|
||||
|
||||
// save privkey to secure storage
|
||||
await db.secureSave(pubkey, privkey);
|
||||
await db.secureSave(pubkey, privkey, pubkey);
|
||||
|
||||
// redirect to next step
|
||||
navigate('/auth/create/step-3', { replace: true });
|
||||
|
@ -66,7 +66,7 @@ export function ImportStep2Screen() {
|
||||
if (!db.secureDB) db.secureDB = stronghold;
|
||||
|
||||
// save privkey to secure storage
|
||||
await db.secureSave(pubkey, privkey);
|
||||
await db.secureSave(pubkey, privkey, pubkey);
|
||||
|
||||
// redirect to next step
|
||||
navigate('/auth/import/step-3', { replace: true });
|
||||
|
10
src/app/auth/lock.tsx
Normal file
10
src/app/auth/lock.tsx
Normal file
@ -0,0 +1,10 @@
|
||||
export function LockScreen() {
|
||||
return (
|
||||
<div
|
||||
className="h-full w-full bg-cover bg-center"
|
||||
style={{ backgroundImage: 'url(/wallpapers/1.png)' }}
|
||||
>
|
||||
<p>TODO</p>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -33,6 +33,7 @@ export function UnlockScreen() {
|
||||
const navigate = useNavigate();
|
||||
const setPrivkey = useStronghold((state) => state.setPrivkey);
|
||||
const setWalletConnectURL = useStronghold((state) => state.setWalletConnectURL);
|
||||
const resetStronghold = useStronghold((state) => state.reset);
|
||||
|
||||
const [showPassword, setShowPassword] = useState<boolean>(false);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
@ -73,6 +74,8 @@ export function UnlockScreen() {
|
||||
const logout = async () => {
|
||||
// remove account
|
||||
db.accountLogout();
|
||||
// reset stronghold
|
||||
resetStronghold();
|
||||
// redirect to welcome screen
|
||||
navigate('/auth/welcome');
|
||||
};
|
||||
@ -146,7 +149,7 @@ export function UnlockScreen() {
|
||||
to="/auth/reset"
|
||||
className="inline-flex h-10 w-full items-center justify-center rounded-lg text-center text-sm font-medium text-white/70 hover:bg-white/20"
|
||||
>
|
||||
Reset password if you still have private key
|
||||
Reset password if you still have a private key
|
||||
</Link>
|
||||
<button
|
||||
type="button"
|
||||
|
@ -68,7 +68,7 @@ export function SplashScreen() {
|
||||
</h3>
|
||||
{ndk ? (
|
||||
<p className="text-sm text-white/50">
|
||||
Ensure all your data is sync across all Nostr clients, it may take a few
|
||||
Ensure all your data is sync across all Nostr clients. It may take a few
|
||||
seconds, please don't close app.
|
||||
</p>
|
||||
) : null}
|
||||
|
@ -35,7 +35,6 @@ export class LumeStorage {
|
||||
|
||||
const client = await this.getSecureClient(clientKey);
|
||||
const store = client.getStore();
|
||||
console.log('insert key: ', key);
|
||||
|
||||
await store.insert(key, Array.from(new TextEncoder().encode(value)));
|
||||
await this.secureDB.save();
|
||||
@ -46,7 +45,6 @@ export class LumeStorage {
|
||||
|
||||
const client = await this.getSecureClient(clientKey);
|
||||
const store = client.getStore();
|
||||
console.log('get key: ', key);
|
||||
|
||||
const value = await store.get(key);
|
||||
if (!value) return null;
|
||||
@ -60,10 +58,10 @@ export class LumeStorage {
|
||||
}
|
||||
|
||||
public async checkAccount() {
|
||||
const result: Array<Account> = await this.db.select(
|
||||
'SELECT * FROM accounts WHERE is_active = 1;'
|
||||
const result: Array<{ total: string }> = await this.db.select(
|
||||
'SELECT COUNT(*) AS "total" FROM accounts;'
|
||||
);
|
||||
return result.length > 0;
|
||||
return parseInt(result[0].total);
|
||||
}
|
||||
|
||||
public async getActiveAccount() {
|
||||
@ -92,16 +90,24 @@ export class LumeStorage {
|
||||
}
|
||||
|
||||
public async createAccount(npub: string, pubkey: string) {
|
||||
const res = await this.db.execute(
|
||||
'INSERT OR IGNORE INTO accounts (npub, pubkey, privkey, is_active) VALUES ($1, $2, $3, $4);',
|
||||
[npub, pubkey, 'privkey is stored in secure storage', 1]
|
||||
const existAccounts: Array<Account> = await this.db.select(
|
||||
'SELECT * FROM accounts WHERE pubkey = $1 ORDER BY id DESC LIMIT 1;',
|
||||
[pubkey]
|
||||
);
|
||||
if (res) {
|
||||
const account = await this.getActiveAccount();
|
||||
return account;
|
||||
|
||||
if (existAccounts.length > 0) {
|
||||
await this.db.execute("UPDATE accounts SET is_active = '1' WHERE pubkey = $1;", [
|
||||
pubkey,
|
||||
]);
|
||||
} else {
|
||||
console.error('create account failed');
|
||||
await this.db.execute(
|
||||
'INSERT OR IGNORE INTO accounts (npub, pubkey, privkey, is_active) VALUES ($1, $2, $3, $4);',
|
||||
[npub, pubkey, 'privkey is stored in secure storage', 1]
|
||||
);
|
||||
}
|
||||
|
||||
const account = await this.getActiveAccount();
|
||||
return account;
|
||||
}
|
||||
|
||||
public async updateAccount(column: string, value: string | string[]) {
|
||||
@ -191,7 +197,8 @@ export class LumeStorage {
|
||||
|
||||
public async countTotalEvents() {
|
||||
const result: Array<{ total: string }> = await this.db.select(
|
||||
'SELECT COUNT(*) AS "total" FROM events;'
|
||||
'SELECT COUNT(*) AS "total" FROM events WHERE account_id = $1;',
|
||||
[this.account.id]
|
||||
);
|
||||
return parseInt(result[0].total);
|
||||
}
|
||||
@ -206,8 +213,8 @@ export class LumeStorage {
|
||||
};
|
||||
|
||||
const query: DBEvent[] = await this.db.select(
|
||||
'SELECT * FROM events GROUP BY root_id ORDER BY created_at DESC LIMIT $1 OFFSET $2;',
|
||||
[limit, offset]
|
||||
'SELECT * FROM events WHERE account_id = $1 GROUP BY root_id ORDER BY created_at DESC LIMIT $2 OFFSET $3;',
|
||||
[this.account.id, limit, offset]
|
||||
);
|
||||
|
||||
if (query && query.length > 0) {
|
||||
@ -264,8 +271,8 @@ export class LumeStorage {
|
||||
};
|
||||
|
||||
const query: DBEvent[] = await this.db.select(
|
||||
`SELECT * FROM events WHERE kinds IN (${authorsArr}) ORDER BY created_at DESC LIMIT $1 OFFSET $2;`,
|
||||
[limit, offset]
|
||||
`SELECT * FROM events WHERE kinds IN (${authorsArr}) AND account_id = $1 ORDER BY created_at DESC LIMIT $2 OFFSET $3;`,
|
||||
[this.account.id, limit, offset]
|
||||
);
|
||||
|
||||
if (query && query.length > 0) {
|
||||
@ -284,7 +291,8 @@ export class LumeStorage {
|
||||
|
||||
public async isEventsEmpty() {
|
||||
const results: DBEvent[] = await this.db.select(
|
||||
'SELECT * FROM events ORDER BY id DESC LIMIT 1;'
|
||||
'SELECT * FROM events WHERE account_id = $1 ORDER BY id DESC LIMIT 1;',
|
||||
[this.account.id]
|
||||
);
|
||||
|
||||
return results.length < 1;
|
||||
@ -351,9 +359,6 @@ export class LumeStorage {
|
||||
}
|
||||
|
||||
public async accountLogout() {
|
||||
// delete all events
|
||||
await this.db.execute('DELETE FROM events WHERE account_id = $1;', [this.account.id]);
|
||||
|
||||
// update current account status
|
||||
await this.db.execute("UPDATE accounts SET is_active = '0' WHERE id = $1;", [
|
||||
this.account.id,
|
||||
|
@ -11,13 +11,13 @@ export function Logout() {
|
||||
const { db } = useStorage();
|
||||
|
||||
const navigate = useNavigate();
|
||||
const clearPrivkey = useStronghold((state) => state.clearPrivkey);
|
||||
const resetStronghold = useStronghold((state) => state.reset);
|
||||
|
||||
const logout = async () => {
|
||||
// remove account
|
||||
db.accountLogout();
|
||||
// clear privkey in session storage
|
||||
clearPrivkey();
|
||||
resetStronghold();
|
||||
// redirect to welcome screen
|
||||
navigate('/auth/welcome');
|
||||
};
|
||||
|
@ -56,7 +56,7 @@ export function EventLoader({ firstTime }: { firstTime: boolean }) {
|
||||
) : (
|
||||
<div className="text-center">
|
||||
<h3 className="font-semibold leading-tight">
|
||||
Downloading all events from your last login...
|
||||
Downloading all events while you're away...
|
||||
</h3>
|
||||
</div>
|
||||
)}
|
||||
|
@ -9,6 +9,7 @@ interface StrongholdState {
|
||||
setWalletConnectURL: (uri: string) => void;
|
||||
clearPrivkey: () => void;
|
||||
setIsFetched: () => void;
|
||||
reset: () => void;
|
||||
}
|
||||
|
||||
export const useStronghold = create<StrongholdState>()(
|
||||
@ -29,6 +30,9 @@ export const useStronghold = create<StrongholdState>()(
|
||||
setIsFetched: () => {
|
||||
set({ isFetched: true });
|
||||
},
|
||||
reset: () => {
|
||||
set({ privkey: null, walletConnectURL: null, isFetched: false });
|
||||
},
|
||||
}),
|
||||
{
|
||||
name: 'stronghold',
|
||||
|
Loading…
x
Reference in New Issue
Block a user