From 41e5ccfa974b0a3f53a445820b41896a20452069 Mon Sep 17 00:00:00 2001 From: Varsha Kumari Date: Tue, 17 Feb 2026 12:36:44 +0530 Subject: [PATCH 1/6] removed space from url before validating it --- src/mixins/fieldValidation.js | 2 +- src/views/playground/developer/WebhookConfig.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mixins/fieldValidation.js b/src/mixins/fieldValidation.js index aa19780..f23e82a 100644 --- a/src/mixins/fieldValidation.js +++ b/src/mixins/fieldValidation.js @@ -1,7 +1,7 @@ import validURL from 'valid-url' export function isValidURL(str) { - return validURL.isUri(str); + return validURL.isUri(str.trim()); } // export function isDomain(str) // { diff --git a/src/views/playground/developer/WebhookConfig.vue b/src/views/playground/developer/WebhookConfig.vue index ca896f3..3abe031 100644 --- a/src/views/playground/developer/WebhookConfig.vue +++ b/src/views/playground/developer/WebhookConfig.vue @@ -167,7 +167,7 @@ export default { this.isLoading = true; this.validateField() await this.createAppWebhookConfig({ - "webhookUrl": this.webhookUrl, + "webhookUrl": this.webhookUrl.trim(), "header": this.getHeadersForSave() }) this.formatConfig() From 33350730b5b50fc655c3c85b993fc5212c9a47e0 Mon Sep 17 00:00:00 2001 From: Varsha Kumari Date: Tue, 17 Feb 2026 13:42:07 +0530 Subject: [PATCH 2/6] allowing whitelisted cors to update --- src/views/Apps.vue | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/views/Apps.vue b/src/views/Apps.vue index ef82e57..8d2e550 100644 --- a/src/views/Apps.vue +++ b/src/views/Apps.vue @@ -934,6 +934,7 @@ import { sanitizeUrl } from "../utils/common"; // import DeployOnChainKYC from "../components/deploy-onchain-kyc-popup/deploy.vue"; import DomainLinkage from "@hypersign-protocol/domain-linkage-verifier"; import config from "../config"; +import {isValidOrigin} from '../mixins/fieldValidation.js'; export default { name: "AppList", computed: { @@ -1290,8 +1291,7 @@ export default { const appModel = this.getAppByAppId(appId); //// commeting it for time being - // appModel.whitelistedCors = appModel.whitelistedCors.toString(); - appModel.whitelistedCors = '*'; + appModel.whitelistedCors = appModel.whitelistedCors.toString(); Object.assign(this.appModel, { ...appModel }); this.selectedAssociatedSSIAppId = appModel.dependentServices[0]; @@ -1334,23 +1334,24 @@ export default { } } - // console.log('----------------------------------------------------------------') - // console.log(this.appModel.whitelistedCors) - // if (!Array.isArray(this.appModel.whitelistedCors)) { - // const newArray = this.appModel.whitelistedCors?.split(",").filter((x) => x != " ").map((x) => x.trim()); - // for (let i = 0; i < newArray.length; i++) { - // if (!isValidOrigin(newArray[i])) { - // m.push(messages.APPLICATION.INVALID_CORS); - // break; - // } - // } - // } - + if (!Array.isArray(this.appModel.whitelistedCors)) { + const newArray = this.appModel.whitelistedCors?.split(",").map((x) => x.trim()).filter((x) => x.length > 0); + for (let i = 0; i < newArray.length; i++) { + if (!isValidOrigin(newArray[i])) { + m.push(messages.APPLICATION.INVALID_CORS); + break; + } + } + } if (!this.appModel.domain) { m.push(messages.APPLICATION.ENTER_DOMAIN_ORGIN); } else { try { - const t = new URL(this.appModel.domain); + let domain = this.appModel.domain?.trim(); + if (domain && !domain.startsWith("http://") && !domain.startsWith("https://")) { + domain = `https://${domain}`; + } + const t = new URL(domain); if (!t.origin || t.host == "") { throw new Error(); } From 54e01d2ad5e687f23ccc833ef0235a2650af13af Mon Sep 17 00:00:00 2001 From: Varsha Kumari Date: Tue, 17 Feb 2026 14:47:41 +0530 Subject: [PATCH 3/6] allowing to update issuer --- src/views/Apps.vue | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/views/Apps.vue b/src/views/Apps.vue index 8d2e550..aaedbcf 100644 --- a/src/views/Apps.vue +++ b/src/views/Apps.vue @@ -373,13 +373,13 @@ - + placeholder="http://your-domain.com,http://test.com"> +
@@ -1291,6 +1291,9 @@ export default { const appModel = this.getAppByAppId(appId); //// commeting it for time being + if (appModel.services && appModel.services.length > 0) { + this.selectedServiceId = appModel.services[0].id; + } appModel.whitelistedCors = appModel.whitelistedCors.toString(); Object.assign(this.appModel, { ...appModel }); From d4de3eaad8fb165b5a24612e0766ea8909e5e09b Mon Sep 17 00:00:00 2001 From: Varsha Kumari Date: Tue, 17 Feb 2026 14:48:09 +0530 Subject: [PATCH 4/6] removed * from whitelisted cors --- src/components/settings/OnlySSIApps.vue | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/settings/OnlySSIApps.vue b/src/components/settings/OnlySSIApps.vue index 4617939..2b08df9 100644 --- a/src/components/settings/OnlySSIApps.vue +++ b/src/components/settings/OnlySSIApps.vue @@ -814,8 +814,7 @@ export default { const appModel = this.getAppByAppId(appId); //// commeting it for time being - // appModel.whitelistedCors = appModel.whitelistedCors.toString(); - appModel.whitelistedCors = '*'; + appModel.whitelistedCors = appModel.whitelistedCors.toString(); Object.assign(this.appModel, { ...appModel }); this.selectedAssociatedSSIAppId = appModel.dependentServices[0]; From 135cab9cd2f212d928f023a4f2ee38770a9c1526 Mon Sep 17 00:00:00 2001 From: Varsha Kumari Date: Wed, 18 Feb 2026 11:18:52 +0530 Subject: [PATCH 5/6] enabled whitelistedCors edit in appConfig --- src/components/settings/OnlySSIApps.vue | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/components/settings/OnlySSIApps.vue b/src/components/settings/OnlySSIApps.vue index 2b08df9..25be55d 100644 --- a/src/components/settings/OnlySSIApps.vue +++ b/src/components/settings/OnlySSIApps.vue @@ -209,7 +209,13 @@
- +
+ + + +
@@ -873,7 +879,11 @@ export default { m.push(messages.APPLICATION.ENTER_DOMAIN_ORGIN); } else { try { - const t = new URL(this.appModel.domain); + let domain = this.appModel.domain?.trim(); + if (domain && !domain.startsWith("http://") && !domain.startsWith("https://")) { + domain = `https://${domain}`; + } + const t = new URL(domain); if (!t.origin || t.host == "") { throw new Error(); } @@ -1234,6 +1244,7 @@ export default { domain: "", hasDomainVerified: false, domainLinkageCredentialString: "", + whitelistedCors: "*" }; this.selectedAssociatedSSIAppId = ""; this.domain = ""; From d242a7a61e3bd95a971bcf314e05a07da393788a Mon Sep 17 00:00:00 2001 From: Pratap2018 Date: Wed, 18 Feb 2026 13:51:36 +0530 Subject: [PATCH 6/6] fix: bugs realted to issuer config and --- src/components/MarketplaceList.vue | 36 +-- src/store/mainStore.js | 2 - src/views/ServiceConfig.vue | 248 +++++++++++++++++++- src/views/playground/WidgetConfig/Index.vue | 43 ++-- 4 files changed, 269 insertions(+), 60 deletions(-) diff --git a/src/components/MarketplaceList.vue b/src/components/MarketplaceList.vue index ed5bba8..0aed32e 100644 --- a/src/components/MarketplaceList.vue +++ b/src/components/MarketplaceList.vue @@ -19,7 +19,7 @@
-
@@ -113,21 +113,24 @@ export default { computed: { ...mapGetters('mainStore', ['getMarketPlaceApps']), services() { - return this.getMarketPlaceApps + return this.getMarketPlaceApps.filter(app => !!app.issuerDid) } - }, - beforeMount() { - }, methods: { - ...mapMutations("mainStore", ["updateAnMarketPlaceApp", 'insertMarketplaceApps']), + ...mapMutations("mainStore", ['insertMarketplaceApps']), onIssuerToggle(eachOrg) { + // Toggle selected state and commit to the store + const updated = this.getMarketPlaceApps.map(x => + x.appId === eachOrg.appId ? { ...x, selected: !x.selected } : x + ) + this.insertMarketplaceApps(updated) + const updatedOrg = updated.find(x => x.appId === eachOrg.appId) this.$emit('selectedServiceEvent', { - issuerDid: eachOrg.issuerDid, - selected: eachOrg.selected, - appId: eachOrg.appId + issuerDid: updatedOrg.issuerDid, + selected: updatedOrg.selected, + appId: updatedOrg.appId }) - }, + }, formattedAppName(appName) { if (appName == "" || appName == undefined) appName = "No app name"; return this.truncate(appName, 25); @@ -140,19 +143,6 @@ export default { return domain } }, - serviceSelected(eachOrg) { - if (eachOrg) { - const t = this.getMarketPlaceApps.map((x) => { - if (x.appId === eachOrg.appId) { - x['selected'] = x['selected'] && x['selected'] == true ? false : true; - } - return x - }) - this.insertMarketplaceApps(t) - this.$emit('selectedServiceEvent', eachOrg); - } - - } }, mixins: [UtilsMixin], diff --git a/src/store/mainStore.js b/src/store/mainStore.js index d33904f..1053700 100644 --- a/src/store/mainStore.js +++ b/src/store/mainStore.js @@ -1310,7 +1310,6 @@ const mainStore = { const authToken = getters.getSelectedService.access_token const headers = UtilsMixin.methods.getKycServiceHeader(authToken); const data = getters.getWidgetnConfig; - data['issuerVerificationMethodId'] = getters.getWidgetnConfig.issuerDID + '#key-1'; fetch(url, { method: 'POST', headers, @@ -1367,7 +1366,6 @@ const mainStore = { const authToken = getters.getSelectedService.access_token const headers = UtilsMixin.methods.getKycServiceHeader(authToken); const data = getters.getWidgetnConfig; - data['issuerVerificationMethodId'] = getters.getWidgetnConfig.issuerDID + '#key-1'; fetch(url, { method: 'PATCH', headers, diff --git a/src/views/ServiceConfig.vue b/src/views/ServiceConfig.vue index bf6403a..98d0f25 100644 --- a/src/views/ServiceConfig.vue +++ b/src/views/ServiceConfig.vue @@ -217,17 +217,72 @@ --> - + +
+ DID Configuration +
+
+
+ + - + + — Select a DID — + + {{ did }} + + + + + + + + + + - - + + + + + {{ formData.issuerDid ? '— Select a Verification Method —' : '— Select a DID first —' }} + + + {{ vm.id }} ({{ vm.type }}) + + + + - --> + @@ -272,7 +327,7 @@ import HfPopUp from "../components/element/hfPopup.vue"; import UtilsMixin from '../mixins/utils' import messages from "../mixins/messages"; -import { mapGetters, mapActions } from 'vuex/dist/vuex.common.js'; +import { mapGetters, mapActions, mapMutations, mapState } from 'vuex/dist/vuex.common.js'; export default { name: "ServiceConfig", data() { @@ -282,6 +337,8 @@ export default { appIdToGenerateSecret: "", linkedAppErrorMessage: "", showVerificationInfo: false, + associatedSSIServiceDIDs: [], + issuerVerificationMethodIds: [], formData: { }, @@ -295,7 +352,8 @@ export default { }; }, computed: { - ...mapGetters("mainStore", ["getSelectedService"]), + ...mapGetters("mainStore", ["getSelectedService", "getAppsWithSSIServices"]), + ...mapState({ widgetConfig: state => state.mainStore.widgetConfig }), formattedErrorMessage() { return this.linkedAppErrorMessage.replace(/\n/g, "
"); }, @@ -316,15 +374,30 @@ export default { ? "hypersign-domain-verification.did=" + this.formData.issuerDid : null; }, + selectedVerificationMethodType() { + if (!this.formData.issuerVerificationMethodId || !this.issuerVerificationMethodIds.length) { + return null; + } + const vm = this.issuerVerificationMethodIds.find( + v => v.id === this.formData.issuerVerificationMethodId + ); + return vm ? vm.type : null; + }, }, components: { HfPopUp }, - created() { + async created() { this.formData = { ...this.getSelectedService }; this.isProd = this.formData.env === "prod"; - - console.log(this.isProd) + + // Fetch DIDs for display/selection + await this.fetchDIDsForDisplay(); + + // If DID is already set, fetch verification methods for display + if (this.formData.issuerDid) { + await this.fetchVerificationMethodsForDisplay(); + } }, watch: { isProd(newVal) { @@ -332,10 +405,149 @@ export default { } }, methods: { - ...mapActions("mainStore", ["updateAnAppOnServer", "deleteAnAppOnServer"]), - startEdit() { + ...mapActions("mainStore", ["updateAnAppOnServer", "deleteAnAppOnServer", "fetchDIDsForAService", "resolveDIDForAKycService", "updateAppsWidgetConfig"]), + ...mapMutations("mainStore", ["setWidgetConfig"]), + async fetchDIDsForDisplay() { + try { + const ssiServiceId = this.formData.dependentServices && this.formData.dependentServices[0]; + if (!ssiServiceId) return; + + const associatedSSIService = this.getAppsWithSSIServices.find( + (x) => x.appId === ssiServiceId + ); + + if (!associatedSSIService) return; + + const payload = { + tenantUrl: associatedSSIService.tenantUrl, + accessToken: associatedSSIService.access_token, + }; + const allDIDs = await this.fetchDIDsForAService(payload); + + if (allDIDs && Array.isArray(allDIDs) && allDIDs.length > 0) { + this.associatedSSIServiceDIDs = allDIDs; + } else { + this.associatedSSIServiceDIDs = []; + } + } catch (e) { + console.error('Error fetching DIDs for display:', e); + } + }, + async fetchVerificationMethodsForDisplay() { + try { + const ssiServiceId = this.formData.dependentServices && this.formData.dependentServices[0]; + if (!ssiServiceId) return; + + const associatedSSIService = this.getAppsWithSSIServices.find( + (x) => x.appId === ssiServiceId + ); + + if (!associatedSSIService) return; + + const payload = { + tenantUrl: associatedSSIService.tenantUrl, + accessToken: associatedSSIService.access_token, + did: this.formData.issuerDid + }; + const didDocument = await this.resolveDIDForAKycService(payload); + this.issuerVerificationMethodIds = didDocument.verificationMethod.filter(vm => vm); + } catch (e) { + // Silently fail for display purposes + console.error('Error fetching verification methods for display:', e); + } + }, + async fetchDIDs() { + try { + // Find the associated SSI service + const ssiServiceId = this.formData.dependentServices && this.formData.dependentServices[0]; + if (!ssiServiceId) { + throw new Error('No associated SSI service found'); + } + + const associatedSSIService = this.getAppsWithSSIServices.find( + (x) => x.appId === ssiServiceId + ); + + if (!associatedSSIService) { + throw new Error('Associated SSI service not found'); + } + + this.isLoading = true; + const payload = { + tenantUrl: associatedSSIService.tenantUrl, + accessToken: associatedSSIService.access_token, + }; + const allDIDs = await this.fetchDIDsForAService(payload); + + if (allDIDs && Array.isArray(allDIDs) && allDIDs.length > 0) { + // DIDs are returned as strings, not objects + this.associatedSSIServiceDIDs = allDIDs; + } else { + this.associatedSSIServiceDIDs = []; + this.notifyErr('No DIDs found for the associated SSI service'); + } + this.isLoading = false; + } catch (e) { + this.isLoading = false; + console.error('Error fetching DIDs:', e); + this.notifyErr(e.message); + } + }, + async resolveDid(event) { + try { + let did; + if (typeof event === 'string') { + did = event; + } else { + did = event.target.value; + } + + if (!did) { + this.issuerVerificationMethodIds = []; + return; + } + + // Find the associated SSI service + const ssiServiceId = this.formData.dependentServices && this.formData.dependentServices[0]; + if (!ssiServiceId) { + throw new Error('No associated SSI service found'); + } + + const associatedSSIService = this.getAppsWithSSIServices.find( + (x) => x.appId === ssiServiceId + ); + + if (!associatedSSIService) { + throw new Error('Associated SSI service not found'); + } + + this.isLoading = true; + const payload = { + tenantUrl: associatedSSIService.tenantUrl, + accessToken: associatedSSIService.access_token, + did + }; + const didDocument = await this.resolveDIDForAKycService(payload); + this.issuerVerificationMethodIds = didDocument.verificationMethod.filter(vm => vm); + this.isLoading = false; + } catch (e) { + this.isLoading = false; + this.notifyErr(e.message); + } + }, + async startEdit() { this.backupData = JSON.parse(JSON.stringify(this.formData)); this.isEditing = true; + + // Fetch DIDs if not already loaded + if (!this.associatedSSIServiceDIDs.length) { + await this.fetchDIDs(); + } + + // If DID is already set, resolve it to get verification methods + if (this.formData.issuerDid) { + await this.resolveDid(this.formData.issuerDid); + } }, cancelEdit() { this.formData = JSON.parse(JSON.stringify(this.backupData)); @@ -353,6 +565,18 @@ export default { this.isLoading = true; await this.updateAnAppOnServer({ ...this.formData }) + + // Sync issuerDid and issuerVerificationMethodId into widget config + if (this.formData.issuerDid && Object.keys(this.widgetConfig).length > 0) { + const updatedWidgetConfig = { + ...this.widgetConfig, + issuerDID: this.formData.issuerDid, + issuerVerificationMethodId: this.formData.issuerVerificationMethodId || this.widgetConfig.issuerVerificationMethodId, + } + this.setWidgetConfig(updatedWidgetConfig) + await this.updateAppsWidgetConfig() + } + this.notifySuccess("Service configuration updated successfully!"); }catch(err){ this.notifyErr(err.message); diff --git a/src/views/playground/WidgetConfig/Index.vue b/src/views/playground/WidgetConfig/Index.vue index d7e22dd..736f8c4 100644 --- a/src/views/playground/WidgetConfig/Index.vue +++ b/src/views/playground/WidgetConfig/Index.vue @@ -146,7 +146,7 @@ ul {
- @@ -156,10 +156,10 @@ ul {
  • - {{ + {{ this.widgetConfigUI.faceRecog.label }} - - + + This feature is always enabled and cannot be turned off.
  • @@ -246,18 +246,15 @@ ul {
    -
  • -
  • +
  • @@ -414,14 +411,9 @@ export default { this.isLoading = true // TODO: this we can stop until onchain feature is ready for production await this.fetchAppsOnChainConfigs() - this.isLoading = false - - this.isLoading = true await this.fetchAppsWidgetConfig() - this.isLoading = false - await this.fetchMarketPlaceAppsFromServer() - + this.isLoading = false } catch (e) { this.isLoading = false console.log(e) @@ -432,7 +424,7 @@ export default { } if (Object.keys(this.widgetConfig).length > 0) { - this.widgetConfigTemp = { ...this.widgetConfig } + this.widgetConfigTemp = JSON.parse(JSON.stringify(this.widgetConfig)) } this.trustedIssuersList = this.getMarketPlaceApps; @@ -613,13 +605,18 @@ export default { ...mapActions('mainStore', ['fetchAppsOnChainConfigs', 'fetchMarketPlaceAppsFromServer', 'createAppsWidgetConfig', 'fetchAppsWidgetConfig', 'updateAppsWidgetConfig']), selectedServiceEventHandler(event) { - console.log('inside selectedServiceEventHandler event ' + event.issuerDid) - if (!this.selectedIssuerDids.has(event.issuerDid)) { + // Guard: ignore entries with no issuerDid + if (!event.issuerDid || !event.issuerDid.trim()) return + + // Use explicit selected flag instead of toggle to stay in sync + if (event.selected) { this.selectedIssuerDids.add(event.issuerDid) } else { this.selectedIssuerDids.delete(event.issuerDid) } - this.widgetConfigTemp.issuerDID = Array.from(this.selectedIssuerDids.values()).join(',') + this.widgetConfigTemp.issuerDID = Array.from(this.selectedIssuerDids.values()) + .filter(did => !!did && !!did.trim()) + .join(',') }, validateField() { if (!this.widgetConfigTemp.issuerDID) { @@ -644,7 +641,7 @@ export default { if (!this.widgetConfigTemp.onChainId.selectedOnChainKYCconfiguration) { throw new Error('Kindly select a onchain configuration') } - this.widgetConfigTemp.onChainId.selectedOnChainKYCconfiguration = this.widgetConfigTemp.onChainId.selectedOnChainKYCconfiguration.filter(e => e != null) + this.widgetConfigTemp.onChainId.selectedOnChainKYCconfiguration = this.widgetConfigTemp.onChainId.selectedOnChainKYCconfiguration.filter(e => !!e) if (!this.widgetConfigTemp.zkProof.enabled) { throw new Error('Enable ZK Proof to enable onchainId') @@ -669,7 +666,7 @@ export default { this.setWidgetConfig(this.widgetConfigTemp) await this.createAppsWidgetConfig() if (this.widgetConfig) { - this.widgetConfigTemp = { ...this.widgetConfig } + this.widgetConfigTemp = JSON.parse(JSON.stringify(this.widgetConfig)) } this.isLoading = false @@ -682,7 +679,7 @@ export default { deleteZkProof(proof) { this.widgetConfigTemp.zkProof.proofs = this.widgetConfigTemp.zkProof.proofs.filter(x => x.proofType != proof) - this.updateConfiguration() + // User must click Save/Update to persist — consistent with addZkProof }, addZkProof(proofType, criteria) {