user management bugs fixed

bugs resolved:
Setup User: No validation applied; the form saves with empty inputs. User ID length validation is not implemented. The role column is not displayed in the table.

Reset Password: No success message is shown after password update. Strong password validation is not applied.

Change Password: No success message is shown after password update. Strong password validation is not applied. Validation to prevent using the same value for old and new passwords is not implemented.
mazdak/UX-2147
Mazdak Gibran 2 weeks ago
parent 45b34eef3f
commit f3685ba942

@ -16,7 +16,19 @@
</div> </div>
<div class="card-body"> <div class="card-body">
<form [formGroup]="firstTimeLoginForm"> <form [formGroup]="firstTimeLoginForm">
<div class="w-100">
<div class="password-wrapper">
<input type="text" id="oldPassword" class="form-control" formControlName="oldPassword" type="{{passwordType}}"
placeholder="{{ 'oldPassword' | translate }}" appNoWhitespaces />
<app-password-hide-show #psh class="password-eye align-items-stretch" [showPassword]="true"
(onEyeClick)="togglePasswordType()"></app-password-hide-show>
</div>
<div class="text-danger"
*ngIf="changePasswordForm.get('oldPassword')?.touched && changePasswordForm.get('oldPassword')?.invalid">
{{ 'fieldRequired' | translate }}
</div>
</div>
<!-- New Password --> <!-- New Password -->
<div class="mb-3"> <div class="mb-3">
<label for="newPassword" class="form-label"> <label for="newPassword" class="form-label">
@ -107,9 +119,14 @@
<app-password-hide-show #psh class="password-eye align-items-stretch" [showPassword]="true" (onEyeClick)="togglePasswordType()"></app-password-hide-show> <app-password-hide-show #psh class="password-eye align-items-stretch" [showPassword]="true" (onEyeClick)="togglePasswordType()"></app-password-hide-show>
</div> </div>
<div class="text-danger" *ngIf="changePasswordForm.get('oldPassword')?.touched && <div class="text-danger" *ngIf="changePasswordForm.get('oldPassword')?.touched ">
changePasswordForm.get('oldPassword')?.invalid"> <div *ngIf="changePasswordForm.get('oldPassword')?.hasError('required')">
{{ 'fieldRequired' | translate }} {{ 'fieldRequired' | translate }}
</div>
<div *ngIf="changePasswordForm.get('oldPassword')?.hasError('pattern')">
{{ 'passwordPattern' | translate }}
</div>
</div> </div>
</div> </div>
</div> </div>
@ -129,10 +146,21 @@
(onEyeClick)="togglePasswordType1()"></app-password-hide-show> (onEyeClick)="togglePasswordType1()"></app-password-hide-show>
</div> </div>
<div class="text-danger" *ngIf="changePasswordForm.get('newPassword')?.touched ">
<div *ngIf="changePasswordForm.get('newPassword')?.hasError('required')">
{{ 'fieldRequired' | translate }}
</div>
<div *ngIf="changePasswordForm.get('newPassword')?.hasError('pattern')">
{{ 'passwordPattern' | translate }}
</div>
<div *ngIf="changePasswordForm.hasError('oldAndNewPasswordSame')">
Old password and new password cannot be the same
</div>
</div>
<div class="text-danger" *ngIf="newPasswordError$">
{{ newPasswordError$ | translate }}
</div>
</div> </div>
</div> </div>
</div> </div>
@ -153,8 +181,18 @@
(onEyeClick)="togglePasswordType2()"></app-password-hide-show> (onEyeClick)="togglePasswordType2()"></app-password-hide-show>
</div> </div>
<div class="text-danger" *ngIf="confirmPasswordError$"> <div class="text-danger" *ngIf="changePasswordForm.get('confirmPassword')?.touched ">
{{ confirmPasswordError$ | translate }} <div *ngIf="changePasswordForm.get('confirmPassword')?.hasError('required')">
{{ 'fieldRequired' | translate }}
</div>
<div *ngIf="changePasswordForm.get('confirmPassword')?.hasError('pattern')">
{{ 'passwordPattern' | translate }}
</div>
<div *ngIf="changePasswordForm.hasError('passwordMismatch')">
{{ 'passwordsDoNotMatch' | translate }}
</div>
</div> </div>
</div> </div>

