| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -159,6 +159,7 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					<script lang="ts"> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { AxiosError } from "axios"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { Buffer } from "buffer/"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import QRCodeVue3 from "qr-code-generator-vue3"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { Component, Vue } from "vue-facing-decorator"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { useClipboard } from "@vueuse/core"; | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -174,12 +175,13 @@ import * as databaseUtil from "../db/databaseUtil"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { parseJsonField } from "../db/databaseUtil"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { getContactJwtFromJwtUrl } from "../libs/crypto"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  generateEndorserJwtUrlForAccount, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  CONTACT_CSV_HEADER, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  CONTACT_IMPORT_CONFIRM_URL_PATH_TIME_SAFARI, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  register, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  setVisibilityUtil, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} from "../libs/endorserServer"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { decodeEndorserJwt, ETHR_DID_PREFIX } from "../libs/crypto/vc"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { retrieveAccountMetadata } from "../libs/util"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import * as libsUtil from "../libs/util"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { Router } from "vue-router"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { logger } from "../utils/logger"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { QRScannerFactory } from "@/services/QRScanner/QRScannerFactory"; | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -252,18 +254,19 @@ export default class ContactQRScanShow extends Vue { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        !!settings.hideRegisterPromptOnNewContact; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      this.isRegistered = !!settings.isRegistered; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      const account = await retrieveAccountMetadata(this.activeDid); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      const account = await libsUtil.retrieveAccountMetadata(this.activeDid); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      if (account) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const name = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          (settings.firstName || "") + | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          (settings.lastName ? ` ${settings.lastName}` : ""); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        this.qrValue = await generateEndorserJwtUrlForAccount( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          account, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          !!settings.isRegistered, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          name, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          settings.profileImageUrl || "", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          false, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const publicKeyBase64 = Buffer.from( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          account.publicKeyHex, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          "hex", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        ).toString("base64"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        this.qrValue = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          CONTACT_CSV_HEADER + | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          "\n" + | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          `"${name}",${account.did},${publicKeyBase64},false,${this.isRegistered}`; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } catch (error) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      logger.error("Error initializing component:", { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -274,7 +277,7 @@ export default class ContactQRScanShow extends Vue { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        group: "alert", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        type: "danger", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        title: "Initialization Error", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        text: "Failed to initialize QR scanner. Please try again.", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        text: "Failed to initialize QR renderer or scanner. Please try again.", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -461,7 +464,8 @@ export default class ContactQRScanShow extends Vue { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      logger.info("Processing QR code scan result:", rawValue); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      // Extract JWT | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      let contact: Contact; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      if (rawValue.includes(CONTACT_IMPORT_CONFIRM_URL_PATH_TIME_SAFARI)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const jwt = getContactJwtFromJwtUrl(rawValue); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (!jwt) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          logger.warn("Invalid QR code format - no JWT found in URL"); | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -473,10 +477,10 @@ export default class ContactQRScanShow extends Vue { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          return; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      // Process JWT and contact info | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        logger.info("Decoding JWT payload from QR code"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const decodedJwt = await decodeEndorserJwt(jwt); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        // Process JWT and contact info | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (!decodedJwt?.payload?.own) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          logger.warn("Invalid JWT payload - missing 'own' field"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          this.$notify({ | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -502,11 +506,25 @@ export default class ContactQRScanShow extends Vue { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        // Create contact object | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      const contact = { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        contact = { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          did: did, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          name: contactInfo.name || "", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        notes: contactInfo.notes || "", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          publicKeyBase64: contactInfo.publicKeyBase64 || "", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          seesMe: contactInfo.seesMe || false, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          registered: contactInfo.registered || false, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } else if (rawValue.startsWith(CONTACT_CSV_HEADER)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const lines = rawValue.split(/\n/); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        contact = libsUtil.csvLineToContact(lines[1]); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        this.$notify({ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          group: "alert", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          type: "danger", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          title: "Error", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          text: "Could not determine the type of contact info. Please try again.", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      // Add contact but keep scanning | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      logger.info("Adding new contact to database:", { | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -654,7 +672,6 @@ export default class ContactQRScanShow extends Vue { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    useClipboard() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .copy(this.qrValue) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .then(() => { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        // console.log("Contact URL:", this.qrValue); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        this.$notify( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            group: "alert", | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -772,7 +789,7 @@ export default class ContactQRScanShow extends Vue { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            title: "Contact Exists", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            text: "This contact has already been added to your list.", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          }, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          3000, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          5000, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |