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/components/settings/OnlySSIApps.vue b/src/components/settings/OnlySSIApps.vue
index 4617939..25be55d 100644
--- a/src/components/settings/OnlySSIApps.vue
+++ b/src/components/settings/OnlySSIApps.vue
@@ -209,7 +209,13 @@
-
+
+
+
+
+
@@ -814,8 +820,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];
@@ -874,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();
}
@@ -1235,6 +1244,7 @@ export default {
domain: "",
hasDomainVerified: false,
domainLinkageCredentialString: "",
+ whitelistedCors: "*"
};
this.selectedAssociatedSSIAppId = "";
this.domain = "";
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/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/Apps.vue b/src/views/Apps.vue
index ef82e57..aaedbcf 100644
--- a/src/views/Apps.vue
+++ b/src/views/Apps.vue
@@ -373,13 +373,13 @@
-
+ placeholder="http://your-domain.com,http://test.com">
+
@@ -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,10 @@ export default {
const appModel = this.getAppByAppId(appId);
//// commeting it for time being
- // appModel.whitelistedCors = appModel.whitelistedCors.toString();
- appModel.whitelistedCors = '*';
+ if (appModel.services && appModel.services.length > 0) {
+ this.selectedServiceId = appModel.services[0].id;
+ }
+ appModel.whitelistedCors = appModel.whitelistedCors.toString();
Object.assign(this.appModel, { ...appModel });
this.selectedAssociatedSSIAppId = appModel.dependentServices[0];
@@ -1334,23 +1337,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();
}
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 }})
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ selectedVerificationMethodType }}
+
+
+
+
- -->
+
@@ -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) {
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()