@ -43,30 +43,74 @@ constructor(private fb: FormBuilder, private httpURIService: HttpURIService, pri
this.passwordType2 = this.passwordHideShow2?.showPassword ? 'password' : 'text'; this.passwordType2 = this.passwordHideShow2?.showPassword ? 'password' : 'text';
} }
ngOnInit(): void {
this.checkIfFirstTimeChangePasswordOrNot();
if (this.isFirstLogin) {
this.firstTimeLoginForm = this.fb.group({
oldPassword: ['', Validators.required],
newPassword: ['', [
Validators.required,
Validators.minLength(8),
Validators.maxLength(20),
Validators.pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]+$/)
]],
confirmPassword: ['', [
Validators.required,
Validators.minLength(8),
Validators.maxLength(20),
Validators.pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]+$/)
]]
}, { validators: this.passwordMatchValidator });
}
else {
this.changePasswordForm = this.fb.group({
oldPassword: ['', Validators.required],
newPassword: ['', [
Validators.required,
Validators.minLength(8),
Validators.maxLength(20),
Validators.pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]+$/)
]
],
confirmPassword: ['', [
Validators.required,
Validators.minLength(8),
Validators.maxLength(20),
Validators.pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]+$/)
]
]
}, { validators: [
this.passwordMatchValidator,
this.oldAndNewPasswordNotSame,
]
},
);
}
}
passwordMatchValidator(group: AbstractControl): ValidationErrors | null { passwordMatchValidator(group: AbstractControl): ValidationErrors | null {
const newPassword = group.get('newPassword')?.value; const newPassword = group.get('newPassword')?.value;
const confirmPassword = group.get('confirmPassword')?.value; const confirmPassword = group.get('confirmPassword')?.value;
return newPassword === confirmPassword ? null : { passwordMismatch: true }; return newPassword === confirmPassword ? null : { passwordMismatch: true };
} }
ngOnInit(): void { oldAndNewPasswordNotSame(group: AbstractControl): ValidationErrors | null {
this.checkIfFirstTimeChangePasswordOrNot(); const oldPassword = group.get('oldPassword')?.value;
const newPassword = group.get('newPassword')?.value;
if (this.isFirstLogin) {
this.firstTimeLoginForm = this.fb.group({
newPassword: ['', [Validators.required, Validators.minLength(6)]],
confirmPassword: ['', [Validators.required, Validators.minLength(6)]]
}, { validators: this.passwordMatchValidator });
} else {
this.changePasswordForm = this.fb.group({
oldPassword: ['', Validators.required],
newPassword: ['', [Validators.required, Validators.minLength(6)]],
confirmPassword: ['', [Validators.required, Validators.minLength(6)]]
}, { validators: this.passwordMatchValidator });
if (!oldPassword || !newPassword) {
return null;
} }
return oldPassword === newPassword
? { oldAndNewPasswordSame: true }
: null;
} }
checkIfFirstTimeChangePasswordOrNot(): void { checkIfFirstTimeChangePasswordOrNot(): void {
try { try {
const currentUser: any = JSON.parse( const currentUser: any = JSON.parse(
@ -80,37 +124,6 @@ constructor(private fb: FormBuilder, private httpURIService: HttpURIService, pri
} }
} }
initChangePasswordForm(): void {
this.changePasswordForm = this.fb.group(
{
oldPassword: ['', Validators.required],
enterNewPassword: ['', [Validators.required, Validators.minLength(6)]],
confirmPassword: ['', [Validators.required, Validators.minLength(6)]],
},
{ validators: this.passwordMatchValidator }
);
}
get newPasswordError$() {
const control = this.changePasswordForm.get('newPassword');
if (!control || !control.touched) return null;
if (control.hasError('required')) return 'fieldRequired';
if (control.hasError('minlength')) return 'passwordTooShort';
return null;
}
get confirmPasswordError$() {
const control = this.changePasswordForm.get('confirmPassword');
if (!control || !control.touched) return null;
if (control.hasError('required')) return 'fieldRequired';
if (control.hasError('minlength')) return 'passwordTooShort';
if (this.changePasswordForm.hasError('passwordMismatch')) return 'passwordsDoNotMatch';
return null;
}
getFormPayload() { getFormPayload() {
const form = this.isFirstLogin ? this.firstTimeLoginForm : this.changePasswordForm; const form = this.isFirstLogin ? this.firstTimeLoginForm : this.changePasswordForm;

@ -40,12 +40,8 @@
placeholder="{{ 'userID' | translate }}" placeholder="{{ 'userID' | translate }}"
appNoWhitespaces appNoWhitespaces
/> />
</div> </div>
<div class="text-danger" *ngIf="resetPasswordForm.get('userId')?.touched &&
resetPasswordForm.get('userId')?.invalid">
{{ 'fieldRequired' | translate }}
</div>
</div> </div>
</div> </div>
</div> </div>
@ -57,23 +53,26 @@
class="mandatory">*</span> class="mandatory">*</span>
</label> </label>
<div class="w-100"> <div class="w-100">
<div class="password-wrapper"> <div class="password-wrapper">
<input id="enterNewPassword" <input id="enterNewPassword" formControlName="newPassword" class="form-control" autocomplete="new-password"
formControlName="newPassword" type="{{passwordType1}}" maxlength="500" placeholder="{{ 'enterNewPassword' | translate }}" appNoWhitespaces
class="form-control" rows="3" />
autocomplete="new-password" <app-password-hide-show #psh1 class="password-eye align-items-stretch" [showPassword]="true"
type="{{passwordType1}}" (onEyeClick)="togglePasswordType1()"></app-password-hide-show>
maxlength="500"
placeholder="{{ 'enterNewPassword' | translate }}" appNoWhitespaces
rows="3" />
<app-password-hide-show #psh1 class="password-eye align-items-stretch" [showPassword]="true" (onEyeClick)="togglePasswordType1()"></app-password-hide-show>
</div>
<div class="text-danger"
*ngIf="resetPasswordForm.get('newPassword')?.touched && resetPasswordForm.get('newPassword')?.invalid">
<div *ngIf="resetPasswordForm.get('newPassword')?.hasError('required')">
{{ 'fieldRequired' | translate }}
</div>
<div
*ngIf="!resetPasswordForm.get('newPassword')?.hasError('required') && resetPasswordForm.get('newPassword')?.hasError('pattern') ">
{{ 'passwordPattern' | translate }}
</div>
</div>
</div> </div>
<div class="text-danger mt-1" *ngIf="newPasswordError">
{{ newPasswordError | translate }}
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -94,8 +93,20 @@
<app-password-hide-show class="password-eye align-items-stretch" #psh2 [showPassword]="true" (onEyeClick)="togglePasswordType2()"></app-password-hide-show> <app-password-hide-show class="password-eye align-items-stretch" #psh2 [showPassword]="true" (onEyeClick)="togglePasswordType2()"></app-password-hide-show>
</div> </div>
<div class="text-danger" *ngIf="confirmPasswordError"> <div class="text-danger"
{{ confirmPasswordError | translate }} *ngIf="resetPasswordForm.get('confirmPassword')?.touched ">
<div *ngIf="resetPasswordForm.get('confirmPassword')?.hasError('required')">
{{ 'fieldRequired' | translate }}
</div>
<div
*ngIf="resetPasswordForm.get('confirmPassword')?.hasError('pattern')">
{{ 'passwordPattern' | translate }}
</div>
<div *ngIf="resetPasswordForm.hasError('passwordMismatch')">
{{ 'passwordsDoNotMatch' | translate }}
</div>
</div> </div>
</div> </div>
</div> </div>

@ -29,15 +29,27 @@ export class ResetPasswordComponent implements OnInit{
ngOnInit(): void { ngOnInit(): void {
const userIdValue = this.storageService.getItem('USER_ID') const userIdValue = this.storageService.getItem('USER_ID')
this.resetPasswordForm = this.fb.group({ this.resetPasswordForm = this.fb.group({
userId: [{value: userIdValue || '', disabled: true}],
userId: [userIdValue || '', Validators.required], newPassword: ['', [
newPassword: ['', [Validators.required, Validators.minLength(6)]], Validators.required,
confirmPassword: ['', [Validators.required, Validators.minLength(6)]] Validators.minLength(8),
Validators.maxLength(20),
Validators.pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]+$/)
]
],
confirmPassword: ['', [
Validators.required,
Validators.minLength(8),
Validators.maxLength(20),
Validators.pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]+$/)
]
]
}, },
{ {
validators: this.passwordMatchValidator validators: this.passwordMatchValidator
} }
); );
this.resetPasswordForm.get('newPassword')?.valueChanges.subscribe(()=>{ this.resetPasswordForm.get('newPassword')?.valueChanges.subscribe(()=>{
this.resetPasswordForm.get('confirmPassword')?.updateValueAndValidity(); this.resetPasswordForm.get('confirmPassword')?.updateValueAndValidity();
}); });
@ -50,39 +62,30 @@ export class ResetPasswordComponent implements OnInit{
togglePasswordType2() { togglePasswordType2() {
this.passwordType2 = this.passwordHideShow2?.showPassword ? 'password' : 'text'; this.passwordType2 = this.passwordHideShow2?.showPassword ? 'password' : 'text';
} }
passwordMatchValidator(group: AbstractControl): ValidationErrors | null {
const newPassword = group.get('newPassword')?.value;
const confirmPassword = group.get('confirmPassword')?.value;
return newPassword === confirmPassword ? null : { passwordMismatch: true }; passwordMatchValidator(group: AbstractControl): ValidationErrors | null {
} const newPassword = group.get('newPassword');
const confirmPassword = group.get('confirmPassword');
get newPasswordError() { if (!newPassword || !confirmPassword) return null;
const control = this.resetPasswordForm.get('newPassword'); if (confirmPassword.errors && !confirmPassword.errors['passwordMismatch']) {
if (!control || !control.touched) return null; return null;
}
if (control.hasError('required')) return 'fieldRequired'; if (newPassword.value !== confirmPassword.value) {
if (control.hasError('minlength')) return 'passwordTooShort'; confirmPassword.setErrors({ passwordMismatch: true });
return null; return { passwordMismatch: true };
} else {
confirmPassword.setErrors(null);
return null;
}
} }
get confirmPasswordError() {
const control = this.resetPasswordForm.get('confirmPassword');
if (!control || !control.touched) return null;
if (control.hasError('required')) return 'fieldRequired';
if (control.hasError('minlength')) return 'passwordTooShort';
if (this.resetPasswordForm.hasError('passwordMismatch')) return 'passwordsDoNotMatch';
return null;
}
onSubmit() { onSubmit() {
if (this.resetPasswordForm.invalid) return; if (this.resetPasswordForm.invalid) return;
const payload = { const payload = {
userId: this.resetPasswordForm.value.userId, userId: this.resetPasswordForm.get('userId')?.value,
newPassword: this.resetPasswordForm.value.newPassword, newPassword: this.resetPasswordForm.get('newPassword')?.value,
porOrgaCode: this.storageService.getItem('POR_ORGACODE') porOrgaCode: this.storageService.getItem('POR_ORGACODE')
}; };
this.httpURIService.requestPOST(URIKey.RESET_PASSWORD_URI, payload) this.httpURIService.requestPOST(URIKey.RESET_PASSWORD_URI, payload)
@ -93,7 +96,7 @@ export class ResetPasswordComponent implements OnInit{
} }
} }
}); });
} }
} }

