forked from jsnbuchanan/crowd-funder-for-time-pwa
parameterize main identifier (to prepare the way for multiple)
This commit is contained in:
@@ -24,6 +24,8 @@
|
|||||||
- get 'copy' to work on account page
|
- get 'copy' to work on account page
|
||||||
|
|
||||||
- contacts v+ :
|
- contacts v+ :
|
||||||
|
- .2 warn about amounts when you cannot see them
|
||||||
|
- .2 confirmed direction is wrong on ContactAmounts screen
|
||||||
- .5 make advanced "show/hide amounts" button into a nice UI toggle
|
- .5 make advanced "show/hide amounts" button into a nice UI toggle
|
||||||
- .2 show error to user when adding a duplicate contact
|
- .2 show error to user when adding a duplicate contact
|
||||||
- parse input more robustly (with CSV lib and not commas)
|
- parse input more robustly (with CSV lib and not commas)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ export type Account = {
|
|||||||
id?: number; // auto-generated by Dexie
|
id?: number; // auto-generated by Dexie
|
||||||
dateCreated: string;
|
dateCreated: string;
|
||||||
derivationPath: string;
|
derivationPath: string;
|
||||||
|
did: string;
|
||||||
identity: string;
|
identity: string;
|
||||||
publicKeyHex: string;
|
publicKeyHex: string;
|
||||||
mnemonic: string;
|
mnemonic: string;
|
||||||
@@ -11,5 +12,5 @@ export type Account = {
|
|||||||
// see https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon
|
// see https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon
|
||||||
export const AccountsSchema = {
|
export const AccountsSchema = {
|
||||||
accounts:
|
accounts:
|
||||||
"++id, dateCreated, derivationPath, $identity, $mnemonic, publicKeyHex",
|
"++id, dateCreated, derivationPath, did, $identity, $mnemonic, publicKeyHex",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// a singleton
|
// a singleton
|
||||||
export type Settings = {
|
export type Settings = {
|
||||||
id: number;
|
id: number; // there's only one entry: MASTER_SETTINGS_KEY
|
||||||
|
activeDid?: string;
|
||||||
firstName?: string;
|
firstName?: string;
|
||||||
lastName?: string;
|
lastName?: string;
|
||||||
showContactGivesInline?: boolean;
|
showContactGivesInline?: boolean;
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import * as didJwt from "did-jwt";
|
import * as didJwt from "did-jwt";
|
||||||
import { AppString } from "@/constants/app";
|
import { AppString } from "@/constants/app";
|
||||||
import { accountsDB } from "../db";
|
import { db } from "../db";
|
||||||
import { SERVICE_ID } from "../libs/veramo/setup";
|
import { SERVICE_ID } from "../libs/veramo/setup";
|
||||||
import { deriveAddress, newIdentifier } from "../libs/crypto";
|
import { deriveAddress, newIdentifier } from "../libs/crypto";
|
||||||
|
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
||||||
|
|
||||||
export async function testServerRegisterUser() {
|
export async function testServerRegisterUser() {
|
||||||
const testUser0Mnem =
|
const testUser0Mnem =
|
||||||
@@ -13,9 +14,8 @@ export async function testServerRegisterUser() {
|
|||||||
|
|
||||||
const identity0 = newIdentifier(addr, publicHex, privateHex, deriPath);
|
const identity0 = newIdentifier(addr, publicHex, privateHex, deriPath);
|
||||||
|
|
||||||
await accountsDB.open();
|
await db.open();
|
||||||
const accounts = await accountsDB.accounts.toArray();
|
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
|
||||||
const thisIdentity = JSON.parse(accounts[0].identity);
|
|
||||||
|
|
||||||
// Make a claim
|
// Make a claim
|
||||||
const vcClaim = {
|
const vcClaim = {
|
||||||
@@ -23,7 +23,7 @@ export async function testServerRegisterUser() {
|
|||||||
"@type": "RegisterAction",
|
"@type": "RegisterAction",
|
||||||
agent: { did: identity0.did },
|
agent: { did: identity0.did },
|
||||||
object: SERVICE_ID,
|
object: SERVICE_ID,
|
||||||
participant: { did: thisIdentity.did },
|
participant: { did: settings?.activeDid },
|
||||||
};
|
};
|
||||||
// Make a payload for the claim
|
// Make a payload for the claim
|
||||||
const vcPayload = {
|
const vcPayload = {
|
||||||
@@ -56,5 +56,5 @@ export async function testServerRegisterUser() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const resp = await axios.post(url, payload, { headers });
|
const resp = await axios.post(url, payload, { headers });
|
||||||
console.log("Result:", resp);
|
console.log("User registration result:", resp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -240,8 +240,11 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import "dexie-export-import";
|
import "dexie-export-import";
|
||||||
|
import * as R from "ramda";
|
||||||
import { Options, Vue } from "vue-class-component";
|
import { Options, Vue } from "vue-class-component";
|
||||||
import { useClipboard } from "@vueuse/core";
|
import { useClipboard } from "@vueuse/core";
|
||||||
|
|
||||||
|
import { AppString } from "@/constants/app";
|
||||||
import { db, accountsDB } from "@/db";
|
import { db, accountsDB } from "@/db";
|
||||||
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
||||||
import {
|
import {
|
||||||
@@ -250,7 +253,7 @@ import {
|
|||||||
generateSeed,
|
generateSeed,
|
||||||
newIdentifier,
|
newIdentifier,
|
||||||
} from "@/libs/crypto";
|
} from "@/libs/crypto";
|
||||||
import { AppString } from "@/constants/app";
|
import { AxiosError } from "axios/index";
|
||||||
//import { testServerRegisterUser } from "../test";
|
//import { testServerRegisterUser } from "../test";
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
@@ -269,6 +272,7 @@ interface RateLimits {
|
|||||||
components: {},
|
components: {},
|
||||||
})
|
})
|
||||||
export default class AccountViewView extends Vue {
|
export default class AccountViewView extends Vue {
|
||||||
|
activeDid = "";
|
||||||
address = "";
|
address = "";
|
||||||
derivationPath = "";
|
derivationPath = "";
|
||||||
firstName = "";
|
firstName = "";
|
||||||
@@ -297,6 +301,7 @@ export default class AccountViewView extends Vue {
|
|||||||
await db.open();
|
await db.open();
|
||||||
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
|
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
|
||||||
if (settings) {
|
if (settings) {
|
||||||
|
this.activeDid = settings.activeDid || "";
|
||||||
this.firstName = settings.firstName || "";
|
this.firstName = settings.firstName || "";
|
||||||
this.lastName = settings.lastName || "";
|
this.lastName = settings.lastName || "";
|
||||||
this.showContactGives = !!settings.showContactGivesInline;
|
this.showContactGives = !!settings.showContactGivesInline;
|
||||||
@@ -319,18 +324,27 @@ export default class AccountViewView extends Vue {
|
|||||||
await accountsDB.accounts.add({
|
await accountsDB.accounts.add({
|
||||||
dateCreated: new Date().toISOString(),
|
dateCreated: new Date().toISOString(),
|
||||||
derivationPath: this.derivationPath,
|
derivationPath: this.derivationPath,
|
||||||
|
did: newId.did,
|
||||||
identity: JSON.stringify(newId),
|
identity: JSON.stringify(newId),
|
||||||
mnemonic: this.mnemonic,
|
mnemonic: this.mnemonic,
|
||||||
publicKeyHex: newId.keys[0].publicKeyHex,
|
publicKeyHex: newId.keys[0].publicKeyHex,
|
||||||
});
|
});
|
||||||
|
this.activeDid = newId.did;
|
||||||
}
|
}
|
||||||
|
|
||||||
const accounts = await accountsDB.accounts.toArray();
|
const accounts = await accountsDB.accounts.toArray();
|
||||||
const identity = JSON.parse(accounts[0].identity);
|
const account = R.find((acc) => acc.did === this.activeDid, accounts);
|
||||||
|
const identity = JSON.parse(account?.identity || "undefined");
|
||||||
this.address = identity.did;
|
this.address = identity.did;
|
||||||
this.publicHex = identity.keys[0].publicKeyHex;
|
this.publicHex = identity.keys[0].publicKeyHex;
|
||||||
this.publicBase64 = Buffer.from(this.publicHex, "hex").toString("base64");
|
this.publicBase64 = Buffer.from(this.publicHex, "hex").toString("base64");
|
||||||
this.derivationPath = identity.keys[0].meta.derivationPath;
|
this.derivationPath = identity.keys[0].meta.derivationPath;
|
||||||
|
|
||||||
|
if (settings) {
|
||||||
|
db.settings.update(MASTER_SETTINGS_KEY, {
|
||||||
|
activeDid: identity.did,
|
||||||
|
});
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.alertMessage =
|
this.alertMessage =
|
||||||
"Clear your cache and start over (after data backup). See console log for more info.";
|
"Clear your cache and start over (after data backup). See console log for more info.";
|
||||||
@@ -387,7 +401,8 @@ export default class AccountViewView extends Vue {
|
|||||||
const url = endorserApiServer + "/api/report/rateLimits";
|
const url = endorserApiServer + "/api/report/rateLimits";
|
||||||
await accountsDB.open();
|
await accountsDB.open();
|
||||||
const accounts = await accountsDB.accounts.toArray();
|
const accounts = await accountsDB.accounts.toArray();
|
||||||
const identity = JSON.parse(accounts[0].identity);
|
const account = R.find((acc) => acc.did === this.address, accounts);
|
||||||
|
const identity = JSON.parse(account?.identity || "undefined");
|
||||||
const token = await accessToken(identity);
|
const token = await accessToken(identity);
|
||||||
const headers = {
|
const headers = {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
@@ -396,21 +411,23 @@ export default class AccountViewView extends Vue {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const resp = await this.axios.get(url, { headers });
|
const resp = await this.axios.get(url, { headers });
|
||||||
|
// axios throws an exception on a 400
|
||||||
if (resp.status === 200) {
|
if (resp.status === 200) {
|
||||||
this.limits = resp.data;
|
this.limits = resp.data;
|
||||||
} else {
|
|
||||||
this.alertTitle = "Error from Server";
|
|
||||||
console.log("Bad response retrieving limits: ", resp.data);
|
|
||||||
if (resp.data.error?.message) {
|
|
||||||
this.alertMessage = resp.data.error?.message;
|
|
||||||
} else {
|
|
||||||
this.alertMessage = "Bad server response of " + resp.status;
|
|
||||||
}
|
|
||||||
this.isAlertVisible = true;
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (error: unknown) {
|
||||||
|
const serverError = error as AxiosError;
|
||||||
|
|
||||||
this.alertTitle = "Error from Server";
|
this.alertTitle = "Error from Server";
|
||||||
this.alertMessage = err as string;
|
console.log("Bad response retrieving limits: ", serverError);
|
||||||
|
// Anybody know how to access items inside "response.data" without this?
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const data: any = serverError.response?.data;
|
||||||
|
if (data.error.message) {
|
||||||
|
this.alertMessage = data.error.message;
|
||||||
|
} else {
|
||||||
|
this.alertMessage = "Bad server response. See logs for details.";
|
||||||
|
}
|
||||||
this.isAlertVisible = true;
|
this.isAlertVisible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,11 +116,12 @@
|
|||||||
import * as R from "ramda";
|
import * as R from "ramda";
|
||||||
import { Options, Vue } from "vue-class-component";
|
import { Options, Vue } from "vue-class-component";
|
||||||
|
|
||||||
import { Contact } from "@/db/tables/contacts";
|
|
||||||
import { accountsDB, db } from "@/db";
|
import { accountsDB, db } from "@/db";
|
||||||
|
import { Contact } from "@/db/tables/contacts";
|
||||||
|
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
||||||
|
import { AppString } from "@/constants/app";
|
||||||
import { accessToken } from "@/libs/crypto";
|
import { accessToken } from "@/libs/crypto";
|
||||||
import { GiveServerRecord } from "@/libs/endorserServer";
|
import { GiveServerRecord } from "@/libs/endorserServer";
|
||||||
import { AppString } from "@/constants/app";
|
|
||||||
|
|
||||||
@Options({})
|
@Options({})
|
||||||
export default class ContactsView extends Vue {
|
export default class ContactsView extends Vue {
|
||||||
@@ -133,16 +134,20 @@ export default class ContactsView extends Vue {
|
|||||||
const contactDid = this.$route.query.contactDid as string;
|
const contactDid = this.$route.query.contactDid as string;
|
||||||
this.contact = (await db.contacts.get(contactDid)) || null;
|
this.contact = (await db.contacts.get(contactDid)) || null;
|
||||||
|
|
||||||
if (this.contact) {
|
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
|
||||||
this.loadGives(this.contact);
|
const activeDid = settings?.activeDid;
|
||||||
|
|
||||||
|
if (activeDid && this.contact) {
|
||||||
|
this.loadGives(activeDid, this.contact);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadGives(contact: Contact) {
|
async loadGives(activeDid: string, contact: Contact) {
|
||||||
// only load the private keys temporarily when needed
|
// only load the private keys temporarily when needed
|
||||||
await accountsDB.open();
|
await accountsDB.open();
|
||||||
const accounts = await accountsDB.accounts.toArray();
|
const accounts = await accountsDB.accounts.toArray();
|
||||||
const identity = JSON.parse(accounts[0].identity);
|
const account = R.find((acc) => acc.did === activeDid, accounts);
|
||||||
|
const identity = JSON.parse(account?.identity || "undefined");
|
||||||
|
|
||||||
const endorserApiServer = AppString.DEFAULT_ENDORSER_API_SERVER;
|
const endorserApiServer = AppString.DEFAULT_ENDORSER_API_SERVER;
|
||||||
|
|
||||||
|
|||||||
@@ -135,11 +135,11 @@
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button v-if="contact.registered" class="tooltip">
|
<button v-if="contact.registered" class="tooltip">
|
||||||
<span class="tooltiptext">They are registered</span>
|
<span class="tooltiptext">Registered</span>
|
||||||
<fa icon="person-circle-check" class="text-slate-900 fa-fw ml-1" />
|
<fa icon="person-circle-check" class="text-slate-900 fa-fw ml-1" />
|
||||||
</button>
|
</button>
|
||||||
<button v-else @click="register(contact)" class="tooltip">
|
<button v-else @click="register(contact)" class="tooltip">
|
||||||
<span class="tooltiptext">They may not be registered</span>
|
<span class="tooltiptext">Registration Unknown</span>
|
||||||
<fa
|
<fa
|
||||||
icon="person-circle-question"
|
icon="person-circle-question"
|
||||||
class="text-slate-900 fa-fw ml-1"
|
class="text-slate-900 fa-fw ml-1"
|
||||||
@@ -170,7 +170,7 @@
|
|||||||
</span>
|
</span>
|
||||||
<button
|
<button
|
||||||
class="text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md mb-6"
|
class="text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md mb-6"
|
||||||
@click="onClickAddGive(identity.did, contact.did)"
|
@click="onClickAddGive(activeDid, contact.did)"
|
||||||
>
|
>
|
||||||
+
|
+
|
||||||
</button>
|
</button>
|
||||||
@@ -192,7 +192,7 @@
|
|||||||
</span>
|
</span>
|
||||||
<button
|
<button
|
||||||
class="text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md mb-6"
|
class="text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md mb-6"
|
||||||
@click="onClickAddGive(contact.did, identity.did)"
|
@click="onClickAddGive(contact.did, activeDid)"
|
||||||
>
|
>
|
||||||
+
|
+
|
||||||
</button>
|
</button>
|
||||||
@@ -251,6 +251,7 @@ const Buffer = require("buffer/").Buffer;
|
|||||||
components: {},
|
components: {},
|
||||||
})
|
})
|
||||||
export default class ContactsView extends Vue {
|
export default class ContactsView extends Vue {
|
||||||
|
activeDid = "";
|
||||||
contacts: Array<Contact> = [];
|
contacts: Array<Contact> = [];
|
||||||
contactInput = "";
|
contactInput = "";
|
||||||
// { "did:...": concatenated-descriptions } entry for each contact
|
// { "did:...": concatenated-descriptions } entry for each contact
|
||||||
@@ -267,19 +268,16 @@ export default class ContactsView extends Vue {
|
|||||||
givenToMeUnconfirmed: Record<string, number> = {};
|
givenToMeUnconfirmed: Record<string, number> = {};
|
||||||
hourDescriptionInput = "";
|
hourDescriptionInput = "";
|
||||||
hourInput = "0";
|
hourInput = "0";
|
||||||
identity: IIdentifier | null = null;
|
|
||||||
showGiveNumbers = false;
|
showGiveNumbers = false;
|
||||||
showGiveTotals = true;
|
showGiveTotals = true;
|
||||||
showGiveConfirmed = true;
|
showGiveConfirmed = true;
|
||||||
|
|
||||||
// 'created' hook runs when the Vue instance is first created
|
// 'created' hook runs when the Vue instance is first created
|
||||||
async created() {
|
async created() {
|
||||||
await accountsDB.open();
|
|
||||||
const accounts = await accountsDB.accounts.toArray();
|
|
||||||
this.identity = JSON.parse(accounts[0].identity);
|
|
||||||
|
|
||||||
await db.open();
|
await db.open();
|
||||||
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
|
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
|
||||||
|
this.activeDid = settings?.activeDid || "";
|
||||||
|
|
||||||
this.showGiveNumbers = !!settings?.showContactGivesInline;
|
this.showGiveNumbers = !!settings?.showContactGivesInline;
|
||||||
if (this.showGiveNumbers) {
|
if (this.showGiveNumbers) {
|
||||||
this.loadGives();
|
this.loadGives();
|
||||||
@@ -292,7 +290,12 @@ export default class ContactsView extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async loadGives() {
|
async loadGives() {
|
||||||
if (!this.identity) {
|
await accountsDB.open();
|
||||||
|
const accounts = await accountsDB.accounts.toArray();
|
||||||
|
const account = R.find((acc) => acc.did === this.activeDid, accounts);
|
||||||
|
const identity = JSON.parse(account?.identity || "undefined");
|
||||||
|
|
||||||
|
if (!identity) {
|
||||||
console.error(
|
console.error(
|
||||||
"Attempted to load Give records with no identity available."
|
"Attempted to load Give records with no identity available."
|
||||||
);
|
);
|
||||||
@@ -306,8 +309,8 @@ export default class ContactsView extends Vue {
|
|||||||
const url =
|
const url =
|
||||||
endorserApiServer +
|
endorserApiServer +
|
||||||
"/api/v2/report/gives?agentDid=" +
|
"/api/v2/report/gives?agentDid=" +
|
||||||
encodeURIComponent(this.identity?.did);
|
encodeURIComponent(identity.did);
|
||||||
const token = await accessToken(this.identity);
|
const token = await accessToken(identity);
|
||||||
const headers = {
|
const headers = {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
Authorization: "Bearer " + token,
|
Authorization: "Bearer " + token,
|
||||||
@@ -361,8 +364,8 @@ export default class ContactsView extends Vue {
|
|||||||
const url =
|
const url =
|
||||||
endorserApiServer +
|
endorserApiServer +
|
||||||
"/api/v2/report/gives?recipientDid=" +
|
"/api/v2/report/gives?recipientDid=" +
|
||||||
encodeURIComponent(this.identity.did);
|
encodeURIComponent(identity.did);
|
||||||
const token = await accessToken(this.identity);
|
const token = await accessToken(identity);
|
||||||
const headers = {
|
const headers = {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
Authorization: "Bearer " + token,
|
Authorization: "Bearer " + token,
|
||||||
@@ -464,7 +467,9 @@ export default class ContactsView extends Vue {
|
|||||||
) {
|
) {
|
||||||
await accountsDB.open();
|
await accountsDB.open();
|
||||||
const accounts = await accountsDB.accounts.toArray();
|
const accounts = await accountsDB.accounts.toArray();
|
||||||
const identity = JSON.parse(accounts[0].identity);
|
const account = R.find((acc) => acc.did === this.activeDid, accounts);
|
||||||
|
const identity = JSON.parse(account?.identity || "undefined");
|
||||||
|
|
||||||
// Make a claim
|
// Make a claim
|
||||||
const vcClaim: RegisterVerifiableCredential = {
|
const vcClaim: RegisterVerifiableCredential = {
|
||||||
"@context": "https://schema.org",
|
"@context": "https://schema.org",
|
||||||
@@ -544,7 +549,9 @@ export default class ContactsView extends Vue {
|
|||||||
(visibility ? "canSeeMe" : "cannotSeeMe");
|
(visibility ? "canSeeMe" : "cannotSeeMe");
|
||||||
await accountsDB.open();
|
await accountsDB.open();
|
||||||
const accounts = await accountsDB.accounts.toArray();
|
const accounts = await accountsDB.accounts.toArray();
|
||||||
const identity = JSON.parse(accounts[0].identity);
|
const account = R.find((acc) => acc.did === this.activeDid, accounts);
|
||||||
|
const identity = JSON.parse(account?.identity || "undefined");
|
||||||
|
|
||||||
const token = await accessToken(identity);
|
const token = await accessToken(identity);
|
||||||
const headers = {
|
const headers = {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
@@ -582,7 +589,9 @@ export default class ContactsView extends Vue {
|
|||||||
encodeURIComponent(contact.did);
|
encodeURIComponent(contact.did);
|
||||||
await accountsDB.open();
|
await accountsDB.open();
|
||||||
const accounts = await accountsDB.accounts.toArray();
|
const accounts = await accountsDB.accounts.toArray();
|
||||||
const identity = JSON.parse(accounts[0].identity);
|
const account = R.find((acc) => acc.did === this.activeDid, accounts);
|
||||||
|
const identity = JSON.parse(account?.identity || "undefined");
|
||||||
|
|
||||||
const token = await accessToken(identity);
|
const token = await accessToken(identity);
|
||||||
const headers = {
|
const headers = {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
@@ -635,8 +644,13 @@ export default class ContactsView extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async onClickAddGive(fromDid: string, toDid: string): Promise<void> {
|
async onClickAddGive(fromDid: string, toDid: string): Promise<void> {
|
||||||
|
await accountsDB.open();
|
||||||
|
const accounts = await accountsDB.accounts.toArray();
|
||||||
|
const account = R.find((acc) => acc.did === this.activeDid, accounts);
|
||||||
|
const identity = JSON.parse(account?.identity || "undefined");
|
||||||
|
|
||||||
// if they have unconfirmed amounts, ask to confirm those first
|
// if they have unconfirmed amounts, ask to confirm those first
|
||||||
if (toDid == this.identity?.did && this.givenToMeUnconfirmed[fromDid] > 0) {
|
if (toDid == identity?.did && this.givenToMeUnconfirmed[fromDid] > 0) {
|
||||||
if (
|
if (
|
||||||
confirm(
|
confirm(
|
||||||
"There are " +
|
"There are " +
|
||||||
@@ -660,14 +674,14 @@ export default class ContactsView extends Vue {
|
|||||||
this.alertTitle = "Input Error";
|
this.alertTitle = "Input Error";
|
||||||
this.alertMessage = "Giving 0 hours does nothing.";
|
this.alertMessage = "Giving 0 hours does nothing.";
|
||||||
this.isAlertVisible = true;
|
this.isAlertVisible = true;
|
||||||
} else if (!this.identity) {
|
} else if (!identity) {
|
||||||
this.alertTitle = "Status Error";
|
this.alertTitle = "Status Error";
|
||||||
this.alertMessage = "No identity is available.";
|
this.alertMessage = "No identity is available.";
|
||||||
this.isAlertVisible = true;
|
this.isAlertVisible = true;
|
||||||
} else {
|
} else {
|
||||||
// ask to confirm amount
|
// ask to confirm amount
|
||||||
let toFrom;
|
let toFrom;
|
||||||
if (fromDid == this.identity?.did) {
|
if (fromDid == identity?.did) {
|
||||||
toFrom = "from you to " + this.nameForDid(this.contacts, toDid);
|
toFrom = "from you to " + this.nameForDid(this.contacts, toDid);
|
||||||
} else {
|
} else {
|
||||||
toFrom = "from " + this.nameForDid(this.contacts, fromDid) + " to you";
|
toFrom = "from " + this.nameForDid(this.contacts, fromDid) + " to you";
|
||||||
@@ -689,7 +703,7 @@ export default class ContactsView extends Vue {
|
|||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
this.createAndSubmitGive(
|
this.createAndSubmitGive(
|
||||||
this.identity,
|
identity,
|
||||||
fromDid,
|
fromDid,
|
||||||
toDid,
|
toDid,
|
||||||
parseFloat(this.hourInput),
|
parseFloat(this.hourInput),
|
||||||
|
|||||||
@@ -45,7 +45,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Options, Vue } from "vue-class-component";
|
import { Options, Vue } from "vue-class-component";
|
||||||
import { deriveAddress, newIdentifier } from "../libs/crypto";
|
import { deriveAddress, newIdentifier } from "../libs/crypto";
|
||||||
import { accountsDB } from "@/db";
|
import { accountsDB, db } from "@/db";
|
||||||
|
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
||||||
|
|
||||||
@Options({
|
@Options({
|
||||||
components: {},
|
components: {},
|
||||||
@@ -81,11 +82,21 @@ export default class ImportAccountView extends Vue {
|
|||||||
await accountsDB.accounts.add({
|
await accountsDB.accounts.add({
|
||||||
dateCreated: new Date().toISOString(),
|
dateCreated: new Date().toISOString(),
|
||||||
derivationPath: this.derivationPath,
|
derivationPath: this.derivationPath,
|
||||||
|
did: newId.did,
|
||||||
identity: JSON.stringify(newId),
|
identity: JSON.stringify(newId),
|
||||||
mnemonic: mne,
|
mnemonic: mne,
|
||||||
publicKeyHex: newId.keys[0].publicKeyHex,
|
publicKeyHex: newId.keys[0].publicKeyHex,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// record that as the active DID
|
||||||
|
await db.open();
|
||||||
|
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
|
||||||
|
if (settings) {
|
||||||
|
db.settings.update(MASTER_SETTINGS_KEY, {
|
||||||
|
activeDid: newId.did,
|
||||||
|
});
|
||||||
|
}
|
||||||
this.$router.push({ name: "account" });
|
this.$router.push({ name: "account" });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log("Error!");
|
console.log("Error!");
|
||||||
|
|||||||
@@ -76,14 +76,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Options, Vue } from "vue-class-component";
|
|
||||||
import { AppString } from "@/constants/app";
|
|
||||||
import { accountsDB } from "../db";
|
|
||||||
import { accessToken, SimpleSigner } from "@/libs/crypto";
|
|
||||||
import * as didJwt from "did-jwt";
|
|
||||||
import { IIdentifier } from "@veramo/core";
|
|
||||||
import { useAppStore } from "@/store/app";
|
|
||||||
import { AxiosError } from "axios";
|
import { AxiosError } from "axios";
|
||||||
|
import * as didJwt from "did-jwt";
|
||||||
|
import * as R from "ramda";
|
||||||
|
import { Options, Vue } from "vue-class-component";
|
||||||
|
|
||||||
|
import { AppString } from "@/constants/app";
|
||||||
|
import { accountsDB, db } from "@/db";
|
||||||
|
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
||||||
|
import { accessToken, SimpleSigner } from "@/libs/crypto";
|
||||||
|
import { useAppStore } from "@/store/app";
|
||||||
|
import { IIdentifier } from "@veramo/core";
|
||||||
|
|
||||||
interface VerifiableCredential {
|
interface VerifiableCredential {
|
||||||
"@context": string;
|
"@context": string;
|
||||||
@@ -97,6 +100,7 @@ interface VerifiableCredential {
|
|||||||
components: {},
|
components: {},
|
||||||
})
|
})
|
||||||
export default class NewEditProjectView extends Vue {
|
export default class NewEditProjectView extends Vue {
|
||||||
|
activeDid = "";
|
||||||
projectName = "";
|
projectName = "";
|
||||||
description = "";
|
description = "";
|
||||||
errorMessage = "";
|
errorMessage = "";
|
||||||
@@ -109,16 +113,19 @@ export default class NewEditProjectView extends Vue {
|
|||||||
|
|
||||||
// 'created' hook runs when the Vue instance is first created
|
// 'created' hook runs when the Vue instance is first created
|
||||||
async created() {
|
async created() {
|
||||||
if (this.projectId === "") {
|
await db.open();
|
||||||
console.log("This is a new project");
|
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
|
||||||
} else {
|
this.activeDid = settings?.activeDid || "";
|
||||||
|
|
||||||
|
if (this.projectId) {
|
||||||
await accountsDB.open();
|
await accountsDB.open();
|
||||||
const num_accounts = await accountsDB.accounts.count();
|
const num_accounts = await accountsDB.accounts.count();
|
||||||
if (num_accounts === 0) {
|
if (num_accounts === 0) {
|
||||||
console.log("Problem! Should have a profile!");
|
console.log("Problem! Should have a profile!");
|
||||||
} else {
|
} else {
|
||||||
const accounts = await accountsDB.accounts.toArray();
|
const accounts = await accountsDB.accounts.toArray();
|
||||||
const identity = JSON.parse(accounts[0].identity);
|
const account = R.find((acc) => acc.did === this.activeDid, accounts);
|
||||||
|
const identity = JSON.parse(account?.identity || "undefined");
|
||||||
this.LoadProject(identity);
|
this.LoadProject(identity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -257,7 +264,8 @@ export default class NewEditProjectView extends Vue {
|
|||||||
console.log("Problem! Should have a profile!");
|
console.log("Problem! Should have a profile!");
|
||||||
} else {
|
} else {
|
||||||
const accounts = await accountsDB.accounts.toArray();
|
const accounts = await accountsDB.accounts.toArray();
|
||||||
const identity = JSON.parse(accounts[0].identity);
|
const account = R.find((acc) => acc.did === this.activeDid, accounts);
|
||||||
|
const identity = JSON.parse(account?.identity || "undefined");
|
||||||
this.SaveProject(identity);
|
this.SaveProject(identity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,13 +146,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Options, Vue } from "vue-class-component";
|
|
||||||
import { accessToken } from "@/libs/crypto";
|
|
||||||
import { accountsDB } from "../db";
|
|
||||||
import { IIdentifier } from "@veramo/core";
|
|
||||||
import { AppString } from "@/constants/app";
|
|
||||||
import * as moment from "moment";
|
|
||||||
import { AxiosError } from "axios";
|
import { AxiosError } from "axios";
|
||||||
|
import * as moment from "moment";
|
||||||
|
import * as R from "ramda";
|
||||||
|
import { Options, Vue } from "vue-class-component";
|
||||||
|
|
||||||
|
import { AppString } from "@/constants/app";
|
||||||
|
import { accountsDB, db } from "@/db";
|
||||||
|
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
||||||
|
import { accessToken } from "@/libs/crypto";
|
||||||
|
import { IIdentifier } from "@veramo/core";
|
||||||
|
|
||||||
@Options({
|
@Options({
|
||||||
components: {},
|
components: {},
|
||||||
@@ -226,13 +229,18 @@ export default class ProjectViewView extends Vue {
|
|||||||
|
|
||||||
// 'created' hook runs when the Vue instance is first created
|
// 'created' hook runs when the Vue instance is first created
|
||||||
async created() {
|
async created() {
|
||||||
|
await db.open();
|
||||||
|
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
|
||||||
|
const activeDid = settings?.activeDid || "";
|
||||||
|
|
||||||
await accountsDB.open();
|
await accountsDB.open();
|
||||||
const num_accounts = await accountsDB.accounts.count();
|
const num_accounts = await accountsDB.accounts.count();
|
||||||
if (num_accounts === 0) {
|
if (num_accounts === 0) {
|
||||||
console.log("Problem! Should have a profile!");
|
console.log("Problem! Should have a profile!");
|
||||||
} else {
|
} else {
|
||||||
const accounts = await accountsDB.accounts.toArray();
|
const accounts = await accountsDB.accounts.toArray();
|
||||||
const identity = JSON.parse(accounts[0].identity);
|
const account = R.find((acc) => acc.did === activeDid, accounts);
|
||||||
|
const identity = JSON.parse(account?.identity || "undefined");
|
||||||
this.LoadProject(identity);
|
this.LoadProject(identity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,11 +101,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import * as R from "ramda";
|
||||||
import { Options, Vue } from "vue-class-component";
|
import { Options, Vue } from "vue-class-component";
|
||||||
import { accessToken } from "@/libs/crypto";
|
|
||||||
import { accountsDB } from "../db";
|
|
||||||
import { IIdentifier } from "@veramo/core";
|
|
||||||
import { AppString } from "@/constants/app";
|
import { AppString } from "@/constants/app";
|
||||||
|
import { accountsDB, db } from "@/db";
|
||||||
|
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
||||||
|
import { accessToken } from "@/libs/crypto";
|
||||||
|
import { IIdentifier } from "@veramo/core";
|
||||||
|
|
||||||
@Options({
|
@Options({
|
||||||
components: {},
|
components: {},
|
||||||
@@ -155,13 +158,18 @@ export default class ProjectsView extends Vue {
|
|||||||
|
|
||||||
// 'created' hook runs when the Vue instance is first created
|
// 'created' hook runs when the Vue instance is first created
|
||||||
async created() {
|
async created() {
|
||||||
|
await db.open();
|
||||||
|
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
|
||||||
|
const activeDid = settings?.activeDid || "";
|
||||||
|
|
||||||
await accountsDB.open();
|
await accountsDB.open();
|
||||||
const num_accounts = await accountsDB.accounts.count();
|
const num_accounts = await accountsDB.accounts.count();
|
||||||
if (num_accounts === 0) {
|
if (num_accounts === 0) {
|
||||||
console.log("Problem! Should have a profile!");
|
console.log("Problem! Should have a profile!");
|
||||||
} else {
|
} else {
|
||||||
const accounts = await accountsDB.accounts.toArray();
|
const accounts = await accountsDB.accounts.toArray();
|
||||||
const identity = JSON.parse(accounts[0].identity);
|
const account = R.find((acc) => acc.did === activeDid, accounts);
|
||||||
|
const identity = JSON.parse(account?.identity || "undefined");
|
||||||
this.LoadProjects(identity);
|
this.LoadProjects(identity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user