|
|
@ -9,59 +9,39 @@ import { |
|
|
|
} from "./tables/settings"; |
|
|
|
import { AppString } from "@/constants/app"; |
|
|
|
|
|
|
|
// a separate DB because the seed is super-sensitive data
|
|
|
|
type SensitiveTables = { |
|
|
|
accounts: Table<Account>; |
|
|
|
}; |
|
|
|
|
|
|
|
// Define types for tables that hold sensitive and non-sensitive data
|
|
|
|
type SensitiveTables = { accounts: Table<Account> }; |
|
|
|
type NonsensitiveTables = { |
|
|
|
contacts: Table<Contact>; |
|
|
|
settings: Table<Settings>; |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* In order to make the next line be acceptable, the program needs to have its linter suppress a rule: |
|
|
|
* https://typescript-eslint.io/rules/no-unnecessary-type-constraint/
|
|
|
|
* |
|
|
|
* and change *any* to *unknown* |
|
|
|
* |
|
|
|
* https://9to5answer.com/how-to-bypass-warning-unexpected-any-specify-a-different-type-typescript-eslint-no-explicit-any
|
|
|
|
*/ |
|
|
|
// Using 'unknown' instead of 'any' for stricter typing and to avoid TypeScript warnings
|
|
|
|
export type SensitiveDexie<T extends unknown = SensitiveTables> = BaseDexie & T; |
|
|
|
export const accountsDB = new BaseDexie("TimeSafariAccounts") as SensitiveDexie; |
|
|
|
const SensitiveSchemas = Object.assign({}, AccountsSchema); |
|
|
|
|
|
|
|
export type NonsensitiveDexie<T extends unknown = NonsensitiveTables> = |
|
|
|
BaseDexie & T; |
|
|
|
export const db = new BaseDexie("TimeSafari") as NonsensitiveDexie; |
|
|
|
const NonsensitiveSchemas = Object.assign({}, ContactsSchema, SettingsSchema); |
|
|
|
|
|
|
|
/** |
|
|
|
* Needed to enable a special webpack setting to allow *await* below: |
|
|
|
* https://stackoverflow.com/questions/72474803/error-the-top-level-await-experiment-is-not-enabled-set-experiments-toplevelaw
|
|
|
|
*/ |
|
|
|
// Initialize Dexie databases for sensitive and non-sensitive data
|
|
|
|
export const accountsDB = new BaseDexie("TimeSafariAccounts") as SensitiveDexie; |
|
|
|
const SensitiveSchemas = { ...AccountsSchema }; |
|
|
|
|
|
|
|
/** |
|
|
|
* Create password and place password in localStorage. |
|
|
|
* |
|
|
|
* It's good practice to keep the data encrypted at rest, so we'll do that even |
|
|
|
* if the secret is stored right next to the app. |
|
|
|
*/ |
|
|
|
export const db = new BaseDexie("TimeSafari") as NonsensitiveDexie; |
|
|
|
const NonsensitiveSchemas = { ...ContactsSchema, ...SettingsSchema }; |
|
|
|
|
|
|
|
// Manage the encryption key. If not present in localStorage, create and store it.
|
|
|
|
const secret = |
|
|
|
localStorage.getItem("secret") || Encryption.createRandomEncryptionKey(); |
|
|
|
if (!localStorage.getItem("secret")) localStorage.setItem("secret", secret); |
|
|
|
|
|
|
|
if (localStorage.getItem("secret") == null) { |
|
|
|
localStorage.setItem("secret", secret); |
|
|
|
} |
|
|
|
|
|
|
|
// Apply encryption to the sensitive database using the secret key
|
|
|
|
encrypted(accountsDB, { secretKey: secret }); |
|
|
|
accountsDB.version(1).stores(SensitiveSchemas); |
|
|
|
|
|
|
|
// Define the schema for our databases
|
|
|
|
accountsDB.version(1).stores(SensitiveSchemas); |
|
|
|
db.version(1).stores(NonsensitiveSchemas); |
|
|
|
|
|
|
|
// initialize, a la https://dexie.org/docs/Tutorial/Design#the-populate-event
|
|
|
|
db.on("populate", function () { |
|
|
|
// ensure there's an initial entry for settings
|
|
|
|
// Event handler to initialize the non-sensitive database with default settings
|
|
|
|
db.on("populate", () => { |
|
|
|
db.settings.add({ |
|
|
|
id: MASTER_SETTINGS_KEY, |
|
|
|
apiServer: AppString.DEFAULT_ENDORSER_API_SERVER, |
|
|
|