@ -41,8 +41,28 @@
</div> </div>
<div class="text-danger" *ngIf="userForm.get('userId')?.touched && userForm.get('userId')?.invalid"> <div class="text-danger" *ngIf="userForm.get('userId')?.touched && userForm.get('userId')?.invalid">
{{ 'fieldRequired' | translate }} <div *ngIf="
userForm.get('userId')?.errors?.['required'] &&
!userForm.get('userId')?.value
">
{{ 'fieldRequired' | translate }}
</div>
</div>
<div class="text-danger" *ngIf="
userForm.get('userId')?.errors?.['minlength'] &&
userForm.get('userId')?.value
">
{{'userIdMinLength' | translate }}
</div> </div>
<div class="text-danger" *ngIf="
userForm.get('userId')?.errors?.['pattern'] &&
userForm.get('userId')?.value
">
{{'emptySpaceRestriction' | translate}}
</div >
</div> </div>
</div> </div>
</div> </div>
@ -63,10 +83,27 @@
placeholder="{{ 'userName' | translate }}" appNoWhitespaces placeholder="{{ 'userName' | translate }}" appNoWhitespaces
rows="3" /> rows="3" />
<div class="text-danger" *ngIf="userForm.get('userFullname')?.touched && userForm.get('userFullname')?.invalid"> <div class="text-danger" *ngIf="userForm.get('userFullname')?.touched && userForm.get('userFullname')?.invalid">
{{ 'fieldRequired' | translate }} <div *ngIf="
userForm.get('userFullname')?.errors?.['required'] &&
!userForm.get('userFullname')?.value
">
{{ 'fieldRequired' | translate }}
</div>
</div> </div>
<div class="text-danger" *ngIf="
userForm.get('userFullname')?.errors?.['minlength'] &&
userForm.get('userFullname')?.value
">
{{'nameMinLength' | translate }}
</div>
<div class="text-danger" *ngIf="
userForm.get('userFullname')?.errors?.['pattern'] &&
userForm.get('userFullname')?.value
">
{{'emptySpaceRestriction' | translate}}
</div >
</div> </div>
</div> </div>
@ -113,7 +150,15 @@
placeholder="{{ 'passwordPlaceHolder' | translate }}" appNoWhitespaces/> placeholder="{{ 'passwordPlaceHolder' | translate }}" appNoWhitespaces/>
<div class="text-danger" *ngIf="userForm.get('defaultPassword')?.touched && userForm.get('defaultPassword')?.invalid"> <div class="text-danger" *ngIf="userForm.get('defaultPassword')?.touched && userForm.get('defaultPassword')?.invalid">
{{ 'fieldRequired' | translate }} <div *ngIf="userForm.get('defaultPassword')?.hasError('required')">
{{ 'fieldRequired' | translate }}
</div>
<div *ngIf="
!userForm.get('defaultPassword')?.hasError('required') &&
userForm.get('defaultPassword')?.hasError('pattern')
">
{{ 'passwordPattern' | translate }}
</div>
</div> </div>
</div> </div>
@ -193,9 +238,10 @@
<table class="table mb-0 border"> <table class="table mb-0 border">
<thead class="table-light"> <thead class="table-light">
<tr> <tr>
<th style="width: 40%">{{'userID' | translate}}</th> <th style="width: 30%">{{'userID' | translate}}</th>
<th style="width: 40%">{{'Name' | translate}}</th> <th style="width: 30%">{{'Name' | translate}}</th>
<th style="width: 20%">{{'action' | translate}}</th> <th style="width: 30%">{{'Role' | translate}}</th>
<th style="width: 10%">{{'action' | translate}}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -204,6 +250,7 @@
<td>{{ item.userId }}</td> <td>{{ item.userId }}</td>
<td>{{ item.userFullname }}</td> <td>{{ item.userFullname }}</td>
<td>{{item.role}}</td>
<td> <td>

