diff --git a/Changelog.md b/Changelog.md index 64b21dcc..c423e322 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,6 +2,28 @@ ## [Unreleased] +## [3.15.2] - 2026-09-21 + +### Added + +- Added user search by name, user ID, session ID, and email. + +### Fixed + +- Fixed user avatar colors changing while searching. + +## [3.15.1] - 2026-09-18 + +### Fixed + +- Fixed login will not allow /studio/login authenticated users + +## [3.15.0] - 2026-09-16 + +### Added + +- Improved User and Attempt Details UI. + ## [3.14.7] - 2026-09-04 ### Added diff --git a/package.json b/package.json index 04371066..e111242e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "entity-developer-dashboard", - "version": "3.14.7", + "version": "3.15.2", "private": true, "scripts": { "serve": "vue-cli-service serve --mode production", diff --git a/src/components/session-details/SessionDecisionHistory.vue b/src/components/session-details/SessionDecisionHistory.vue new file mode 100644 index 00000000..6c38b645 --- /dev/null +++ b/src/components/session-details/SessionDecisionHistory.vue @@ -0,0 +1,296 @@ + + + + + diff --git a/src/components/session-details/SessionManualReviewModal.vue b/src/components/session-details/SessionManualReviewModal.vue new file mode 100644 index 00000000..0139b659 --- /dev/null +++ b/src/components/session-details/SessionManualReviewModal.vue @@ -0,0 +1,250 @@ + + + + + diff --git a/src/components/session-details/SessionProfileSummary.vue b/src/components/session-details/SessionProfileSummary.vue new file mode 100644 index 00000000..b8d19738 --- /dev/null +++ b/src/components/session-details/SessionProfileSummary.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/components/session-details/SessionRiskFlagList.vue b/src/components/session-details/SessionRiskFlagList.vue new file mode 100644 index 00000000..f5de623c --- /dev/null +++ b/src/components/session-details/SessionRiskFlagList.vue @@ -0,0 +1,267 @@ + + + + + diff --git a/src/components/stepper/StepCompanyDetails.vue b/src/components/stepper/StepCompanyDetails.vue index 137bbd25..bf086f43 100644 --- a/src/components/stepper/StepCompanyDetails.vue +++ b/src/components/stepper/StepCompanyDetails.vue @@ -338,6 +338,7 @@ export default { BUSINESS_INTERESTED_IN: { KYC: "Know Your Customer (KYC)", KYB: "Know Your Business (KYB)", + AADHAR_VERIFICATION: "Aadhaar Verification", AGE_VERIFICATION: "Age Verification", PROOF_OF_PERSONHOOD: "Proof of Personhood", AML_SCREEN: "AML Screening", diff --git a/src/config.js b/src/config.js index c718d21c..f9f47817 100644 --- a/src/config.js +++ b/src/config.js @@ -170,12 +170,28 @@ config['LivelinessError'] = { 13: 'The face is too close to border', }; +config['JurisdictionRestrictionReason'] = Object.freeze({ + RESTRICTED_ISSUING_COUNTRY: 'RESTRICTED_ISSUING_COUNTRY', + RESTRICTED_NATIONALITY: 'RESTRICTED_NATIONALITY', + ISSUING_COUNTRY_NOT_ALLOWED: 'ISSUING_COUNTRY_NOT_ALLOWED', + NATIONALITY_NOT_ALLOWED: 'NATIONALITY_NOT_ALLOWED', +}) + +config['IdDocumentVerificationFailureCode'] = Object.freeze({ + RESTRICTED_ISSUING_COUNTRY: 8, + RESTRICTED_NATIONALITY: 9, + ISSUING_COUNTRY_NOT_ALLOWED: 10, + NATIONALITY_NOT_ALLOWED: 11, + JURISDICTION_MANUAL_REVIEW_REQUIRED: 12, +}) + config['FaicalAuthenticationError'] = { 0: 'Face check could not be performed', 1: 'Faces does not match', 2: 'Face not found in the image', 4: 'Rejected, to perform face check due to the pose of the face', 5: 'Rejected, due to problems in the extraction of the facial pattern', + // --- Document Related Error --- // 6: 'Rejected, because document has already been verified in some other account with this service', 7: 'Failed, because the date of birth could not be read correctly from the document', 8: 'Failed, because document issuing country is restricted', diff --git a/src/mixins/utils.js b/src/mixins/utils.js index 0121e0f4..9bdd3bc0 100644 --- a/src/mixins/utils.js +++ b/src/mixins/utils.js @@ -57,22 +57,12 @@ export default { } }, - copyToClip(textToCopy, contentType) { - if (textToCopy) { - navigator.clipboard - .writeText(textToCopy) - .then(() => { - this.notifySuccess( - `${contentType} copied!` - ); - }) - .catch((err) => { - this.notifyErr( - 'Error while copying', - err - ); - }); - } + copyToClip(textToCopy, contentType = 'Value') { + if (!textToCopy) return; + + navigator.clipboard.writeText(String(textToCopy)) + .then(() => this.notifySuccess(`${contentType} was copied`)) + .catch(() => this.notifyErr('Error while copying')); }, shorten(str) { if (!str || str === 'undefined') { @@ -188,11 +178,11 @@ export default { }, getUserStatus(status) { - // Sucess, Expired, Pending + const label = this.getUserStatusLabel(status); if (status == 'Success') { return ` - Approved + ${label} ` } @@ -233,10 +223,18 @@ export default { return ` - Pending + ${label} ` }, + getUserStatusLabel(status) { + if (status == 'Success') return 'Approved'; + if (status == 'Failed' || status == 'REJECTED') return 'Rejected'; + if (status == 'MANUAL_REVIEW') return 'Manual Review'; + if (status == 'Expired') return 'Expired'; + return 'Pending'; + }, + isValidEmail(email) { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); diff --git a/src/router.js b/src/router.js index 3ebd5f8e..921b66cd 100644 --- a/src/router.js +++ b/src/router.js @@ -85,7 +85,11 @@ const router = new Router({ { path: '/studio/login', name: 'PKIIdLogin', - component: PKIIdLogin + component: PKIIdLogin, + meta: { + guestOnly: true, + title: `${config.app.name} - Login` + } }, { path: '/studio/mfa', @@ -350,6 +354,10 @@ router.beforeEach(async (to, from, next) => { document.title = to.meta.title; } + if (to.meta.guestOnly && isAuthenticated) { + return next({ name: 'dashboard' }); + } + // console.log("BeforeEach →", { // requiresAuth: to.meta.requiresAuth, // isAuthenticated, diff --git a/src/store/mainStore.js b/src/store/mainStore.js index eb57850a..b357fcda 100644 --- a/src/store/mainStore.js +++ b/src/store/mainStore.js @@ -2362,13 +2362,26 @@ const mainStore = { headers }) }) - .then(response => response.json()).then(json => { + .then(async response => { + const json = await response.json() + if (!response.ok) { + const details = json.error?.details + const message = Array.isArray(details) + ? details.join(' ') + : json.error?.message || json.error || json.message || 'Unable to fetch session details' + throw new Error(message) + } + return json + }).then(json => { if (json.error) { - return reject(new Error(json.error?.details.join(' ') || json.error.join(' '))) + const details = json.error?.details + const message = Array.isArray(details) + ? details.join(' ') + : json.error?.message || json.error || json.message || 'Unable to fetch session details' + return reject(new Error(message)) } if (json.data && Object.keys(json.data)?.length > 0) { - commit('updateSessionDetails', json.data); return resolve(json.data) } else { return reject(new Error('Invalid session Id or details not found')) diff --git a/src/views/playground/Sessions.vue b/src/views/playground/Sessions.vue index c22e778f..faa14bfe 100644 --- a/src/views/playground/Sessions.vue +++ b/src/views/playground/Sessions.vue @@ -159,6 +159,22 @@ color: #374151; padding: 2px 10px; } + +.sessions-search { + max-width: 45vw; + width: 360px; +} + +.sessions-search .search-btn { + cursor: pointer; +} + +.search-empty-state { + padding: 48px 16px; + text-align: center; + color: #6b7280; + font-size: 0.85rem; +}