diff --git a/src/components/Header.svelte b/src/components/Header.svelte index 40ee3e2..5f05ed5 100644 --- a/src/components/Header.svelte +++ b/src/components/Header.svelte @@ -1,5 +1,8 @@ diff --git a/src/components/auth/backup/AreYouSure.svelte b/src/components/auth/backup/AreYouSure.svelte index a9f7ba7..a516557 100644 --- a/src/components/auth/backup/AreYouSure.svelte +++ b/src/components/auth/backup/AreYouSure.svelte @@ -1,13 +1,27 @@ @@ -20,15 +34,15 @@ Without a backup device, if you lose this device or reset your browser, you will not be able to recover your account data.

- - + YOLO—I'll risk just one device for now - + diff --git a/src/components/auth/backup/Backup.svelte b/src/components/auth/backup/Backup.svelte index 7300ea9..f16a18a 100644 --- a/src/components/auth/backup/Backup.svelte +++ b/src/components/auth/backup/Backup.svelte @@ -1,5 +1,6 @@ - - - diff --git a/src/components/auth/link/.gitkeep b/src/components/auth/link/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/components/auth/link/DelegateAccount.svelte b/src/components/auth/link/DelegateAccount.svelte new file mode 100644 index 0000000..a5d9cc9 --- /dev/null +++ b/src/components/auth/link/DelegateAccount.svelte @@ -0,0 +1,162 @@ + + +{#if view === 'backup-device'} + + +{:else if view === 'delegate-account'} + + +{/if} diff --git a/src/components/auth/link/LinkDevice.svelte b/src/components/auth/link/LinkDevice.svelte new file mode 100644 index 0000000..26338f0 --- /dev/null +++ b/src/components/auth/link/LinkDevice.svelte @@ -0,0 +1,68 @@ + + + + diff --git a/src/components/icons/Shield.svelte b/src/components/icons/Shield.svelte new file mode 100644 index 0000000..cef753f --- /dev/null +++ b/src/components/icons/Shield.svelte @@ -0,0 +1,14 @@ + + + diff --git a/src/lib/auth/backup.ts b/src/lib/auth/backup.ts new file mode 100644 index 0000000..0ac89b8 --- /dev/null +++ b/src/lib/auth/backup.ts @@ -0,0 +1,29 @@ +import * as webnative from 'webnative' +import type FileSystem from 'webnative/fs/index' + +export type BackupStatus = { created: boolean } | null + +export const setBackupStatus = async (fs: FileSystem, status: BackupStatus): Promise => { + const backupStatusPath = webnative.path.file('private', 'backup-status.json') + await fs.write(backupStatusPath, JSON.stringify(status)) + await fs.publish() +} + +export const getBackupStatus = async (fs: FileSystem): Promise => { + const backupStatusPath = webnative.path.file('private', 'backup-status.json') + + if (await fs.exists(backupStatusPath)) { + const fileContent = await fs.read(backupStatusPath) + + if (typeof fileContent === 'string') { + return JSON.parse(fileContent) as BackupStatus + } + + console.warn('Unable to load backup status') + + return { created: false } + } else { + return { created: false } + } +} + diff --git a/src/lib/auth/linking.ts b/src/lib/auth/linking.ts new file mode 100644 index 0000000..b3c25ba --- /dev/null +++ b/src/lib/auth/linking.ts @@ -0,0 +1,14 @@ +import * as webnative from 'webnative' +import type { account } from 'webnative' + +export const createAccountLinkingConsumer = async ( + username: string +): Promise => { + return await webnative.account.createConsumer({ username }) +} + +export const createAccountLinkingProducer = async ( + username: string +): Promise => { + return await webnative.account.createProducer({ username }) +} \ No newline at end of file diff --git a/src/lib/common/webnative.ts b/src/lib/common/webnative.ts index cca3c2c..45c29b2 100644 --- a/src/lib/common/webnative.ts +++ b/src/lib/common/webnative.ts @@ -1,12 +1,16 @@ import * as webnative from 'webnative' -import type FileSystem from 'webnative/fs/index' import { setup } from 'webnative' import { asyncDebounce } from '$lib/common/utils' import { filesystemStore, sessionStore } from '../../stores' +import { getBackupStatus, type BackupStatus } from '$lib/auth/backup' // runfission.net = staging -setup.endpoints({ api: 'https://runfission.net', lobby: 'https://auth.runfission.net', user: 'fissionuser.net' }) +setup.endpoints({ + api: 'https://runfission.net', + lobby: 'https://auth.runfission.net', + user: 'fissionuser.net' +}) let state: webnative.AppState @@ -15,6 +19,8 @@ setup.debug({ enabled: false }) export const initialize = async (): Promise => { try { + let backupStatus: BackupStatus = null + state = await webnative.app({ useWnfs: true }) switch (state.scenario) { @@ -22,16 +28,21 @@ export const initialize = async (): Promise => { sessionStore.set({ username: '', authed: false, - loading: false + loading: false, + backupCreated: null }) break case webnative.AppScenario.Authed: + backupStatus = await getBackupStatus(state.fs) + sessionStore.set({ username: state.username, authed: state.authenticated, - loading: false + loading: false, + backupCreated: backupStatus.created }) + filesystemStore.set(state.fs) break @@ -77,7 +88,7 @@ export const isUsernameAvailable = async ( export const register = async (username: string): Promise => { const { success } = await webnative.account.register({ username }) - const fs = await bootstrapFilesystem() + const fs = await webnative.bootstrapRootFileSystem() filesystemStore.set(fs) sessionStore.update(session => ({ @@ -89,12 +100,13 @@ export const register = async (username: string): Promise => { return success } -export const bootstrapFilesystem = async (): Promise => { - return await webnative.bootstrapRootFileSystem() -} +export const loadAccount = async (username: string): Promise => { + const fs = await webnative.loadRootFileSystem() + filesystemStore.set(fs) -// interface StateFS { -// fs?: FileSystem -// } - -// export const getWNFS: () => FileSystem = () => (state as StateFS)?.fs + sessionStore.update(session => ({ + ...session, + username, + authed: true + })) +} \ No newline at end of file diff --git a/src/lib/session.ts b/src/lib/session.ts index 6dc88a3..dc0eb2a 100644 --- a/src/lib/session.ts +++ b/src/lib/session.ts @@ -4,6 +4,7 @@ export type Session = { username: string authed: boolean loading: boolean + backupCreated: boolean error?: SessionError } diff --git a/src/lib/views.ts b/src/lib/views.ts index ac1b04a..0442adf 100644 --- a/src/lib/views.ts +++ b/src/lib/views.ts @@ -1 +1 @@ -export type BackupView = 'backup' | 'backup-device' | 'are-you-sure' \ No newline at end of file +export type BackupView = 'backup' | 'are-you-sure' \ No newline at end of file diff --git a/src/routes/__layout.svelte b/src/routes/__layout.svelte index e9ca22d..87c1fc1 100644 --- a/src/routes/__layout.svelte +++ b/src/routes/__layout.svelte @@ -32,9 +32,6 @@ const init = async () => { await initialize() - - // TODO: Remove this debugging statement - console.log('session at init', session) } const clearNotification = () => { diff --git a/src/routes/backup.svelte b/src/routes/backup.svelte index b9374fe..9eadad1 100644 --- a/src/routes/backup.svelte +++ b/src/routes/backup.svelte @@ -1,10 +1,15 @@ + + diff --git a/src/routes/link-device.svelte b/src/routes/link-device.svelte new file mode 100644 index 0000000..1b97595 --- /dev/null +++ b/src/routes/link-device.svelte @@ -0,0 +1,5 @@ + + + diff --git a/src/stores.ts b/src/stores.ts index 43af42f..74f45f8 100644 --- a/src/stores.ts +++ b/src/stores.ts @@ -10,11 +10,12 @@ import type { Theme } from '$lib/theme' export const theme: Writable = writable(loadTheme()) export const sessionStore: Writable = writable({ - username: '', + username: null, authed: false, - loading: true + loading: true, + backupCreated: null }) export const filesystemStore: Writable = writable(null) -export const deviceStore: Writable = writable({ isMobile: true }) \ No newline at end of file +export const deviceStore: Writable = writable({ isMobile: true })