change all copied contact URLs to contact-import, and handle multiples & singles separately

This commit is contained in:
2025-01-09 20:10:00 -07:00
parent 00fc80036a
commit e97bc4893e
5 changed files with 104 additions and 74 deletions

View File

@@ -122,7 +122,6 @@
</template>
<script lang="ts">
import { JWTPayload, JWTVerified } from "did-jwt";
import * as R from "ramda";
import { Component, Vue } from "vue-facing-decorator";
import { RouteLocationNormalizedLoaded, Router } from "vue-router";
@@ -138,13 +137,13 @@ import {
} from "@/db/index";
import { Contact, ContactMethod } from "@/db/tables/contacts";
import * as libsUtil from "@/libs/util";
import { decodeAndVerifyJwt } from "@/libs/crypto/vc";
import { decodeEndorserJwt } from "@/libs/crypto/vc";
import {
capitalizeAndInsertSpacesBeforeCaps,
errorStringForLog,
setVisibilityUtil,
} from "@/libs/endorserServer";
import { getContactPayloadFromJwtUrl } from "@/libs/crypto";
import { getContactJwtFromJwtUrl } from "@/libs/crypto";
@Component({
components: { EntityIcon, OfferDialog, QuickNav },
@@ -182,7 +181,7 @@ export default class ContactImportView extends Vue {
this.activeDid = settings.activeDid || "";
this.apiServer = settings.apiServer || "";
// look for any imported contacts from the query parameter
// look for any imported contact array from the query parameter
const importedContacts = (this.$route as RouteLocationNormalizedLoaded)
.query["contacts"] as string;
if (importedContacts) {
@@ -194,10 +193,36 @@ export default class ContactImportView extends Vue {
/\/contact-import\/(ey.+)$/,
)?.[1];
if (jwt) {
// decode the JWT
// would prefer to validate but we've got an error with JWTs on QR codes generated in the future
// eslint-disable-next-line prettier/prettier
const parsedJwt: Omit<JWTVerified, "didResolutionResult" | "signer" | "jwt"> = await decodeAndVerifyJwt(jwt);
await this.setContactsSelected(parsedJwt.payload.contacts as Contact[]);
// const parsedJwt: Omit<JWTVerified, "didResolutionResult" | "signer" | "jwt"> = await decodeAndVerifyJwt(jwt);
// decode the JWT
const parsedJwt = decodeEndorserJwt(jwt);
const contacts: Array<Contact> =
parsedJwt.payload.contacts || // someday this will be the only payload sent to this page
(Array.isArray(parsedJwt.payload) ? parsedJwt.payload : undefined);
if (!contacts && parsedJwt.payload.own) {
// handle this single-contact JWT in the contacts page, better suited to single additions
(this.$router as Router).push({
name: "contacts",
query: { contactJwt: jwt },
});
}
if (contacts) {
await this.setContactsSelected(contacts);
} else {
// no contacts found so default message should be OK
}
}
if (
this.contactsImporting.length === 1 &&
R.isEmpty(this.contactsExisting)
) {
// if there is only one contact and it's new, then we will automatically import it
this.contactsSelected[0] = true;
this.importContacts(); // ... which routes to the contacts list
}
}
@@ -269,7 +294,10 @@ export default class ContactImportView extends Vue {
try {
// (For another approach used with invites, see InviteOneAcceptView.processInvite)
const payload: JWTPayload = getContactPayloadFromJwtUrl(jwtInput);
const jwt: string = getContactJwtFromJwtUrl(jwtInput);
// JWT format: { header, payload, signature, data }
const payload = decodeEndorserJwt(jwt).payload;
if (Array.isArray(payload.contacts)) {
await this.setContactsSelected(payload.contacts);
} else {
@@ -304,6 +332,7 @@ export default class ContactImportView extends Vue {
updatedCount++;
} else {
// without explicit clone on the Proxy, we get: DataCloneError: Failed to execute 'add' on 'IDBObjectStore': #<Object> could not be cloned.
// DataError: Failed to execute 'add' on 'IDBObjectStore': Evaluating the object store's key path yielded a value that is not a valid key.
await db.contacts.add(R.clone(contact));
importedCount++;
}