feat: DSC enrollment + MFA controls, user CRUD UX, auth error hardening
- DSC module: list/enroll/revoke dialogs and dsc.service (m_bank_user_dsc API) - Access control: DSC + MFA toggles via disable-confirm-dialog - Two-factor auth: expanded UX (DSC + OTP flows) - Users: create/edit form polish, success snackbar on edit, DSC widget retained only inside dsc/ (removed from view-user) - Auth: X-Requested-With added globally; error handler null-safe on empty 500 bodies Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
3b752dc6ae
commit
09fab88451
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Copyright since 2025 Mifos Initiative
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
export type DscCertStatus = 'ACTIVE' | 'EXPIRED' | 'REVOKED';
|
||||
export type DscChallengeStatusValue = 'PENDING' | 'VERIFIED' | 'FAILED' | 'EXPIRED';
|
||||
|
||||
/**
|
||||
* One row in m_bank_user_dsc as returned by GET /v1/dsc/me, GET /v1/dsc/user/{userId} and
|
||||
* GET /v1/dsc/{id}. Field names match the backend's BankUserDscData DTO verbatim. Only the
|
||||
* full serial is null on list endpoints; everything else is populated.
|
||||
*/
|
||||
export interface BankUserDsc {
|
||||
id: number;
|
||||
appUserId: number;
|
||||
username: string;
|
||||
dscName: string;
|
||||
/** Last six chars visible; the rest masked with bullets. Always present. */
|
||||
dscSerialNoMasked: string;
|
||||
/** Full serial — null on list endpoints, populated by GET /v1/dsc/{id}. */
|
||||
dscSerialNoFull: string | null;
|
||||
dscType: string;
|
||||
commonName: string;
|
||||
issuedTo: string;
|
||||
issuedBy: string;
|
||||
dscExpiryDate: string;
|
||||
dateOfSubmission: string;
|
||||
certStatus: DscCertStatus;
|
||||
revokedOn: string | null;
|
||||
revokeReason: string | null;
|
||||
}
|
||||
|
||||
/** Response from POST /v1/dsc/enroll/start. */
|
||||
export interface DscEnrollSession {
|
||||
randomNo: string;
|
||||
jnlpUrl: string;
|
||||
statusUrl: string;
|
||||
expiresInSeconds: number;
|
||||
/**
|
||||
* Pre-stringified JSON the helper expects in its launch argument. The UI embeds this verbatim
|
||||
* into a locally-built JNLP file's <argument> element — JWS never has to fetch a JNLP from
|
||||
* the server.
|
||||
*/
|
||||
helperArgsJson: string;
|
||||
/** Relative URL the UI XHRs to fetch the helper JAR bytes (Authed via the HTTP interceptor). */
|
||||
helperJarUrl: string;
|
||||
}
|
||||
|
||||
/** Response from GET /v1/dsc/enroll/{rn}/status. */
|
||||
export interface DscChallengeStatus {
|
||||
randomNo: string;
|
||||
status: DscChallengeStatusValue;
|
||||
errorMessage: string | null;
|
||||
/** Set only when status === 'VERIFIED'. */
|
||||
dsc: BankUserDsc | null;
|
||||
}
|
||||
|
||||
/** Response from POST /v1/login/dsc/challenge. */
|
||||
export interface DscLoginChallenge {
|
||||
randomNo: string;
|
||||
jnlpUrl: string;
|
||||
statusUrl: string;
|
||||
expiresInSeconds: number;
|
||||
/** Same shape as {@link DscEnrollSession.helperArgsJson} but for SIGN_CHALLENGE mode. */
|
||||
helperArgsJson: string;
|
||||
/** Same as {@link DscEnrollSession.helperJarUrl}. */
|
||||
helperJarUrl: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Response from GET /v1/login/dsc/{rn}/status and POST /v1/login/dsc/{rn}/claim. The /status
|
||||
* endpoint never sets tfaToken; the /claim endpoint sets it exactly once (single-use).
|
||||
*/
|
||||
export interface DscLoginStatus {
|
||||
randomNo: string;
|
||||
status: DscChallengeStatusValue;
|
||||
errorMessage: string | null;
|
||||
tfaToken: string | null;
|
||||
tfaTokenLiveSeconds: number | null;
|
||||
}
|
||||
Reference in New Issue
Block a user