@ -10,8 +10,10 @@ import { ButtonManagementService } from '../../services/button-management.servic
import { StorageService } from '../../shared/services/storage.service'; import { StorageService } from '../../shared/services/storage.service';
import { TableFilterPipe } from '../../shared/pipes/table-filter.pipe'; import { TableFilterPipe } from '../../shared/pipes/table-filter.pipe';
import { URIKey } from '../../utils/uri-enums'; import { URIKey } from '../../utils/uri-enums';
import { HttpParams } from '@angular/common/http'; import { HttpErrorResponse, HttpParams } from '@angular/common/http';
import { HttpURIService } from '../../app.http.uri.service'; import { HttpURIService } from '../../app.http.uri.service';
import { I18NService } from '../../services/i18n.service';
import { SuccessMessages } from '../../utils/enums';
@ -52,7 +54,8 @@ export class SetupUserComponent implements OnInit {
private fb: FormBuilder, private fb: FormBuilder,
private buttonManagementService: ButtonManagementService, private buttonManagementService: ButtonManagementService,
private storageService: StorageService, private storageService: StorageService,
private httpService: HttpURIService private httpService: HttpURIService,
private i18nService: I18NService
){} ){}
onSearch(value: string): void { onSearch(value: string): void {
@ -95,13 +98,14 @@ export class SetupUserComponent implements OnInit {
} }
this.httpService.requestPOST<SetupUser[]>(URIKey.CREATE_USER, newUser).subscribe({ this.httpService.requestPOST<SetupUser[]>(URIKey.CREATE_USER, newUser).subscribe({
next: () => { next: (response) => {
this.userForm.reset(); if (!(response instanceof HttpErrorResponse)) {
this.mode = 'edit'; this.i18nService.success(SuccessMessages.USER_CREATED_SUCCESS, []);
this.loadUsersDirect() this.userForm.reset();
}, this.mode = 'edit';
this.loadUsersDirect()
error: (err: any) => console.error(err) }
}
}); });
@ -126,9 +130,25 @@ ngOnInit(): void {
this.getButtonPermissions(); this.getButtonPermissions();
this.userForm = this.fb.group({ this.userForm = this.fb.group({
userId: ['', [Validators.required]], userId: ['', [
userFullname: ['', [Validators.required, Validators.maxLength(500)]], Validators.required,
defaultPassword: ['', Validators.required], Validators.minLength(5),
Validators.pattern(/^\S+$/)
]
],
userFullname: ['', [
Validators.required,
Validators.minLength(5),
Validators.pattern(/^\S+$/)
]
],
defaultPassword: ['', [
Validators.required,
Validators.pattern(
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,20}$/
)
]
],
email: ['', [Validators.required, Validators.email]], email: ['', [Validators.required, Validators.email]],
userRole: [null, Validators.required] userRole: [null, Validators.required]
}); });
@ -182,14 +202,13 @@ ngOnInit(): void {
let params = new HttpParams().set('userId', userId); let params = new HttpParams().set('userId', userId);
this.httpService.requestDELETE<any>(URIKey.DELETE_USER, params).subscribe({ this.httpService.requestDELETE<any>(URIKey.DELETE_USER, params).subscribe({
next: (response) =>{ next: (response) =>{
if (!(response instanceof HttpErrorResponse)) {
this.i18nService.success(SuccessMessages.USER_DELETE_SUCCESS, []);
this.loadUsersDirect(); this.loadUsersDirect();
this.userForm.reset() this.userForm.reset();
this.selectedUserId = null; this.selectedUserId = null;
}, }
error: (err) =>{
console.error('Error fetching users:', err);
this.allItems = [];
this.isLoading = false;
} }
}) })
} }

