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
@@ -10,6 +10,7 @@
|
||||
import { Component, OnInit, inject } from '@angular/core';
|
||||
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
|
||||
import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
|
||||
/** Custom Services */
|
||||
import { UsersService } from '../users.service';
|
||||
@@ -27,7 +28,8 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
imports: [
|
||||
...STANDALONE_SHARED_IMPORTS,
|
||||
MatCheckbox,
|
||||
MatIcon
|
||||
MatIcon,
|
||||
MatSnackBarModule
|
||||
]
|
||||
})
|
||||
export class EditUserComponent implements OnInit {
|
||||
@@ -35,6 +37,7 @@ export class EditUserComponent implements OnInit {
|
||||
private usersService = inject(UsersService);
|
||||
private route = inject(ActivatedRoute);
|
||||
private router = inject(Router);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
|
||||
/** User Data */
|
||||
userData: any;
|
||||
@@ -81,7 +84,8 @@ export class EditUserComponent implements OnInit {
|
||||
this.userData.email,
|
||||
[
|
||||
Validators.required,
|
||||
Validators.email
|
||||
Validators.email,
|
||||
Validators.pattern(/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/)
|
||||
]
|
||||
],
|
||||
mobileNo: [
|
||||
@@ -135,14 +139,30 @@ export class EditUserComponent implements OnInit {
|
||||
*/
|
||||
submit() {
|
||||
const editedUser = this.editUserForm.value;
|
||||
this.usersService.editUser(this.userData.id, editedUser).subscribe((response: any) => {
|
||||
this.router.navigate(
|
||||
[
|
||||
'../../',
|
||||
response.resourceId
|
||||
],
|
||||
{ relativeTo: this.route }
|
||||
);
|
||||
this.usersService.editUser(this.userData.id, editedUser).subscribe({
|
||||
next: (response: any) => {
|
||||
// Fineract sometimes omits resourceId in PUT responses — fall back to
|
||||
// the user id we're editing so navigation never silently no-ops.
|
||||
const targetId = response?.resourceId ?? this.userData.id;
|
||||
this.snackBar.open('User updated successfully', 'OK', {
|
||||
duration: 3000,
|
||||
panelClass: ['success-snackbar']
|
||||
});
|
||||
this.router.navigate(
|
||||
[
|
||||
'../../',
|
||||
targetId
|
||||
],
|
||||
{ relativeTo: this.route }
|
||||
);
|
||||
},
|
||||
error: (err) => {
|
||||
console.error('[EditUser] update failed', err);
|
||||
this.snackBar.open('Failed to update user', 'Close', {
|
||||
duration: 4000,
|
||||
panelClass: ['error-snackbar']
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user