diff options
Diffstat (limited to 'src/state')
-rw-r--r-- | src/state/persisted/__tests__/legacy.test.ts | 13 | ||||
-rw-r--r-- | src/state/persisted/index.ts | 5 | ||||
-rw-r--r-- | src/state/persisted/legacy.ts | 33 | ||||
-rw-r--r-- | src/state/persisted/schema.ts | 7 | ||||
-rw-r--r-- | src/state/session/index.tsx | 4 |
5 files changed, 40 insertions, 22 deletions
diff --git a/src/state/persisted/__tests__/legacy.test.ts b/src/state/persisted/__tests__/legacy.test.ts new file mode 100644 index 000000000..7f4b138a1 --- /dev/null +++ b/src/state/persisted/__tests__/legacy.test.ts @@ -0,0 +1,13 @@ +import {expect, test} from '@jest/globals' + +import {transform} from '#/state/persisted/legacy' +import {defaults, schema} from '#/state/persisted/schema' + +test('defaults', () => { + expect(() => schema.parse(defaults)).not.toThrow() +}) + +test('transform', () => { + const data = transform({}) + expect(() => schema.parse(data)).not.toThrow() +}) diff --git a/src/state/persisted/index.ts b/src/state/persisted/index.ts index 545fdc0e1..67d8b78c6 100644 --- a/src/state/persisted/index.ts +++ b/src/state/persisted/index.ts @@ -26,7 +26,10 @@ export async function init() { try { await migrate() // migrate old store const stored = await store.read() // check for new store - if (!stored) await store.write(defaults) // opt: init new store + if (!stored) { + logger.info('persisted state: initializing default storage') + await store.write(defaults) // opt: init new store + } _state = stored || defaults // return new store logger.log('persisted state: initialized') } catch (e) { diff --git a/src/state/persisted/legacy.ts b/src/state/persisted/legacy.ts index 025877529..c45b18322 100644 --- a/src/state/persisted/legacy.ts +++ b/src/state/persisted/legacy.ts @@ -1,7 +1,7 @@ import AsyncStorage from '@react-native-async-storage/async-storage' import {logger} from '#/logger' -import {defaults, Schema} from '#/state/persisted/schema' +import {defaults, Schema, schema} from '#/state/persisted/schema' import {write, read} from '#/state/persisted/store' /** @@ -66,7 +66,6 @@ type LegacySchema = { const DEPRECATED_ROOT_STATE_STORAGE_KEY = 'root' -// TODO remove, assume that partial data may be here during our refactor export function transform(legacy: Partial<LegacySchema>): Schema { return { colorMode: legacy.shell?.colorMode || defaults.colorMode, @@ -116,7 +115,7 @@ export function transform(legacy: Partial<LegacySchema>): Schema { * local storage AND old storage exists. */ export async function migrate() { - logger.info('persisted state: migrate') + logger.info('persisted state: check need to migrate') try { const rawLegacyData = await AsyncStorage.getItem( @@ -138,6 +137,7 @@ export async function migrate() { ), }) logger.info(`persisted state: debug new data`, { + hasNewData: Boolean(newData), hasExistingLoggedInAccount: Boolean(newData?.session?.currentAccount), numberOfExistingAccounts: newData?.session?.accounts?.length, existingAccountMatchesLegacy: Boolean( @@ -145,27 +145,32 @@ export async function migrate() { legacy?.session?.data?.did, ), }) - } else { - logger.info(`persisted state: no legacy to debug, fresh install`) } - } catch (e) { - logger.error(`persisted state: legacy debugging failed`, {error: e}) + } catch (e: any) { + logger.error(e, {message: `persisted state: legacy debugging failed`}) } if (!alreadyMigrated && rawLegacyData) { logger.info('persisted state: migrating legacy storage') + const legacyData = JSON.parse(rawLegacyData) const newData = transform(legacyData) - await write(newData) - // track successful migrations - logger.log('persisted state: migrated legacy storage') + const validate = schema.safeParse(newData) + + if (validate.success) { + await write(newData) + logger.log('persisted state: migrated legacy storage') + } else { + logger.error('persisted state: legacy data failed validation', { + error: validate.error, + }) + } } else { - // track successful migrations logger.log('persisted state: no migration needed') } - } catch (e) { - logger.error('persisted state: error migrating legacy storage', { - error: String(e), + } catch (e: any) { + logger.error(e, { + message: 'persisted state: error migrating legacy storage', }) } } diff --git a/src/state/persisted/schema.ts b/src/state/persisted/schema.ts index 71f9bd545..5ed8e01f3 100644 --- a/src/state/persisted/schema.ts +++ b/src/state/persisted/schema.ts @@ -2,17 +2,14 @@ import {z} from 'zod' import {deviceLocales} from '#/platform/detection' // only data needed for rendering account page -// TODO agent.resumeSession requires the following fields const accountSchema = z.object({ service: z.string(), did: z.string(), handle: z.string(), - email: z.string(), - emailConfirmed: z.boolean(), + email: z.string().optional(), + emailConfirmed: z.boolean().optional(), refreshJwt: z.string().optional(), // optional because it can expire accessJwt: z.string().optional(), // optional because it can expire - // displayName: z.string().optional(), - // aviUrl: z.string().optional(), }) export type PersistedAccount = z.infer<typeof accountSchema> diff --git a/src/state/session/index.tsx b/src/state/session/index.tsx index e6def1fab..37454187a 100644 --- a/src/state/session/index.tsx +++ b/src/state/session/index.tsx @@ -245,7 +245,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { service: agent.service.toString(), did: agent.session.did, handle: agent.session.handle, - email: agent.session.email!, // TODO this is always defined? + email: agent.session.email, emailConfirmed: agent.session.emailConfirmed || false, refreshJwt: agent.session.refreshJwt, accessJwt: agent.session.accessJwt, @@ -342,7 +342,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { service: agent.service.toString(), did: agent.session.did, handle: agent.session.handle, - email: agent.session.email!, // TODO this is always defined? + email: agent.session.email, emailConfirmed: agent.session.emailConfirmed || false, refreshJwt: agent.session.refreshJwt, accessJwt: agent.session.accessJwt, |