@ -59,7 +59,10 @@ TRANSACTION_SUCCESSFUL = "TRANSACTION_SUCCESSFUL",
SAVED_SUCCESSFULLY = "SAVED_SUCCESSFULLY", SAVED_SUCCESSFULLY = "SAVED_SUCCESSFULLY",
RECORD_DELETED_SUCCESSFULY = "RECORD_DELETED_SUCCESSFULY", RECORD_DELETED_SUCCESSFULY = "RECORD_DELETED_SUCCESSFULY",
ACCOUNT_CLOSED_SUCCESSFULLY = "ACCOUNT_CLOSED_SUCCESSFULLY", ACCOUNT_CLOSED_SUCCESSFULLY = "ACCOUNT_CLOSED_SUCCESSFULLY",
SUCCESS_MESSAGE = "SUCCESS_MESSAGE" SUCCESS_MESSAGE = "SUCCESS_MESSAGE",
USER_CREATED_SUCCESS = "USER_CREATED_SUCCESS",
USER_DELETE_SUCCESS = "USER_DELETE_SUCCESS"
} }
export enum MESSAGEKEY { export enum MESSAGEKEY {

@ -260,5 +260,11 @@
"ERR_SEC_0005": "المستخدم غير موجود", "ERR_SEC_0005": "المستخدم غير موجود",
"ERR_SEC_0006": "كلمة المرور التي تم إدخالها غير صحيحة", "ERR_SEC_0006": "كلمة المرور التي تم إدخالها غير صحيحة",
"toDateGreaterThanToday": "يجب أن يكون التاريخ الحالي أقل من التاريخ الحالي", "toDateGreaterThanToday": "يجب أن يكون التاريخ الحالي أقل من التاريخ الحالي",
"fromDateGreaterThanToday": "يجب أن يكون تاريخ البدء أقل من التاريخ الحالي" "fromDateGreaterThanToday": "يجب أن يكون تاريخ البدء أقل من التاريخ الحالي",
"userIdMinLength": "يجب أن يكون معرف المستخدم مكوّنًا من 5 أحرف على الأقل",
"nameMinLength": "يجب أن يكون الاسم مكوّنًا من 5 أحرف على الأقل",
"emptySpaceRestriction": "المسافات الفارغة غير مسموح بها",
"USER_CREATED_SUCCESS": "تم إنشاء المستخدم",
"USER_DELETE_SUCCESS": "تم حذف المستخدم"
} }

