forked from trent_larson/crowd-funder-for-time-pwa
separate account from other data for backup/restore
This commit is contained in:
@@ -48,9 +48,9 @@ On the test server, User #0 has rights to register others, so you can start play
|
||||
|
||||
- Register someone else under User #0 on the `/account` page:
|
||||
|
||||
* Edit the `src/views/AccountViewView.vue` file and uncomment the lines referring to "test".
|
||||
* Edit the `src/views/AccountViewView.vue` file and uncomment the lines referring to "testServerRegisterUser".
|
||||
|
||||
* Use the [Vue Devtools browser extension](https://devtools.vuejs.org/) and type this into the console: `$vm.ctx.testRegisterUser()`
|
||||
* Visit the `/account` page, open the [Vue Devtools browser extension](https://devtools.vuejs.org/), select a component, then type this into the console: `$vm.ctx.testRegisterUser()`
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
import BaseDexie, { Table } from "dexie";
|
||||
import { encrypted, Encryption } from "@pvermeer/dexie-encrypted-addon";
|
||||
import { Account, AccountsSchema } from "./tables/accounts";
|
||||
import { Contact, ContactsSchema } from "./tables/contacts";
|
||||
import {
|
||||
Account,
|
||||
AccountsSchema,
|
||||
Contact,
|
||||
ContactsSchema,
|
||||
MASTER_SETTINGS,
|
||||
MASTER_SETTINGS_KEY,
|
||||
Settings,
|
||||
SettingsSchema,
|
||||
} from "./tables";
|
||||
} from "./tables/settings";
|
||||
|
||||
type AllTables = {
|
||||
// a separate DB because the seed is super-sensitive data
|
||||
type SensitiveTables = {
|
||||
accounts: Table<Account>;
|
||||
};
|
||||
|
||||
type NonsensitiveTables = {
|
||||
contacts: Table<Contact>;
|
||||
settings: Table<Settings>;
|
||||
};
|
||||
@@ -24,15 +26,14 @@ type AllTables = {
|
||||
*
|
||||
* https://9to5answer.com/how-to-bypass-warning-unexpected-any-specify-a-different-type-typescript-eslint-no-explicit-any
|
||||
*/
|
||||
type DexieTables = AllTables;
|
||||
export type Dexie<T extends unknown = DexieTables> = BaseDexie & T;
|
||||
export const db = new BaseDexie("KickStart") as Dexie;
|
||||
const AllSchemas = Object.assign(
|
||||
{},
|
||||
AccountsSchema,
|
||||
ContactsSchema,
|
||||
SettingsSchema
|
||||
);
|
||||
export type SensitiveDexie<T extends unknown = SensitiveTables> = BaseDexie & T;
|
||||
export const accountsDB = new BaseDexie("KickStartSensitive") as SensitiveDexie;
|
||||
const SensitiveSchemas = Object.assign({}, AccountsSchema);
|
||||
|
||||
export type NonsensitiveDexie<T extends unknown = NonsensitiveTables> =
|
||||
BaseDexie & T;
|
||||
export const db = new BaseDexie("KickStart") as NonsensitiveDexie;
|
||||
const NonsensitiveSchemas = Object.assign({}, ContactsSchema, SettingsSchema);
|
||||
|
||||
/**
|
||||
* Needed to enable a special webpack setting to allow *await* below:
|
||||
@@ -48,11 +49,13 @@ if (localStorage.getItem("secret") == null) {
|
||||
}
|
||||
|
||||
//console.log("IndexedDB Encryption Secret:", secret);
|
||||
encrypted(db, { secretKey: secret });
|
||||
db.version(1).stores(AllSchemas);
|
||||
encrypted(accountsDB, { secretKey: secret });
|
||||
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
|
||||
db.settings.add({ id: MASTER_SETTINGS });
|
||||
db.settings.add({ id: MASTER_SETTINGS_KEY });
|
||||
});
|
||||
|
||||
@@ -13,29 +13,3 @@ export const AccountsSchema = {
|
||||
accounts:
|
||||
"++id, dateCreated, derivationPath, $identity, $mnemonic, publicKeyHex",
|
||||
};
|
||||
|
||||
export interface Contact {
|
||||
did: string;
|
||||
name?: string;
|
||||
publicKeyBase64?: string;
|
||||
seesMe?: boolean;
|
||||
registered?: boolean;
|
||||
}
|
||||
|
||||
export const ContactsSchema = {
|
||||
contacts: "++did, name, publicKeyBase64, registered, seesMe",
|
||||
};
|
||||
|
||||
// a singleton
|
||||
export type Settings = {
|
||||
id: number;
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
showContactGivesInline?: boolean;
|
||||
};
|
||||
|
||||
export const SettingsSchema = {
|
||||
settings: "id",
|
||||
};
|
||||
|
||||
export const MASTER_SETTINGS = 1;
|
||||
11
src/db/tables/contacts.ts
Normal file
11
src/db/tables/contacts.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export interface Contact {
|
||||
did: string;
|
||||
name?: string;
|
||||
publicKeyBase64?: string;
|
||||
seesMe?: boolean;
|
||||
registered?: boolean;
|
||||
}
|
||||
|
||||
export const ContactsSchema = {
|
||||
contacts: "++did, name, publicKeyBase64, registered, seesMe",
|
||||
};
|
||||
13
src/db/tables/settings.ts
Normal file
13
src/db/tables/settings.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
// a singleton
|
||||
export type Settings = {
|
||||
id: number;
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
showContactGivesInline?: boolean;
|
||||
};
|
||||
|
||||
export const SettingsSchema = {
|
||||
settings: "id",
|
||||
};
|
||||
|
||||
export const MASTER_SETTINGS_KEY = 1;
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
|
||||
import { db } from "@/db";
|
||||
import { accountsDB } from "@/db";
|
||||
|
||||
const routes: Array<RouteRecordRaw> = [
|
||||
{
|
||||
@@ -8,8 +8,8 @@ const routes: Array<RouteRecordRaw> = [
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "start" */ "../views/DiscoverView.vue"),
|
||||
beforeEnter: async (to, from, next) => {
|
||||
await db.open();
|
||||
const num_accounts = await db.accounts.count();
|
||||
await accountsDB.open();
|
||||
const num_accounts = await accountsDB.accounts.count();
|
||||
if (num_accounts > 0) {
|
||||
next();
|
||||
} else {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import axios from "axios";
|
||||
import * as didJwt from "did-jwt";
|
||||
import { AppString } from "@/constants/app";
|
||||
import { db } from "../db";
|
||||
import { accountsDB } from "../db";
|
||||
import { SERVICE_ID } from "../libs/veramo/setup";
|
||||
import { deriveAddress, newIdentifier } from "../libs/crypto";
|
||||
|
||||
@@ -13,8 +13,8 @@ export async function testServerRegisterUser() {
|
||||
|
||||
const identity0 = newIdentifier(addr, publicHex, privateHex, deriPath);
|
||||
|
||||
await db.open();
|
||||
const accounts = await db.accounts.toArray();
|
||||
await accountsDB.open();
|
||||
const accounts = await accountsDB.accounts.toArray();
|
||||
const thisIdentity = JSON.parse(accounts[0].identity);
|
||||
|
||||
// Make a claim
|
||||
|
||||
@@ -200,17 +200,17 @@
|
||||
<script lang="ts">
|
||||
import { Options, Vue } from "vue-class-component";
|
||||
import { useClipboard } from "@vueuse/core";
|
||||
import { db } from "@/db";
|
||||
import { MASTER_SETTINGS } from "@/db/tables";
|
||||
import { db, accountsDB } from "@/db";
|
||||
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
||||
import { deriveAddress, generateSeed, newIdentifier } from "@/libs/crypto";
|
||||
//import { testServerRegisterUser } from "../test";
|
||||
import { testServerRegisterUser } from "../test";
|
||||
|
||||
@Options({
|
||||
components: {},
|
||||
})
|
||||
export default class AccountViewView extends Vue {
|
||||
// This registers current user in vue plugin with: $vm.ctx.testRegisterUser()
|
||||
//testRegisterUser = testServerRegisterUser;
|
||||
testRegisterUser = testServerRegisterUser;
|
||||
|
||||
address = "";
|
||||
firstName = "";
|
||||
@@ -224,16 +224,17 @@ export default class AccountViewView extends Vue {
|
||||
|
||||
// 'created' hook runs when the Vue instance is first created
|
||||
async created() {
|
||||
await db.open();
|
||||
try {
|
||||
const settings = await db.settings.get(MASTER_SETTINGS);
|
||||
await db.open();
|
||||
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
|
||||
if (settings) {
|
||||
this.firstName = settings.firstName || "";
|
||||
this.lastName = settings.lastName || "";
|
||||
this.showContactGives = !!settings.showContactGivesInline;
|
||||
}
|
||||
|
||||
const numAccounts = await db.accounts.count();
|
||||
await accountsDB.open();
|
||||
const numAccounts = await accountsDB.accounts.count();
|
||||
if (numAccounts === 0) {
|
||||
let privateHex = "";
|
||||
this.mnemonic = generateSeed();
|
||||
@@ -246,7 +247,7 @@ export default class AccountViewView extends Vue {
|
||||
privateHex,
|
||||
this.derivationPath
|
||||
);
|
||||
await db.accounts.add({
|
||||
await accountsDB.accounts.add({
|
||||
dateCreated: new Date().toISOString(),
|
||||
derivationPath: this.derivationPath,
|
||||
identity: JSON.stringify(newId),
|
||||
@@ -254,6 +255,12 @@ export default class AccountViewView extends Vue {
|
||||
publicKeyHex: newId.keys[0].publicKeyHex,
|
||||
});
|
||||
}
|
||||
|
||||
const accounts = await accountsDB.accounts.toArray();
|
||||
const identity = JSON.parse(accounts[0].identity);
|
||||
this.address = identity.did;
|
||||
this.publicHex = identity.keys[0].publicKeyHex;
|
||||
this.derivationPath = identity.keys[0].meta.derivationPath;
|
||||
} catch (err) {
|
||||
this.alertMessage =
|
||||
"Clear your cache and start over (after data backup). See console log for more info.";
|
||||
@@ -261,21 +268,15 @@ export default class AccountViewView extends Vue {
|
||||
this.alertTitle = "Error Creating Account";
|
||||
this.isAlertVisible = true;
|
||||
}
|
||||
|
||||
const accounts = await db.accounts.toArray();
|
||||
const identity = JSON.parse(accounts[0].identity);
|
||||
this.address = identity.did;
|
||||
this.publicHex = identity.keys[0].publicKeyHex;
|
||||
this.derivationPath = identity.keys[0].meta.derivationPath;
|
||||
}
|
||||
|
||||
public async toggleShowContactAmounts() {
|
||||
this.showContactGives = !this.showContactGives;
|
||||
try {
|
||||
await db.open();
|
||||
const settings = await db.settings.get(MASTER_SETTINGS);
|
||||
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
|
||||
if (settings) {
|
||||
db.settings.update(MASTER_SETTINGS, {
|
||||
db.settings.update(MASTER_SETTINGS_KEY, {
|
||||
showContactGivesInline: this.showContactGives,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -140,8 +140,8 @@ import { Options, Vue } from "vue-class-component";
|
||||
import { AppString } from "@/constants/app";
|
||||
import { accessToken, SimpleSigner } from "@/libs/crypto";
|
||||
import { IIdentifier } from "@veramo/core";
|
||||
import { db } from "../db";
|
||||
import { Contact } from "../db/tables";
|
||||
import { accountsDB, db } from "../db";
|
||||
import { Contact } from "../db/tables/contacts";
|
||||
|
||||
export interface GiveVerifiableCredential {
|
||||
"@context": string;
|
||||
@@ -169,9 +169,11 @@ export default class ContactsView extends Vue {
|
||||
|
||||
// 'created' hook runs when the Vue instance is first created
|
||||
async created() {
|
||||
await db.open();
|
||||
const accounts = await db.accounts.toArray();
|
||||
await accountsDB.open();
|
||||
const accounts = await accountsDB.accounts.toArray();
|
||||
this.identity = JSON.parse(accounts[0].identity);
|
||||
|
||||
await db.open();
|
||||
this.contacts = await db.contacts.toArray();
|
||||
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<script lang="ts">
|
||||
import { Options, Vue } from "vue-class-component";
|
||||
import { deriveAddress, newIdentifier } from "../libs/crypto";
|
||||
import { db } from "@/db";
|
||||
import { accountsDB } from "@/db";
|
||||
|
||||
@Options({
|
||||
components: {},
|
||||
@@ -75,10 +75,10 @@ export default class ImportAccountView extends Vue {
|
||||
);
|
||||
|
||||
try {
|
||||
await db.open();
|
||||
const num_accounts = await db.accounts.count();
|
||||
await accountsDB.open();
|
||||
const num_accounts = await accountsDB.accounts.count();
|
||||
if (num_accounts === 0) {
|
||||
await db.accounts.add({
|
||||
await accountsDB.accounts.add({
|
||||
dateCreated: new Date().toISOString(),
|
||||
derivationPath: this.derivationPath,
|
||||
identity: JSON.stringify(newId),
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
<script lang="ts">
|
||||
import { Options, Vue } from "vue-class-component";
|
||||
import { db } from "@/db";
|
||||
import { MASTER_SETTINGS } from "@/db/tables";
|
||||
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
||||
|
||||
@Options({
|
||||
components: {},
|
||||
@@ -69,7 +69,7 @@ export default class NewEditAccountView extends Vue {
|
||||
// 'created' hook runs when the Vue instance is first created
|
||||
async created() {
|
||||
await db.open();
|
||||
const settings = await db.settings.get(MASTER_SETTINGS);
|
||||
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
|
||||
if (settings) {
|
||||
this.firstName = settings.firstName || "";
|
||||
this.lastName = settings.lastName || "";
|
||||
@@ -77,7 +77,7 @@ export default class NewEditAccountView extends Vue {
|
||||
}
|
||||
|
||||
onClickSaveChanges() {
|
||||
db.settings.update(MASTER_SETTINGS, {
|
||||
db.settings.update(MASTER_SETTINGS_KEY, {
|
||||
firstName: this.firstName,
|
||||
lastName: this.lastName,
|
||||
});
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
<script lang="ts">
|
||||
import { Options, Vue } from "vue-class-component";
|
||||
import { AppString } from "@/constants/app";
|
||||
import { db } from "../db";
|
||||
import { accountsDB } from "../db";
|
||||
import { accessToken, SimpleSigner } from "@/libs/crypto";
|
||||
import * as didJwt from "did-jwt";
|
||||
import { IIdentifier } from "@veramo/core";
|
||||
@@ -112,12 +112,12 @@ export default class NewEditProjectView extends Vue {
|
||||
if (this.projectId === "") {
|
||||
console.log("This is a new project");
|
||||
} else {
|
||||
await db.open();
|
||||
const num_accounts = await db.accounts.count();
|
||||
await accountsDB.open();
|
||||
const num_accounts = await accountsDB.accounts.count();
|
||||
if (num_accounts === 0) {
|
||||
console.log("Problem! Should have a profile!");
|
||||
} else {
|
||||
const accounts = await db.accounts.toArray();
|
||||
const accounts = await accountsDB.accounts.toArray();
|
||||
const identity = JSON.parse(accounts[0].identity);
|
||||
this.LoadProject(identity);
|
||||
}
|
||||
@@ -254,12 +254,12 @@ export default class NewEditProjectView extends Vue {
|
||||
public async onSaveProjectClick() {
|
||||
this.isHiddenSave = true;
|
||||
this.isHiddenSpinner = false;
|
||||
await db.open();
|
||||
const num_accounts = await db.accounts.count();
|
||||
await accountsDB.open();
|
||||
const num_accounts = await accountsDB.accounts.count();
|
||||
if (num_accounts === 0) {
|
||||
console.log("Problem! Should have a profile!");
|
||||
} else {
|
||||
const accounts = await db.accounts.toArray();
|
||||
const accounts = await accountsDB.accounts.toArray();
|
||||
const identity = JSON.parse(accounts[0].identity);
|
||||
this.SaveProject(identity);
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
<script lang="ts">
|
||||
import { Options, Vue } from "vue-class-component";
|
||||
import { accessToken } from "@/libs/crypto";
|
||||
import { db } from "../db";
|
||||
import { accountsDB } from "../db";
|
||||
import { IIdentifier } from "@veramo/core";
|
||||
import { AppString } from "@/constants/app";
|
||||
import * as moment from "moment";
|
||||
@@ -224,12 +224,12 @@ export default class ProjectViewView extends Vue {
|
||||
|
||||
// 'created' hook runs when the Vue instance is first created
|
||||
async created() {
|
||||
await db.open();
|
||||
const num_accounts = await db.accounts.count();
|
||||
await accountsDB.open();
|
||||
const num_accounts = await accountsDB.accounts.count();
|
||||
if (num_accounts === 0) {
|
||||
console.log("Problem! Should have a profile!");
|
||||
} else {
|
||||
const accounts = await db.accounts.toArray();
|
||||
const accounts = await accountsDB.accounts.toArray();
|
||||
const identity = JSON.parse(accounts[0].identity);
|
||||
this.LoadProject(identity);
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
<script lang="ts">
|
||||
import { Options, Vue } from "vue-class-component";
|
||||
import { accessToken } from "@/libs/crypto";
|
||||
import { db } from "../db";
|
||||
import { accountsDB } from "../db";
|
||||
import { IIdentifier } from "@veramo/core";
|
||||
import { AppString } from "@/constants/app";
|
||||
|
||||
@@ -155,12 +155,12 @@ export default class ProjectsView extends Vue {
|
||||
|
||||
// 'created' hook runs when the Vue instance is first created
|
||||
async created() {
|
||||
await db.open();
|
||||
const num_accounts = await db.accounts.count();
|
||||
await accountsDB.open();
|
||||
const num_accounts = await accountsDB.accounts.count();
|
||||
if (num_accounts === 0) {
|
||||
console.log("Problem! Should have a profile!");
|
||||
} else {
|
||||
const accounts = await db.accounts.toArray();
|
||||
const accounts = await accountsDB.accounts.toArray();
|
||||
const identity = JSON.parse(accounts[0].identity);
|
||||
this.LoadProjects(identity);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user