Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,21 @@

## [Unreleased]

### [3.11.1] - 2026-06-18
### Added
- Show tile for zkp
- show zkp error message
- change the zkp label to normal user readable text
- added toggle button for widget zkp configure
- Added toggel to disable widget login

### [3.11.0] - 2026-06-18

### Added
- Added toggel to disable widget login


### [3.10.5] - 2026-06-11


### Fixed
- Fixed busines icon

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "entity-developer-dashboard",
"version": "3.11.0",
"version": "3.11.1",
"private": true,
"scripts": {
"serve": "vue-cli-service serve --mode production",
Expand Down
1 change: 0 additions & 1 deletion src/views/GettingStarted.vue
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@
depressed
small
color="white"

class="text-none font-weight-bold"
:href="`#/studio/kyb-webpage-generator/${appId()}`"
>
Expand Down
5 changes: 5 additions & 0 deletions src/views/ServiceConfig.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<template>
<b-container fluid class="py-3">
<load-ing :active.sync="isLoading" :can-cancel="true" :is-full-page="fullPage"></load-ing>

<div class="d-flex justify-content-between align-items-center mb-4 flex-wrap">
<div>
Expand Down Expand Up @@ -332,11 +333,14 @@ import messages from "../mixins/messages";
import { mapGetters, mapActions, mapMutations, mapState } from 'vuex/dist/vuex.common.js';
import LogoUploader from "../components/element/LogoUploader.vue";
import CorsChipsInput from "../components/element/CorsChips.vue";
import LoadIng from "../components/element/LoadIng.vue";
import { normalizeCorsOrigin } from '../utils/utils.js';
export default {
name: "ServiceConfig",
data() {
return {
isLoading: false,
fullPage: true,
isEditing: false,
// allow editing domain independently of full-form edit
isEditingDomain: false,
Expand Down Expand Up @@ -385,6 +389,7 @@ export default {
HfPopUp,
LogoUploader,
CorsChipsInput,
LoadIng,
},
async created() {
this.formData = { ...this.getSelectedService };
Expand Down
25 changes: 24 additions & 1 deletion src/views/playground/Sessions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@
<template v-slot:activator="{ on, attrs }">
<v-icon v-bind="attrs" v-on="on" small color="red darken-1">mdi-alert-circle-outline</v-icon>
</template>
<span>{{ getFailureReason(row.failureInfo && row.failureInfo.failureReason, row.failureInfo && row.failureInfo.failureStep) }}</span>
<span>{{ getRowFailureReason(row) }}</span>
</v-tooltip>
</div>
</td>
Expand Down Expand Up @@ -330,6 +330,7 @@ export default {
{ field: 'step_start', icon: 'fa-flag', title: 'Started' },
{ field: 'step_liveliness', icon: 'fa-user', title: 'Liveliness Check' },
{ field: 'step_ocrIdVerification', icon: 'fa-address-card', title: 'Document Verification' },
// { field: 'step_zkProofVerification', icon: 'fa-user-check', title: 'Age Verification' },
{ field: 'step_mintSbt', icon: 'fa-address-book', title: 'Mint SBT' },
{ field: 'step_userConsent', icon: 'fa-thumbs-up', title: 'User Consent' },
{ field: 'step_finish', icon: 'fa-check', title: 'Finished' },
Expand Down Expand Up @@ -412,14 +413,36 @@ export default {
filteredSteps(row) {
return this.allSteps.filter(step => row[step.field] !== null && row[step.field] !== undefined);
},
getRowFailureReason(row) {
if (row.status !== 'Failed' || !row.failureInfo) {
return 'Unknown error';
}

return this.getFailureReason(row.failureInfo.failureReason, row.failureInfo.failureStep);
},
getFailureReason(errorCode, errorType = 'step_liveliness') {
if (typeof errorCode === 'string' && isNaN(Number(errorCode))) {
return errorCode;
}

if (errorType == 'step_liveliness') {
return Config['LivelinessError'][errorCode] || 'Unknown error';
}

if (errorType == 'step_ocrIdVerification') {
return Config['FaicalAuthenticationError'][errorCode] || 'Unknown error';
}

if (errorType == 'step_zkProofVerification') {
const zkpVerificationErrors = {
0: 'Age verification could not be performed',
1: 'Age verification failed',
2: 'Age verification uncertain',
};
return zkpVerificationErrors[errorCode] || 'Age verification failed';
}

return 'Unknown error';
},
getAvatarStyle() {
// const colors = ['#607d8b', '#3f51b5', '#009688', '#ff5722', '#795548', '#673ab7', '#e91e63'];
Expand Down
176 changes: 176 additions & 0 deletions src/views/playground/SessionsDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,47 @@
</div>
</v-col>

<!-- Age Verification -->
<v-col
cols="12"
md="6"
lg="4"
id="zkp-verification-info"
v-if="zkpVerificationDataFound"
>
<div class="detail-card p-4">
<div class="card-section-title">
<i class="fa fa-user-check mr-2"></i>Age Verification
</div>
<table class="data-table w-100">
<tbody>
<tr v-if="zkpVerificationResultFound">
<td>Status</td>
<td>
<span
v-if="zkpVerificationPassed"
style="color: #28a745; font-weight: 600"
>
<i class="fa fa-check-circle mr-1"></i>Passed
</span>
<span v-else style="color: #dc3545; font-weight: 600">
<i class="fa fa-times-circle mr-1"></i>Failed
</span>
</td>
</tr>
<!-- <tr v-if="zkpVerificationResultFound">
<td>Result</td>
<td>{{ zkpVerificationResultForDisplay }}</td>
</tr> -->
<tr v-if="session.zkpVerificationDetails.createdAt">
<td>Verified At</td>
<td>{{ formatDate(session.zkpVerificationDetails.createdAt) }}</td>
</tr>
</tbody>
</table>
</div>
</v-col>

<!-- Soul Bound Token -->
<v-col
cols="12"
Expand Down Expand Up @@ -834,6 +875,7 @@ const ServiceLivenessResultEnum = {
16: "Face is obstructed",
17: "No life detected",
18: "Eyes closed",
66: "Eye is obstructed"
};

const FaicalAuthenticationError = {
Expand All @@ -845,6 +887,13 @@ const FaicalAuthenticationError = {
6: "Duplicate document was used",
};

const ZkpVerificationResultEnum = {
0: "Age verification could not be performed",
1: "Age verification failed",
2: "Age verification uncertain",
3: "Age verification passed",
};

export default {
name: "sessionDetails",
components: {
Expand Down Expand Up @@ -963,6 +1012,21 @@ export default {
sbtDataFound() {
return this.session?.mintsbtsDetails && this.session.mintsbtsDetails.length > 0;
},
zkpVerificationDataFound() {
return this.hasObjectData(this.session?.zkpVerificationDetails);
},
zkpVerificationResultFound() {
return this.hasValue(
this.session?.zkpVerificationDetails?.serviceZkpVerificationResult
);
},
zkpVerificationPassed() {
return this.session?.zkpVerificationDetails?.serviceZkpVerificationResult == 3;
},
zkpVerificationResultForDisplay() {
const result = this.session?.zkpVerificationDetails?.serviceZkpVerificationResult;
return ZkpVerificationResultEnum[result] || `Result ${result}`;
},
startFinishDiffInSeconds() {
if (this.userConsentDataFound) {
const startDate = new Date(this.session.createdAt);
Expand Down Expand Up @@ -1184,9 +1248,23 @@ export default {
}
}

if (this.isZkpVerificationTimelineDetail(newItem)) {
newItem.stepName = "Age verification";
if (this.hasValue(newItem.result) && newItem.result != 3) {
newItem.error = newItem?.failureReason||"Age verification failed"
}
}

return newItem;
});
}

const zkpTimelineDetail = this.buildZkpVerificationTimelineDetail();
if (zkpTimelineDetail && !this.timeLineDetails.some(this.isZkpVerificationTimelineDetail)) {
this.timeLineDetails.push(zkpTimelineDetail);
}

this.applySessionFailureToTimeline();
} catch (e) {
this.notifyErr(e.message);
this.isLoading = false;
Expand All @@ -1205,6 +1283,104 @@ export default {
const d = new Date(date);
return d.toLocaleString(); // Customize formatting if needed
},
applySessionFailureToTimeline() {
if (this.session?.status !== "Failed") return;

const failureInfo = this.session?.failureInfo;
if (!failureInfo) {
return;
}

const failureReason = this.getFailureReason(
failureInfo.failureReason,
failureInfo.failureStep
);

this.timeLineDetails = this.timeLineDetails.map((item) => {
if (!this.isTimelineDetailForFailureStep(item, failureInfo.failureStep)) {
return item;
}

return {
...item,
error: failureReason,
};
});
},
isTimelineDetailForFailureStep(item, failureStep) {
const stepName = item?.step_name || item?.stepName;
const failureStepMap = {
step_liveliness: ["liveliness", "Selfie uploaded"],
step_ocrIdVerification: ["ocrIdDoc", "Document uploaded"],
step_zkProofVerification: [
"zkpVerification",
"zkProofVerification",
"Age verification",
],
step_zkpVerification: [
"zkpVerification",
"zkProofVerification",
"Age verification",
],
step_mintSbt: ["mintSbt", "Mint SBT", "Soul Bound Token"],
};

return (failureStepMap[failureStep] || []).includes(stepName);
},
getFailureReason(errorCode, errorType) {
if (typeof errorCode === "string" && isNaN(Number(errorCode))) {
return errorCode;
}

if (errorType === "step_liveliness") {
return ServiceLivenessResultEnum[errorCode] || "Liveliness check failed";
}

if (errorType === "step_ocrIdVerification") {
return FaicalAuthenticationError[errorCode] || "Document verification failed";
}

if (
errorType === "step_zkProofVerification" ||
errorType === "step_zkpVerification"
) {
return ZkpVerificationResultEnum[errorCode] || "Age verification failed";
}

if (errorType === "step_mintSbt") {
return "SBT minting failed";
}

return "Verification failed";
},
isZkpVerificationTimelineDetail(item) {
return (
item?.step_name === "zkpVerification" ||
item?.step_name === "zkProofVerification" ||
item?.stepName === "zkpVerification" ||
item?.stepName === "zkProofVerification" ||
item?.stepName === "Age verification"
);
},
buildZkpVerificationTimelineDetail() {
const details = this.session?.zkpVerificationDetails;
if (!details?.createdAt) return null;

const result = details.serviceZkpVerificationResult;
const timelineDetail = {
step_name: "zkpVerification",
stepName: "Age verification",
createdAt: details.createdAt,
result,
};

if (this.hasValue(result) && result != 3) {
timelineDetail.error =
ZkpVerificationResultEnum[result] || "Age verification failed";
}

return timelineDetail;
},
formatFieldValue(key, value) {
if (!value && value !== 0) return value;
const dateKeys = /date|dob|birth|expir|issued|valid/i;
Expand Down
Loading
Loading