@ -112,7 +112,7 @@
"oldPassword":"Old Password", "oldPassword":"Old Password",
"newPasswordStatic":"New Password", "newPasswordStatic":"New Password",
"savePassword":"Save", "savePassword":"Save",
"passwordPattern":"Password must be over 8 characters and include an uppercase letter, a lower case letter, a number and a special character", "passwordPattern":"Password must be 820 characters and include uppercase, lowercase, number, and special character",
"SMSGatewaySelect":"Select Gateway", "SMSGatewaySelect":"Select Gateway",
"selectIdentValueType": "Select Type", "selectIdentValueType": "Select Type",
"IdTypeSelect":"Select Select Type", "IdTypeSelect":"Select Select Type",
@ -260,5 +260,10 @@
"ERR_SEC_0005": "User not found", "ERR_SEC_0005": "User not found",
"ERR_SEC_0006": "Incorrect password", "ERR_SEC_0006": "Incorrect password",
"toDateGreaterThanToday": "To Date must be less than Current Date", "toDateGreaterThanToday": "To Date must be less than Current Date",
"fromDateGreaterThanToday": "From Date must be less than Current Date" "fromDateGreaterThanToday": "From Date must be less than Current Date",
"userIdMinLength" : "User ID must be at least 5 characters",
"nameMinLength" : "Name must be at least 5 characters",
"emptySpaceRestriction" : "Empty spaces are not allowed",
"USER_CREATED_SUCCESS": "User Created",
"USER_DELETE_SUCCESS": "User Deleted"
} }
Loading…
Cancel
Save