|
@ -34,7 +34,11 @@ |
|
|
</p> |
|
|
</p> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div @click="onCopyToClipboard()" v-if="activeDid" class="text-center"> |
|
|
<div |
|
|
|
|
|
@click="onCopyUrlToClipboard()" |
|
|
|
|
|
v-if="activeDid && activeDid.startsWith(ETHR_DID_PREFIX)" |
|
|
|
|
|
class="text-center" |
|
|
|
|
|
> |
|
|
<!-- |
|
|
<!-- |
|
|
Play with display options: https://qr-code-styling.com/ |
|
|
Play with display options: https://qr-code-styling.com/ |
|
|
See docs: https://www.npmjs.com/package/qr-code-generator-vue3 |
|
|
See docs: https://www.npmjs.com/package/qr-code-generator-vue3 |
|
@ -45,8 +49,18 @@ |
|
|
:dotsOptions="{ type: 'square' }" |
|
|
:dotsOptions="{ type: 'square' }" |
|
|
class="flex justify-center" |
|
|
class="flex justify-center" |
|
|
/> |
|
|
/> |
|
|
<span> Click that QR to copy your contact URL to your clipboard. </span> |
|
|
<span> |
|
|
<div>Not scanning? Show it in pieces.</div> |
|
|
Click this or QR code to copy your contact URL to your clipboard. |
|
|
|
|
|
</span> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div v-else-if="activeDid" class="text-center"> |
|
|
|
|
|
<!-- Not an ETHR DID so force them to paste it. (Passkey Peer DIDs are too big.) --> |
|
|
|
|
|
<span @click="onCopyDidToClipboard()" class="text-blue-500"> |
|
|
|
|
|
Click here to copy your DID to your clipboard. |
|
|
|
|
|
</span> |
|
|
|
|
|
<span> |
|
|
|
|
|
Then give it to them so they can paste it in their list of People. |
|
|
|
|
|
</span> |
|
|
</div> |
|
|
</div> |
|
|
<div class="text-center" v-else> |
|
|
<div class="text-center" v-else> |
|
|
You have no identitifiers yet, so |
|
|
You have no identitifiers yet, so |
|
@ -92,13 +106,14 @@ import { |
|
|
nextDerivationPath, |
|
|
nextDerivationPath, |
|
|
} from "@/libs/crypto"; |
|
|
} from "@/libs/crypto"; |
|
|
import { |
|
|
import { |
|
|
CONTACT_URL_PREFIX, createEndorserJwtForDid, |
|
|
CONTACT_URL_PREFIX, |
|
|
|
|
|
createEndorserJwtForDid, |
|
|
ENDORSER_JWT_URL_LOCATION, |
|
|
ENDORSER_JWT_URL_LOCATION, |
|
|
isDid, |
|
|
isDid, |
|
|
register, |
|
|
register, |
|
|
setVisibilityUtil, |
|
|
setVisibilityUtil, |
|
|
} from "@/libs/endorserServer"; |
|
|
} from "@/libs/endorserServer"; |
|
|
import * as libsUtil from "@/libs/util"; |
|
|
import { ETHR_DID_PREFIX } from "@/libs/crypto/vc"; |
|
|
|
|
|
|
|
|
@Component({ |
|
|
@Component({ |
|
|
components: { |
|
|
components: { |
|
@ -117,6 +132,8 @@ export default class ContactQRScanShow extends Vue { |
|
|
isRegistered = false; |
|
|
isRegistered = false; |
|
|
qrValue = ""; |
|
|
qrValue = ""; |
|
|
|
|
|
|
|
|
|
|
|
ETHR_DID_PREFIX = ETHR_DID_PREFIX; |
|
|
|
|
|
|
|
|
async created() { |
|
|
async created() { |
|
|
await db.open(); |
|
|
await db.open(); |
|
|
const settings = await db.settings.get(MASTER_SETTINGS_KEY); |
|
|
const settings = await db.settings.get(MASTER_SETTINGS_KEY); |
|
@ -131,20 +148,9 @@ export default class ContactQRScanShow extends Vue { |
|
|
const accounts = await accountsDB.accounts.toArray(); |
|
|
const accounts = await accountsDB.accounts.toArray(); |
|
|
const account = R.find((acc) => acc.did === this.activeDid, accounts); |
|
|
const account = R.find((acc) => acc.did === this.activeDid, accounts); |
|
|
if (account) { |
|
|
if (account) { |
|
|
const identity = await libsUtil.getIdentity(this.activeDid); |
|
|
const publicKeyHex = account.publicKeyHex; |
|
|
const publicKeyHex = identity.keys[0].publicKeyHex; |
|
|
|
|
|
const publicEncKey = Buffer.from(publicKeyHex, "hex").toString("base64"); |
|
|
const publicEncKey = Buffer.from(publicKeyHex, "hex").toString("base64"); |
|
|
|
|
|
|
|
|
const newDerivPath = nextDerivationPath(account.derivationPath as string); |
|
|
|
|
|
const nextPublicHex = deriveAddress( |
|
|
|
|
|
account.mnemonic as string, |
|
|
|
|
|
newDerivPath, |
|
|
|
|
|
)[2]; |
|
|
|
|
|
const nextPublicEncKey = Buffer.from(nextPublicHex, "hex"); |
|
|
|
|
|
const nextPublicEncKeyHash = sha256(nextPublicEncKey); |
|
|
|
|
|
const nextPublicEncKeyHashBase64 = |
|
|
|
|
|
Buffer.from(nextPublicEncKeyHash).toString("base64"); |
|
|
|
|
|
|
|
|
|
|
|
const contactInfo = { |
|
|
const contactInfo = { |
|
|
iat: Date.now(), |
|
|
iat: Date.now(), |
|
|
iss: this.activeDid, |
|
|
iss: this.activeDid, |
|
@ -153,13 +159,28 @@ export default class ContactQRScanShow extends Vue { |
|
|
(settings?.firstName || "") + |
|
|
(settings?.firstName || "") + |
|
|
(settings?.lastName ? ` ${settings.lastName}` : ""), // deprecated, pre v 0.1.3 |
|
|
(settings?.lastName ? ` ${settings.lastName}` : ""), // deprecated, pre v 0.1.3 |
|
|
publicEncKey, |
|
|
publicEncKey, |
|
|
nextPublicEncKeyHash: nextPublicEncKeyHashBase64, |
|
|
|
|
|
profileImageUrl: settings?.profileImageUrl, |
|
|
profileImageUrl: settings?.profileImageUrl, |
|
|
registered: settings?.isRegistered, |
|
|
registered: settings?.isRegistered, |
|
|
}, |
|
|
}, |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
const vcJwt: string = await createEndorserJwtForDid(identity.did, contactInfo); |
|
|
if (account?.mnemonic && account?.derivationPath) { |
|
|
|
|
|
const newDerivPath = nextDerivationPath( |
|
|
|
|
|
account.derivationPath as string, |
|
|
|
|
|
); |
|
|
|
|
|
const nextPublicHex = deriveAddress( |
|
|
|
|
|
account.mnemonic as string, |
|
|
|
|
|
newDerivPath, |
|
|
|
|
|
)[2]; |
|
|
|
|
|
const nextPublicEncKey = Buffer.from(nextPublicHex, "hex"); |
|
|
|
|
|
const nextPublicEncKeyHash = sha256(nextPublicEncKey); |
|
|
|
|
|
const nextPublicEncKeyHashBase64 = |
|
|
|
|
|
Buffer.from(nextPublicEncKeyHash).toString("base64"); |
|
|
|
|
|
contactInfo.own.nextPublicEncKeyHash = nextPublicEncKeyHashBase64; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const vcJwt = await createEndorserJwtForDid(this.activeDid, contactInfo); |
|
|
|
|
|
|
|
|
const viewPrefix = CONTACT_URL_PREFIX + ENDORSER_JWT_URL_LOCATION; |
|
|
const viewPrefix = CONTACT_URL_PREFIX + ENDORSER_JWT_URL_LOCATION; |
|
|
this.qrValue = viewPrefix + vcJwt; |
|
|
this.qrValue = viewPrefix + vcJwt; |
|
|
} |
|
|
} |
|
@ -409,7 +430,7 @@ export default class ContactQRScanShow extends Vue { |
|
|
); |
|
|
); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
onCopyToClipboard() { |
|
|
onCopyUrlToClipboard() { |
|
|
//this.onScanDetect([{ rawValue: this.qrValue }]); // good for testing |
|
|
//this.onScanDetect([{ rawValue: this.qrValue }]); // good for testing |
|
|
useClipboard() |
|
|
useClipboard() |
|
|
.copy(this.qrValue) |
|
|
.copy(this.qrValue) |
|
@ -426,5 +447,22 @@ export default class ContactQRScanShow extends Vue { |
|
|
); |
|
|
); |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
onCopyDidToClipboard() { |
|
|
|
|
|
//this.onScanDetect([{ rawValue: this.qrValue }]); // good for testing |
|
|
|
|
|
useClipboard() |
|
|
|
|
|
.copy(this.activeDid) |
|
|
|
|
|
.then(() => { |
|
|
|
|
|
this.$notify( |
|
|
|
|
|
{ |
|
|
|
|
|
group: "alert", |
|
|
|
|
|
type: "info", |
|
|
|
|
|
title: "Copied", |
|
|
|
|
|
text: "Your DID was copied to the clipboard. Have them paste it on their 'People' screen to add you.", |
|
|
|
|
|
}, |
|
|
|
|
|
10000, |
|
|
|
|
|
); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
</script> |
|
|
</script> |
|
|