Live video on the AT Protocol
at next 69 lines 2.0 kB view raw
1import { SimpleStore } from "@atproto-labs/simple-store"; 2import { Jwk, Key } from "@atproto/jwk"; 3import { JoseKey } from "@atproto/jwk-jose"; 4import Storage from "expo-sqlite/kv-store"; 5 6interface HasDPoPKey { 7 dpopKey: Key | undefined; 8} 9 10const NAMESPACE = `@@atproto/oauth-client-react-native`; 11 12/** 13 * An expo-sqlite store that handles serializing and deserializing 14 * our Jose DPoP keys. Wraps SQLiteKVStore or whatever other SimpleStore 15 * that a user might provide. 16 */ 17export class JoseKeyStore<T extends HasDPoPKey> { 18 private store: SimpleStore<string, string>; 19 constructor(store: SimpleStore<string, string>) { 20 this.store = store; 21 } 22 23 async get(key: string): Promise<T | undefined> { 24 const itemStr = await this.store.get(key); 25 if (!itemStr) return undefined; 26 const item = JSON.parse(itemStr) as T; 27 if (item.dpopKey) { 28 item.dpopKey = new JoseKey(item.dpopKey as unknown as Jwk); 29 } 30 return item; 31 } 32 33 async set(key: string, value: T): Promise<void> { 34 if (value.dpopKey) { 35 value = { 36 ...value, 37 dpopKey: (value.dpopKey as JoseKey).privateJwk, 38 }; 39 } 40 return await this.store.set(key, JSON.stringify(value)); 41 } 42 43 async del(key: string): Promise<void> { 44 return await this.store.del(key); 45 } 46} 47 48/** 49 * Simple wrapper around expo-sqlite's KVStore. Default implementation 50 * unless a user brings their own KV store. 51 */ 52export class SQLiteKVStore implements SimpleStore<string, string> { 53 private namespace: string; 54 constructor(namespace: string) { 55 this.namespace = `${NAMESPACE}:${namespace}`; 56 } 57 58 async get(key: string): Promise<string | undefined> { 59 return (await Storage.getItem(`${this.namespace}:${key}`)) ?? undefined; 60 } 61 62 async set(key: string, value: string): Promise<void> { 63 return await Storage.setItem(`${this.namespace}:${key}`, value); 64 } 65 66 async del(key: string): Promise<void> { 67 return await Storage.removeItem(`${this.namespace}:${key}`); 68 } 69}