From cb8ae956c79529a7ad56bd7ed74eb71d22abd30a Mon Sep 17 00:00:00 2001 From: Ben Stokes Date: Wed, 9 Sep 2026 12:36:26 +0100 Subject: [PATCH] feat: view multiple vericiation sessions + re-verify block on reject --- .../src/app/data/services/identity.service.ts | 4 +++ .../connected-account-detail.component.html | 12 +++++-- .../connected-account-detail.component.ts | 35 +++++++++++-------- .../account/settings/settings.component.ts | 12 ++++--- 4 files changed, 42 insertions(+), 21 deletions(-) diff --git a/apps/web/src/app/data/services/identity.service.ts b/apps/web/src/app/data/services/identity.service.ts index c71ff68..2b737c5 100644 --- a/apps/web/src/app/data/services/identity.service.ts +++ b/apps/web/src/app/data/services/identity.service.ts @@ -33,6 +33,7 @@ export class IdentityService { params: { relatedAccount?: string; limit?: number; + startingAfter?: string; } = {} ): Promise> { const query: Record = {}; @@ -42,6 +43,9 @@ export class IdentityService { if (params.limit !== undefined) { query['limit'] = String(params.limit); } + if (params.startingAfter) { + query['starting_after'] = params.startingAfter; + } return this.api.Call>( 'GET', 'identity/verification_sessions', diff --git a/apps/web/src/app/features/account/connected-accounts/views/connected-account-detail/connected-account-detail.component.html b/apps/web/src/app/features/account/connected-accounts/views/connected-account-detail/connected-account-detail.component.html index 8753e43..c1ea9e1 100644 --- a/apps/web/src/app/features/account/connected-accounts/views/connected-account-detail/connected-account-detail.component.html +++ b/apps/web/src/app/features/account/connected-accounts/views/connected-account-detail/connected-account-detail.component.html @@ -408,10 +408,16 @@

Identity requirements

} - } @if (diditSessionId(); as sessionId) { + } @if (diditSessionIds().length > 0) {
-
Didit session
-
+
+ Didit session{{ diditSessionIds().length > 1 ? 's' : '' }} +
+ @for (sessionId of diditSessionIds(); track sessionId) { +
+ +
+ }
} @if ( !GetIdentityStatusLabel() && GetCurrentlyDue().length === 0 && GetPendingVerification().length === 0 && GetRequirementErrors().length === diff --git a/apps/web/src/app/features/account/connected-accounts/views/connected-account-detail/connected-account-detail.component.ts b/apps/web/src/app/features/account/connected-accounts/views/connected-account-detail/connected-account-detail.component.ts index 3c1a95b..6a8ac75 100644 --- a/apps/web/src/app/features/account/connected-accounts/views/connected-account-detail/connected-account-detail.component.ts +++ b/apps/web/src/app/features/account/connected-accounts/views/connected-account-detail/connected-account-detail.component.ts @@ -108,7 +108,7 @@ export class ConnectedAccountDetailViewComponent implements OnInit, OnDestroy { availableBalance: WritableSignal = signal(0); pendingBalance: WritableSignal = signal(0); externalWallets: WritableSignal = signal([]); - diditSessionId: WritableSignal = signal(null); + diditSessionIds: WritableSignal = signal([]); idCopied: WritableSignal = signal(false); private idCopiedTimer?: ReturnType; @@ -410,7 +410,7 @@ export class ConnectedAccountDetailViewComponent implements OnInit, OnDestroy { if (this.account()?.id === id) return; this.account.set(null); - this.diditSessionId.set(null); + this.diditSessionIds.set([]); this.activeTab.set('overview'); this.detailPanel.set('main'); this.moneyMovementTab.set('payouts'); @@ -431,7 +431,7 @@ export class ConnectedAccountDetailViewComponent implements OnInit, OnDestroy { await Promise.all([ this.RefreshBalance(id), this.LoadWallets(id, account), - this.LoadLatestVerificationSession(id), + this.LoadVerificationSessions(id), ]); } finally { this.loading.set(false); @@ -470,19 +470,26 @@ export class ConnectedAccountDetailViewComponent implements OnInit, OnDestroy { } } - private async LoadLatestVerificationSession( - accountId: string - ): Promise { + private async LoadVerificationSessions(accountId: string): Promise { try { - const result = await this.identityService.ListVerificationSessions({ - relatedAccount: accountId, - limit: 1, - }); - this.diditSessionId.set( - result.data[0]?.provider_session_id?.trim() || null - ); + const ids: string[] = []; + let startingAfter: string | undefined; + for (;;) { + const result = await this.identityService.ListVerificationSessions({ + relatedAccount: accountId, + limit: 100, + startingAfter, + }); + for (const session of result.data) { + const id = session.provider_session_id?.trim(); + if (id) ids.push(id); + } + if (!result.has_more || result.data.length === 0) break; + startingAfter = result.data[result.data.length - 1].id; + } + this.diditSessionIds.set(ids); } catch { - this.diditSessionId.set(null); + this.diditSessionIds.set([]); } } diff --git a/apps/web/src/app/features/account/settings/settings.component.ts b/apps/web/src/app/features/account/settings/settings.component.ts index 3d82fd2..28f8125 100644 --- a/apps/web/src/app/features/account/settings/settings.component.ts +++ b/apps/web/src/app/features/account/settings/settings.component.ts @@ -44,6 +44,7 @@ import { GetIdentityDocumentTaskTitle, NeedsIdentityDocumentRemediation, } from '../connected-accounts/util/identity-requirements'; +import { IsRejectedAccountReason } from '@zoneless/shared-schemas'; @Component({ selector: 'app-settings', @@ -118,11 +119,14 @@ export class SettingsComponent implements OnInit { identityVerificationStarting: WritableSignal = signal(false); identityVerificationError: WritableSignal = signal(''); - readonly showIdentityTask = computed( - () => + readonly showIdentityTask = computed(() => { + const account = this.accountService.account(); + return ( !this.authService.isPlatform() && - NeedsIdentityDocumentRemediation(this.accountService.account()) - ); + !IsRejectedAccountReason(account?.requirements?.disabled_reason) && + NeedsIdentityDocumentRemediation(account) + ); + }); readonly identityRepresentativeName = computed(() => { const personName = this.personService.GetFullName(