Merge pull request 'GBRSP/UX-1599' (#13) from GBRSP/UX-1599 into dev-pending-09-12-2025

Reviewed-on: https://ct.mfsys.com.pk/aConnect/aConnect-UX/pulls/13
aconnect-UX/1715
Naeem Ullah 6 days ago
commit 6f2843b805

@ -26,7 +26,9 @@
"@ng-select/ng-select": "^14.8.0",
"@ngx-translate/core": "^17.0.0",
"@ngx-translate/http-loader": "^16.0.1",
"@types/crypto-js": "^4.2.2",
"bootstrap": "^5.3.8",
"crypto-js": "^4.2.0",
"express": "^4.18.2",
"ngx-spinner": "^19.0.0",
"ngx-toastr": "^19.1.0",

@ -1,2 +1,3 @@
<app-loader></app-loader>
<app-notifications></app-notifications>
<router-outlet></router-outlet>

@ -5,10 +5,11 @@ import { StorageService } from './shared/services/storage.service';
import { isPlatformBrowser } from '@angular/common';
import { directions, supportedLanguages } from './utils/enums';
import { LoaderComponent } from './shared/components/loader/loader.component';
import { NotificationsComponent } from './shared/components/notifications/notifications.component';
@Component({
selector: 'app-root',
imports: [RouterOutlet, LoaderComponent],
imports: [RouterOutlet, LoaderComponent, NotificationsComponent],
templateUrl: './app.component.html',
styleUrl: './app.component.scss'
})

@ -0,0 +1,125 @@
import { HttpHeaders, HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { filter, Observable, Observer } from 'rxjs';
import { HttpService } from './shared/services/http.service';
import { URIService } from './app.uri';
import { URIKey } from '../app/utils/uri-enums';
@Injectable(
{ providedIn: 'root' }
)
export class HttpURIService {
constructor(private http: HttpService, private uriService: URIService) {
}
requestGET<T>(uriKey: URIKey | string, params?: HttpParams): Observable<T> {
return new Observable((observer: Observer<any>) => {
this.uriService.canSubscribe.pipe(filter(val => val)).subscribe(val => {
let uri: string = this.uriService.getURIForRequest(uriKey as URIKey)
this.http.requestGET<T>(uri, params).subscribe(t => {
observer.next(t),
observer.complete()
},
error => {
console.error(error);
observer.next(error),
observer.complete()
});
});
});
}
requestPOST<T>(uriKey: URIKey | string, body: any, headers?: HttpHeaders, params?: HttpParams): Observable<T> {
return new Observable((observer: Observer<any>) => {
this.uriService.canSubscribe.pipe(filter(val => val)).subscribe(val => {
let uri: string = this.uriService.getURIForRequest(uriKey as URIKey)
this.http.requestPOST<T>(uri, body, headers, params).subscribe(
t => {
observer.next(t),
observer.complete()
},
error => {
console.error(error);
observer.next(error),
observer.complete()
}
);
});
});
}
requestPOSTMultipart<T>(uriKey: URIKey | string, body: any, headers?: HttpHeaders, params?: HttpParams): Observable<T> {
return new Observable((observer: Observer<any>) => {
this.uriService.canSubscribe.pipe(filter(val => val)).subscribe(val => {
let uri: string = this.uriService.getURIForRequest(uriKey as URIKey)
this.http.requestPOSTMultipart<T>(uri, body, headers, params).subscribe(
t => {
observer.next(t),
observer.complete()
},
error => {
console.error(error);
observer.next(error),
observer.complete()
}
);
});
});
}
requestDELETE<T>(uriKey: URIKey | string, params: HttpParams): Observable<T> {
return new Observable((observer: Observer<any>) => {
this.uriService.canSubscribe.pipe(filter(val => val)).subscribe(val => {
let uri: string = this.uriService.getURIForRequest(uriKey as URIKey)
this.http.requestDELETE<T>(uri, params).subscribe(t => {
observer.next(t),
observer.complete()
},
error => {
console.error(error);
observer.next(error),
observer.complete()
}
);
});
});
}
requestPATCH<T>(uriKey: URIKey | string, body: any, headers?: HttpHeaders, params?: HttpParams): Observable<T> {
return new Observable((observer: Observer<any>) => {
this.uriService.canSubscribe.pipe(filter(val => val)).subscribe(val => {
let uri: string = this.uriService.getURIForRequest(uriKey as URIKey)
this.http.requestPATCH<T>(uri, body, headers, params).subscribe(t => {
observer.next(t),
observer.complete()
},
error => {
console.error(error);
observer.next(error),
observer.complete()
}
);
});
});
}
requestPUT<T>(uriKey: URIKey | string, body: any, headers?: HttpHeaders, params?: HttpParams): Observable<T> {
return new Observable((observer: Observer<any>) => {
this.uriService.canSubscribe.pipe(filter(val => val)).subscribe(val => {
let uri: string = this.uriService.getURIForRequest(uriKey as URIKey)
this.http.requestPUT<T>(uri, body, headers, params).subscribe(t => {
observer.next(t),
observer.complete()
},
error => {
console.error(error);
observer.next(error),
observer.complete()
}
);
});
});
}
}

@ -2,7 +2,8 @@ import { Routes } from '@angular/router';
import { LoginComponent } from './authenticate/login/login.component';
import { ChangePasswordComponent } from './user-management/change-password/change-password.component';
import { FullLayoutComponent } from './full-layout/full-layout.component';
import { GAuth } from './shared/guards/gauth.guard';
import { AuthenticationGuard } from './shared/guards/authentication.guard';
// import { ActivityGuard } from './shared/guards/activity.guard';
export const routes: Routes = [
{
@ -21,7 +22,7 @@ export const routes: Routes = [
{
path: 'home',
component: FullLayoutComponent,
canActivate: [GAuth],
canActivate: [AuthenticationGuard],
children: [
{
path: '',
@ -37,6 +38,9 @@ export const routes: Routes = [
},
{
path: 'permissions',
// will need this guard in future when permissions are implemented.
// commenting them for now.
// canActivate: [ActivityGuard],
loadComponent: () =>
import('./user-permissions/user-permissions.component').then(
m => m.UserPermissionsComponent
@ -44,6 +48,7 @@ export const routes: Routes = [
},
{
path: 'smsLogger',
// canActivate: [ActivityGuard],
loadComponent: () =>
import('./sms-banking/sms-banking.component').then(
m => m.SmsBankingComponent
@ -51,6 +56,7 @@ export const routes: Routes = [
},
{
path: 'smsGateway',
// canActivate: [ActivityGuard],
loadComponent: () =>
import('./sms-gateway/sms-gateway.component').then(
m => m.SmsGatewayComponent
@ -58,6 +64,7 @@ export const routes: Routes = [
},
{
path: 'loggerManager',
// canActivate: [ActivityGuard],
loadComponent: () =>
import('./logging/logging.component').then(
m => m.LoggingComponent
@ -65,6 +72,7 @@ export const routes: Routes = [
},
{
path: 'analysis',
// canActivate: [ActivityGuard],
loadComponent: () =>
import('./data-analysis/data-analysis.component').then(
m => m.DataAnalysisComponent
@ -72,6 +80,7 @@ export const routes: Routes = [
},
{
path: 'ibUnblockUser',
// canActivate: [ActivityGuard],
loadComponent: () =>
import('./ib-support/ib-unblock-user/ib-unblock-user.component').then(
m => m.IbUnblockUserComponent
@ -79,6 +88,7 @@ export const routes: Routes = [
},
{
path: 'feedbackSetup',
// canActivate: [ActivityGuard],
loadComponent: () =>
import('./ib-support/feedback-setup/feedback-setup.component').then(
m => m.FeedbackSetupComponent
@ -86,6 +96,7 @@ export const routes: Routes = [
},
{
path: 'purposeSetup',
// canActivate: [ActivityGuard],
loadComponent: () =>
import('./ib-support/tran-purpose-setup/tran-purpose-setup.component').then(
m => m.TranPurposeSetupComponent
@ -93,6 +104,7 @@ export const routes: Routes = [
},
{
path: 'thirdPartyRegistration',
// canActivate: [ActivityGuard],
loadComponent: () =>
import('./user-management/third-party-registration/third-party-registration.component').then(
m => m.ThirdPartyRegistrationComponent
@ -100,6 +112,7 @@ export const routes: Routes = [
},
{
path: 'setupUser',
// canActivate: [ActivityGuard],
loadComponent: () =>
import('./user-management/setup-user/setup-user.component').then(
m => m.SetupUserComponent
@ -107,6 +120,7 @@ export const routes: Routes = [
},
{
path: 'resetPassword',
// canActivate: [ActivityGuard],
loadComponent: () =>
import('./user-management/reset-password/reset-password.component').then(
m => m.ResetPasswordComponent
@ -114,6 +128,7 @@ export const routes: Routes = [
},
{
path: 'changePassword',
// canActivate: [ActivityGuard],
loadComponent: () =>
import('./user-management/change-password/change-password.component').then(
m => m.ChangePasswordComponent

@ -0,0 +1,84 @@
import { HttpClient } from '@angular/common/http';
import { Injectable, OnInit } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { environment } from '../environments/environment';
import { URIKey } from './utils/uri-enums';
@Injectable({
providedIn: 'root',
})
export class URIService {
canSubscribe: BehaviorSubject<boolean>;
uriMap: Map<URIKey, string>;
constructor(private http: HttpClient) {
this.canSubscribe = new BehaviorSubject(<boolean>false);
this.uriMap = new Map<URIKey, string>();
this.loadURIs();
}
loadURIs(): void {
this.http.get<URIInfo[]>('assets/data/app.uri.json')
.subscribe(data => {
for (const item of data) {
const baseURI = environment.moduleHost.get(item.Id) as string;
if (baseURI) {
for (const module of item.Modules) {
for (const page of module.Pages) {
const uri = `${baseURI}${module.URI}${page.URI}`;
const key = URIKey[page.UUID as keyof typeof URIKey];
if (key !== undefined) {
this.uriMap.set(key, uri);
}
}
}
}
}
this.canSubscribe.next(true);
});
}
getURI(key: URIKey): string | undefined {
return this.uriMap.get(key);
}
getURIForRequest(key: URIKey): string {
let uri = this.getURI(key as URIKey);
if (uri != undefined) {
return uri;
}
else {
let arr = key.split("/");
if (arr.length) {
let db = arr[0];
let baseurl = environment.moduleHost.get(db.toUpperCase() + "_DOMAIN_URI");
if (baseurl != undefined) {
uri = (baseurl).concat("/").concat(key);
return uri;
}
}
}
return key;
}
}
export interface URIInfo {
Id: string;
URI: string;
Modules: URIModule[];
}
interface URIModule {
Id: string;
URI: string;
Pages: URIPage[];
}
interface URIPage {
Id: string;
URI: string;
UUID: string;
}

@ -0,0 +1,23 @@
export interface AuthenticationToken {
token: string;
}
export interface AuthenticationResponse extends AuthenticationToken {
authenticated: boolean
porOrgacode: string;
userId: string;
userType: string;
password: string;
userHomevac: string;
}
export class UserCredentials {
porOrgacode!: string;
userId!: string;
password!: string;
token!: string;
}
export class AuthenticationRequest {
isInProgress: boolean = false;
}

@ -4,14 +4,15 @@ import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angula
import { CONSTANTS } from '../../utils/app.constants';
import { PasswordHideShowComponent } from '../../shared/components/password-hide-show/password-hide-show.component';
import { AuthService } from '../../services/auth.service';
import { Router } from '@angular/router';
import { MiscService } from '../../shared/services/misc.service';
import { User } from '../../models/user';
import { CommonModule, isPlatformBrowser } from '@angular/common';
import { StorageService } from '../../shared/services/storage.service';
import { directions, supportedLanguages } from '../../utils/enums';
import { directions, FormConstants, HiddenValues, supportedLanguages } from '../../utils/enums';
import { environment } from '../../../environments/environment';
import { AuthenticationService } from '../../services/authenticate.service';
import { UserCredentials } from '../authenticate';
@Component({
selector: 'app-login',
@ -28,10 +29,11 @@ export class LoginComponent {
passwordType: string = 'password';
direction: string = '';
supportedLanguages = supportedLanguages;
ucred: UserCredentials = new UserCredentials();
@ViewChild(PasswordHideShowComponent) passwordHideShow?: PasswordHideShowComponent;
constructor(
private authService: AuthService,
private authService: AuthenticationService,
private translateService: TranslateService,
private router: Router,
private miscService: MiscService,
@ -92,27 +94,16 @@ export class LoginComponent {
})
}
async login() {
let User: User = {
Username: this.loginForm.get("USER_ID")?.value,
Password: this.loginForm.get("PASSWORD")?.value
}
let response = await this.authService.login(User);
if ((await response["errorMessage"] == undefined)) {
if (await response) {
if (!this.authService.firstLogin) {
this.router.navigate(['home/dashboard']);
this.miscService.handleSuccess(this.translateService.instant('loginSuccess'));
}
else {
this.router.navigate(['/changepassword']);
this.miscService.handleSuccess(this.translateService.instant('passwordChangeRequired'));
}
}
}
else {
this.miscService.handleError(await response["errorMessage"])
login() {
if (this.loginForm.valid) {
this.ucred.porOrgacode = HiddenValues.POR_ORGACODE;
this.ucred.password = this.loginForm.get(FormConstants.PASSWORD)?.value;
this.ucred.userId = this.loginForm.get(FormConstants.USER_ID)?.value;
this.authService.authenticate(this.ucred).subscribe( (res: any) => {
});
}
}
onLangChange() {

@ -0,0 +1,111 @@
import { HttpErrorResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { BehaviorSubject, Observable, Observer } from 'rxjs';
import { tap } from 'rxjs/operators';
import { ErrorMessages, FormConstants, HiddenValues, SuccessMessages } from '../utils/enums';
import { CredentialService } from './credential.service';
import { AuthenticationToken, UserCredentials } from '../authenticate/authenticate';
import { HttpURIService } from '../app.http.uri.service';
import { URIKey } from '../utils/uri-enums';
import { I18NService } from './i18n.service';
import { StorageService } from '../shared/services/storage.service';
import { ButtonManagementService } from './button-management.service';
@Injectable(
{ providedIn: 'root' }
)
export class AuthenticationService {
showLicenseInfo: boolean = false;
reset: boolean = false;
public onAuthenticationComplete: BehaviorSubject<boolean> = new BehaviorSubject(<boolean>false);
constructor(private buttonManagementService: ButtonManagementService, private httpService: HttpURIService, private router: Router, private credentialService: CredentialService, private i18nService: I18NService, private storageService: StorageService) {
}
authenticate(uCreds: UserCredentials) : Observable<any> {
const observable = new Observable((observer: Observer<any>) => {
if (this.storageService.getItem('user') != null) {
this.i18nService.error(ErrorMessages.ALREADY_LOGGED_IN,[]);
return;
}
this.credentialService.setPorOrgacode(uCreds.porOrgacode);
this.credentialService.setUserId(uCreds.userId);
this.credentialService.setPassword(uCreds.password);
this.storageService.setItem(FormConstants.POR_ORGACODE, uCreds.porOrgacode);
this.storageService.setItem(FormConstants.USER_ID, uCreds.userId);
this.storageService.setItem(FormConstants.PASSWORD, uCreds.password);
this.httpService.requestPOST(URIKey.USER_LOGIN_URI, uCreds).subscribe((data: any) => {
if (!(data instanceof HttpErrorResponse)) {
data.authenticated = true;
this.i18nService.success(SuccessMessages.LOGIN_SUCCESSFULLY, []);
this.storageService.setItem('user', JSON.stringify(data));
this.credentialService.setToken(data.token);
this.credentialService.setUserType(data.userType);
if(data.permission){
this.storageService.setItem('permission', data.permission);
this.credentialService.setPermission(JSON.parse(data.permission));
}
else{
this.storageService.setItem('permission', '[]');
this.credentialService.setPermission([]);
}
this.buttonManagementService.setButtonPermissions(this.credentialService.getPermission(), this.isSuperAdminUser());
if(data.user.isFirstLogin){
this.router.navigate(["/changepassword"]);
} else {
this.router.navigate(["/home/dashboard"]);
}
this.onAuthenticationComplete.next(true);
observer.complete();
}
else {
this.onAuthenticationComplete.next(false);
observer.error(false);
}
});
});
return observable;
}
isAuthenticated(): boolean {
if (this.storageService && this.storageService.getItem('user') != null) {
let cachedUser = JSON.parse(this.storageService.getItem('user') || '{}');
return cachedUser.authenticated;
}
return false;
}
isSuperAdminUser(){
if (this.storageService && this.storageService.getItem('user') != null) {
let cachedUser = JSON.parse(this.storageService.getItem('user') || '{}');
return cachedUser.userType === HiddenValues.SUPERADMIN_USER;
}
return false;
}
refreshToken() {
let uCreds: UserCredentials = { porOrgacode: this.credentialService.getPorOrgacode(), userId: this.credentialService.getUserId(), password: this.credentialService.getPassword(), token: this.credentialService.getToken() };
return this.httpService.requestPOST<AuthenticationToken>(URIKey.USER_REFRESH_TOKEN, uCreds).pipe(
tap(response => {
this.credentialService.setToken(response.token);
let cachedUser = JSON.parse(this.storageService.getItem('user') || '{}');
cachedUser.token = response.token;
this.storageService.setItem('user', JSON.stringify(cachedUser));
})
);
}
logout() {
let defaultPermission: string = this.storageService.getItem("defaultPermission") || "{}";
this.storageService.clear();
this.storageService.setItem("defaultPermission", defaultPermission)
this.credentialService.resetService();
this.router.navigate(['/login']);
}
}

@ -0,0 +1,56 @@
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
import { PermissionNode } from "../utils/app.constants";
import { HttpURIService } from "../app.http.uri.service";
import { StorageService } from "../shared/services/storage.service";
@Injectable({
providedIn: 'root'
})
export class ButtonManagementService {
buttonPermissions: any = {};
defaultPermission: any = {};
constructor(private httpService: HttpURIService, private storageService: StorageService){
this.defaultPermissions().subscribe((data: PermissionNode[]) => {
this.defaultPermission = data;
this.storageService.setItem("defaultPermission", JSON.stringify(data));
});
}
traverse(nodes: any, isSuperAdmin: boolean) {
if (!Array.isArray(nodes)) return;
nodes.forEach(node => {
// Check if the node has buttons
if (node.buttons && Array.isArray(node.buttons) && node.buttons.length > 0) {
// Create an object for this node's buttons
this.buttonPermissions[node.name] = {};
// Map each button's name to its checked value
node.buttons.forEach((button:any) => {
this.buttonPermissions[node.name][button.name] = isSuperAdmin? true : button.checked;
});
}
// Recursively traverse children
if (node.children && Array.isArray(node.children)) {
this.traverse(node.children, isSuperAdmin);
}
});
}
setButtonPermissions(permission: any, isSuperAdmin: boolean){
if (isSuperAdmin){
if (Object.keys(this.defaultPermission).length === 0){
this.defaultPermission = JSON.parse(this.storageService.getItem("defaultPermission") || '{}');
}
this.traverse(this.defaultPermission, isSuperAdmin);
} else{
this.traverse(permission, isSuperAdmin);
}
}
defaultPermissions(): Observable<PermissionNode[]> {
return this.httpService.requestGET<PermissionNode[]>('assets/data/sideMenu.json');
}
}

@ -0,0 +1,79 @@
import { Injectable } from '@angular/core';
import { StorageService } from '../shared/services/storage.service';
@Injectable(
{ providedIn: 'root' }
)
export class CredentialService {
private porOrgacode!: string;
private userId!: string;
private userType!: string;
private password!: string;
private token!: string;
private userHomevac!: string;
private permission: any[] = [];
constructor(private storageService: StorageService){
}
getToken(): string {
return this.token;
}
setToken(token: string) {
this.token = token;
}
getPorOrgacode(): string {
return this.porOrgacode;
}
setPorOrgacode(porOrgacode: string) {
this.porOrgacode = porOrgacode
}
getUserId(): string {
return this.userId
}
setUserId(userId: string) {
this.userId = userId;
}
getUserType(): string {
return this.userType
}
setUserType(userType: string) {
this.userType = userType;
}
getPassword(): string {
return this.password;
}
setPassword(password: string) {
this.password = password;
}
getPermission(): any[] {
return this.permission;
}
setPermission(permission: any[]) {
this.permission = permission;
}
resetService() {
this.setPorOrgacode("");
this.setUserId("");
this.setUserType("");
this.setPassword("");
this.setToken("");
this.setPermission([]);
}
}

@ -0,0 +1,54 @@
import { Injectable } from '@angular/core';
import { AES, enc, pad} from 'crypto-js';
@Injectable({
providedIn: 'root'
})
export class EncryptionService {
constructor() { }
encryptData(request: any): object {
const fromKey1: number = Math.floor(Math.random() * 5) + 1;
const fromKey2: number = Math.floor(Math.random() * 5) + 1;
const key1: string = this.generateRandomKey(16);
const key2: string = this.generateRandomKey(16);
try {
let input: string;
if (typeof request === 'string') {
input = request;
} else {
input = JSON.stringify(request);
}
// Encryption
const encrypted: string = AES.encrypt(input, enc.Utf8.parse(key1), {
iv: enc.Utf8.parse(key2),
padding: pad.Pkcs7
}).toString();
const dataBeforeKey1 = encrypted.substring(0, fromKey1);
let encryptedDataSubstring = encrypted.substring(fromKey1);
const dataBeforeAfterKey2 = encryptedDataSubstring.substring(encryptedDataSubstring.length - fromKey2);
encryptedDataSubstring = encryptedDataSubstring.substring(0, encryptedDataSubstring.length - fromKey2);
const encryptedRequestData = `1${fromKey1}${dataBeforeKey1}${key1}${encryptedDataSubstring}${key2}${dataBeforeAfterKey2}${fromKey2}1`;
const encryptedDataObject = { data: encryptedRequestData };
return encryptedDataObject;
} catch (error) {
console.error(error);
return {};
}
}
generateRandomKey(length: number): string {
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let key = '';
for (let i = 0; i < length; i++) {
key += characters.charAt(Math.floor(Math.random() * characters.length));
}
return key;
}
}

@ -0,0 +1,87 @@
import { Injectable } from "@angular/core";
import { TranslateService } from "@ngx-translate/core";
import { BehaviorSubject, Observable } from "rxjs";
import { MESSAGEKEY } from "../utils/enums";
import { NotificationService } from "../shared/services/notification.service";
@Injectable(
{ providedIn: 'root' }
)
export class I18NService {
public translationsMerge: BehaviorSubject<boolean> = new BehaviorSubject(<boolean>false);
constructor(private translate: TranslateService, private notificationService: NotificationService) {
}
success(code: string, customMessage: any[], defaultText?: string): any {
let params = this.keyValueParamter(customMessage);
this.getMessageTranslate(MESSAGEKEY.SUCCESS, code, params).subscribe((res) => {
this.notificationService.success((res[code] == code && defaultText != undefined) ? defaultText : res[code]);
});
}
error(code: string, customMessage: any[], defaultText?: string): any {
let params = this.keyValueParamter(customMessage);
this.getMessageTranslate(MESSAGEKEY.ERROR, code, params).subscribe((res) => {
this.notificationService.error((res[code] == code && defaultText != undefined) ? defaultText : res[code]);
});
}
info(code: string, customMessage: any[]): any {
let params = this.keyValueParamter(customMessage);
this.getMessageTranslate(MESSAGEKEY.INFO, code, params).subscribe((res) => {
this.notificationService.info(res[code]);
});
}
warn(code: string, customMessage: any[]): any {
let params = this.keyValueParamter(customMessage);
this.getMessageTranslate(MESSAGEKEY.WARN, code, params).subscribe((res) => {
this.notificationService.warning(res[code]);
});
}
notification(code: string, customMessage: any[]): string {
let params = this.keyValueParamter(customMessage);
let notification: string = "";
this.getMessageTranslate(MESSAGEKEY.NOTIFICATION, code, params).subscribe((res) => {
notification = res[code] as string;
});
return notification;
}
keyValueParamter(params: object[]): Object {
// Create an object to hold the key-value pairs
const keyValueObject: { [key: string]: string } = {};
// Populate the object
for (let i = 0; i < params?.length; i++) {
keyValueObject[`value${i + 1}`] = String(params[i]);
}
return keyValueObject;
}
getMessageTranslate(type: string, code: string, params: any): Observable<string | any> {
if (type == MESSAGEKEY.SUCCESS) {
return this.translate.get([code, "SUC_APP_F_SUM"], params)
} else if (type == MESSAGEKEY.ERROR) {
return this.translate.get([code, "ERR_APP_F_SUM"], params)
} else if (type == MESSAGEKEY.WARN) {
return this.translate.get([code, "WRN_APP_F_SUM"], params)
} else if (type == MESSAGEKEY.INFO) {
return this.translate.get([code, "INF_APP_F_SUM"], params)
} else if (type == MESSAGEKEY.NOTIFICATION) {
return this.translate.get([code, "NTF_APP_F_SUM"], params)
} else {
return this.translate.get([code, code], params)
}
}
}

@ -3,8 +3,8 @@ import { ActivatedRoute, Router } from '@angular/router';
import { SidebarService } from '../../../services/sidebar.service';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { StorageService } from '../../services/storage.service';
import { AuthService } from '../../../services/auth.service';
import { isPlatformBrowser, formatDate, CommonModule } from '@angular/common';
import { AuthenticationService } from '../../../services/authenticate.service';
@Component({
selector: 'app-header',
@ -34,12 +34,10 @@ export class HeaderComponent {
vacName: any;
allVacs: any;
constructor(
private router: Router,
public sidebarService: SidebarService,
private translate: TranslateService,
@Inject(PLATFORM_ID) private platformId: Object,
private storageService: StorageService,
public authService: AuthService
public authService: AuthenticationService
) {
this.isDropdownVisible = false;
this.isVacDropdownVisible = false;

@ -0,0 +1,4 @@
<div *ngIf="notifications$ | async as notification" class="notification" [ngClass]="notification.type">
{{ notification.message }}
<button class="close-btn" (click)="clearNotification()">×</button>
</div>

@ -0,0 +1,88 @@
.notification {
position: fixed;
top: 20px;
right: 20px;
max-width: 400px;
padding: 16px 48px 16px 20px;
border-radius: 6px;
z-index: 10000;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
background-color: #ffffff;
color: #333333;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 14px;
line-height: 1.4;
transition: opacity 0.4s ease, transform 0.3s ease;
animation: fadeIn 0.3s ease forwards;
border-left: 8px solid #c9c9c9;
display: flex;
align-items: center;
justify-content: space-between;
&.success {
background-color: #e8f5e9;
border-color: #4caf50;
color: #2e7d32;
}
&.error {
background-color: #ffebee;
border-color: #f44336;
color: #c62828;
}
&.warning {
background-color: #fffde7;
border-color: #ffeb3b;
color: #fbc02d;
}
&.info {
background-color: #e3f2fd;
border-color: #2196f3;
color: #1976d2;
}
&.fade-out {
animation: fadeOut 0.4s ease forwards;
}
}
.close-btn {
position: absolute;
top: 12px;
right: 16px;
width: 20px;
height: 20px;
background: none;
border: none;
font-size: 20px;
color: inherit;
cursor: pointer;
transition: color 0.3s;
line-height: 1;
font-weight: bold;
&:hover {
color: #000000;
}
}
/* Animations */
@keyframes fadeIn {
from {
opacity: 0;
transform: translateX(100px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes fadeOut {
to {
opacity: 0;
transform: translateX(100px);
}
}

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NotificationsComponent } from './notifications.component';
describe('NotificationsComponent', () => {
let component: NotificationsComponent;
let fixture: ComponentFixture<NotificationsComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [NotificationsComponent]
})
.compileComponents();
fixture = TestBed.createComponent(NotificationsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

@ -0,0 +1,21 @@
import { Component } from '@angular/core';
import { Observable } from 'rxjs';
import { NotificationService } from '../../services/notification.service';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-notifications',
imports: [CommonModule],
templateUrl: './notifications.component.html',
styleUrl: './notifications.component.scss'
})
export class NotificationsComponent {
notifications$: Observable<{ type: string; message: string; } | null>
constructor(private notificationService: NotificationService) {
this.notifications$ = this.notificationService.notifications$;
}
clearNotification() {
this.notificationService.clearNotification();
}
}

@ -30,7 +30,7 @@
</a>
</li>
<li>
<a routerLink="/home/changePassword" routerLinkActive="mm-active" (click)="navigateToChangePassword()" style="cursor: pointer">
<a routerLink="/home/changePassword" routerLinkActive="mm-active" style="cursor: pointer">
<span> {{ 'changePassword' | translate }}</span>
</a>
</li>

@ -101,9 +101,4 @@ export class SideNavComponent {
}
}
navigateToChangePassword() {
this.router.navigate(['/home/changePassword'], {
state: { fromMenu: true }
});
}
}

@ -0,0 +1,59 @@
import { LocationStrategy } from '@angular/common';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
import { AuthenticationService } from '../../services/authenticate.service';
import { I18NService } from '../../services/i18n.service';
import { ErrorMessages, FormConstants } from '../../utils/enums';
import { CredentialService } from '../../services/credential.service';
@Injectable(
{ providedIn: 'root' }
)
export class ActivityGuard implements CanActivate {
constructor(private router: Router, private authService: AuthenticationService, private i18nService: I18NService, private credentialService: CredentialService) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
if (typeof window !== 'undefined' && window.localStorage) {
let permissions = JSON.parse(window.localStorage.getItem('permission') || '[]');
if (this.authService.isAuthenticated()) {
if (this.authService.isSuperAdminUser()){
return true;
}
let routeLink = (state.url.split('?'))[0];
if (this.isRouteAuthorized(routeLink, route.queryParams, permissions)) {
return true;
}
this.i18nService.error(ErrorMessages.ACCESS_DENIED, []);
window.localStorage.setItem('currentSubModule','dashboard');
this.router.navigate(["/home/dashboard"]);
return false;
} else {
this.authService.logout();
return false;
}
}
return false;
}
isRouteAuthorized(routerLink: string, queryParams: any, permissions: any): boolean {
let routePermissions : any = {}
let permissionName : any = {}
permissions.forEach((permission: any) => {
routePermissions[permission.route] = permission.checked;
permissionName[permission.name] = permission.checked;
if(permission.children.length>0){
permission.children.forEach((child: any)=>{
routePermissions[child.route] = child.checked;
permissionName[child.name] = child.checked;
})
}
});
if(routePermissions[routerLink]){
return true;
}
return false;
}
}

@ -0,0 +1,40 @@
import { LocationStrategy } from '@angular/common';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
import { AuthenticationResponse } from '../../authenticate/authenticate';
import { AuthenticationService } from '../../services/authenticate.service';
import { CredentialService } from '../../services/credential.service';
import { FormConstants } from '../../utils/enums';
import { ButtonManagementService } from '../../services/button-management.service';
@Injectable(
{ providedIn: 'root' }
)
export class AuthenticationGuard implements CanActivate {
constructor(private router: Router, private authService: AuthenticationService, private location: LocationStrategy, private credentialService: CredentialService,private buttonManagementService: ButtonManagementService) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
if (typeof window !== 'undefined' && window.localStorage) {
let data = JSON.parse(window.localStorage.getItem('user') || '{}') as AuthenticationResponse;
let permission = JSON.parse(window.localStorage.getItem('permission') || '[]');
if (this.authService.isAuthenticated()) {
this.credentialService.setPorOrgacode(window.localStorage.getItem(FormConstants.POR_ORGACODE) || '');
this.credentialService.setUserId(window.localStorage.getItem(FormConstants.USER_ID) || '');
this.credentialService.setPassword(window.localStorage.getItem(FormConstants.PASSWORD) || '');
this.credentialService.setToken(data.token);
this.credentialService.setUserType(data.userType);
this.credentialService.setPermission(permission);
this.buttonManagementService.setButtonPermissions(this.credentialService.getPermission(), this.authService.isSuperAdminUser());
this.authService.onAuthenticationComplete.next(true);
return true;
} else {
this.authService.logout();
return false;
}
}
return false;
}
}

@ -1,26 +0,0 @@
import { Inject, Injectable, PLATFORM_ID } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { isPlatformBrowser } from '@angular/common';
import { AuthService } from '../../services/auth.service';
@Injectable({
providedIn: 'root'
})
export class GAuth implements CanActivate {
constructor(private authservice: AuthService, private router: Router, @Inject(PLATFORM_ID) private platformId: object) { }
canActivate() {
if (this.authservice.IsLoggedIn()){
return true;
}
else {
if(isPlatformBrowser(this.platformId))
this.router.navigate(['login']);
return false;
}
}
}

@ -1,30 +1,34 @@
import { Injectable, Injector } from '@angular/core';
import {HttpRequest,HttpHandler,HttpEvent,HttpInterceptor,HttpErrorResponse} from '@angular/common/http';
import { BehaviorSubject, Observable, throwError } from 'rxjs';
import { AuthService } from '../../services/auth.service';
import { catchError, filter, switchMap, take, timeout } from 'rxjs/operators';
import { MiscService } from '../services/misc.service';
import { ServerException } from '../../services/app.server.response';
import { catchError, filter, switchMap, take } from 'rxjs/operators';
import { ErrorMessages } from '../../utils/enums';
import { environment } from '../../../environments/environment';
import { CredentialService } from '../../services/credential.service';
import { EncryptionService } from '../../services/encryption.service';
import { NotificationService } from '../services/notification.service';
import { I18NService } from '../../services/i18n.service';
import { AuthenticationService } from '../../services/authenticate.service';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
private isRefreshing = false;
token: any;
private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);
private logoutChannel = new BroadcastChannel('logout_channel');
constructor(private injector: Injector,private authService:AuthService) {}
private enableEncryption = environment.enableEncryption;
constructor(private injector: Injector, private credentialService: CredentialService, private encryptionService: EncryptionService, private notificationService: NotificationService, private i18nService: I18NService) {}
intercept(request: HttpRequest<any>, handler: HttpHandler): Observable<HttpEvent<any>> {
this.logoutChannel.onmessage = async (event) => {
if (event.data === 'logout') {
localStorage.clear();
window.location.href = '/#/auth';
if (this.credentialService.getPorOrgacode()!= undefined){
request = this.setDefaultHeaders(request);
}
// FOR BIOMETRIC SECUGEN WE BYPASS THESE URIS AS SECUGEN DRIVERS IS USING LOCAL ENDPOINTS.
if (this.credentialService.getToken()&& !request.url.endsWith("/SGIFPCapture")&& !request.url.endsWith("/CreateTemplate")&& !request.url.endsWith("/verifyUserBiometric")) {
request = this.addToken(request, this.credentialService.getToken());
}
};
if (this.authService.getToken()) {
request = this.addToken(request, this.authService.getToken());
if(this.enableEncryption && (request.method === "POST" || request.method === "PATCH" ) && !request.url.endsWith("/SGIFPCapture")&& !request.url.endsWith("/createTemplate")&& !request.url.endsWith("/verifyUserBiometric"))
{
request = this.setEncryptionHeader(request);
request = this.encryptRequestBody(request);
}
return handler.handle(request).pipe(catchError(error => {
if (error instanceof HttpErrorResponse && error.status === 401) {
@ -33,13 +37,24 @@ export class AuthInterceptor implements HttpInterceptor {
this.handleServerError(error);
return throwError(error);
}
}))as Observable<HttpEvent<any>>;
}));
}
private encryptRequestBody(request: HttpRequest<any>): HttpRequest<any> {
if (Object.keys(request.body).length > 0) {
const encryptedData: object = this.encryptionService.encryptData(request.body);
const encryptedRequest: any = request.clone({ body: encryptedData });
return encryptedRequest;
}
return request;
}
private handleAuthError(request: HttpRequest<any>, handler: HttpHandler) {
if (!this.isRefreshing) {
this.isRefreshing = true;
this.refreshTokenSubject.next(null);
let authService: AuthService = this.injector.get(AuthService);
let authService: AuthenticationService = this.injector.get(AuthenticationService);
return authService.refreshToken().pipe(
switchMap((response: any) => {
this.isRefreshing = false;
@ -58,6 +73,7 @@ export class AuthInterceptor implements HttpInterceptor {
}));
}
}
private handleServerError(error: HttpErrorResponse) {
let url: string = error.url as string;
let moduleName: string = "";
@ -66,42 +82,36 @@ export class AuthInterceptor implements HttpInterceptor {
url.split(':')[2].split('/')[1]:
url.split('/')[3];
}
let authService: AuthService = this.injector.get(AuthService);
let miscService: MiscService = this.injector.get(MiscService);
let authService: AuthenticationService = this.injector.get(AuthenticationService);
switch (error.status) {
case 400:
let errorResponse: ServerException = error as ServerException;
let errorResponse:any = error ;
if (errorResponse.error && errorResponse.error.errorCode != null) {
errorResponse.error.arguments.forEach((argument, index) => {
if (miscService.getErrorMessageTranslation(argument) != argument) {
errorResponse.error.arguments[index] = miscService.getErrorMessageTranslation(argument);
}
});
miscService.handleError(errorResponse.error.errorCode);
this.i18nService.error(errorResponse.error.errorCode, errorResponse.error.arguments);
} else {
miscService.handleError(ErrorMessages.BAD_REQUEST, [moduleName.toUpperCase()]);
this.i18nService.error(ErrorMessages.BAD_REQUEST,[moduleName.toUpperCase()]);
}
break;
case 401:
miscService.handleError(ErrorMessages.UNAUTHORIZED_REQUEST,[error.error.message]);
this.i18nService.error(ErrorMessages.UNAUTHORIZED_REQUEST,[]);
authService.logout();
break;
case 403:
miscService.handleError(ErrorMessages.FORBIDDEN_REQUEST,[]);
this.i18nService.error(ErrorMessages.FORBIDDEN_REQUEST,[]);
authService.logout();
break;
case 500:
miscService.handleError(ErrorMessages.INTERNAL_SERVER_ERROR,[]);
this.i18nService.error(ErrorMessages.INTERNAL_SERVER_ERROR,[moduleName.toUpperCase()]);
break;
case 0:
miscService.handleError(ErrorMessages.CONNECTION_ERROR,[]);
this.i18nService.error(ErrorMessages.CONNECTION_ERROR,[moduleName.toUpperCase()]);
break;
}
}
private addToken(request: HttpRequest<any>, token: string) {
return request.clone({
setHeaders: {
@ -110,4 +120,14 @@ export class AuthInterceptor implements HttpInterceptor {
});
}
private setDefaultHeaders(request: HttpRequest<any>): HttpRequest<any> {
const modifiedHeaders = request.headers.set('userId', this.credentialService.getUserId())
.append('porOrgacode', this.credentialService.getPorOrgacode())
return request.clone({ headers: modifiedHeaders });
}
private setEncryptionHeader(request: HttpRequest<any>): HttpRequest<any> {
const modifiedHeaders = request.headers.set('X-Encrypted', this.enableEncryption.toString());
return request.clone({ headers: modifiedHeaders });
}
}

@ -1,192 +1,108 @@
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { CONSTANTS } from '../../utils/app.constants';
import { HttpClient, HttpErrorResponse, HttpHeaders, HttpParams } from '@angular/common/http';
import { MiscService } from './misc.service';
import { TranslateService } from '@ngx-translate/core';
import { environment } from '../../../environments/environment';
import { APP_URL_KEY } from '../../utils/enums';
import { BehaviorSubject, Observable } from 'rxjs';
import { FormConstants, HiddenValues } from '../../utils/enums';
@Injectable({
providedIn: 'root'
})
@Injectable(
{ providedIn: 'root' }
)
export class HttpService {
private loadingSubject = new BehaviorSubject<boolean>(false);
loading$ = this.loadingSubject.asObservable();
API_PATH = environment.apiPath.get(APP_URL_KEY.API_PATH)
constructor(private translateService: TranslateService,
private miscService: MiscService, private http: HttpClient
) { }
getRequest(url: string, queryParams?: HttpParams, pathParams?: any, showLoader = true, options?: any) {
const custId: any = localStorage.getItem("userId");
let headers = new HttpHeaders().set("Content-Type", "application/json");
const authorization = "Bearer " + localStorage.getItem('token');
headers = headers.set("Authorization", authorization);
headers = headers.set("cmpUserId", custId);
let apiUrl = this.API_PATH + url;
this.miscService.showLoader();
apiUrl = this.replaceParamsWithValues(apiUrl, pathParams);
try {
let response = this.http.get(apiUrl, { headers: headers });
if (!(response instanceof HttpErrorResponse)) {
if (showLoader) {
this.miscService.hideLoader();
}
return response;
}
else {
this.miscService.handleError(this.translateService.instant('ServerError'));
return null;
}
}
catch (e) {
console.log(e);
return null;
}
private setLoading(loading: boolean) {
this.loadingSubject.next(loading);
}
postRequest(url: string, data?: any, pathParams?: any, isMultipart = false, showLoader = true) {
const custId = localStorage.getItem("userId");
let headers = new HttpHeaders().set("Content-Type", "application/json");
let apiUrl = this.API_PATH + url;
this.miscService.showLoader();
headers = headers.set("Authorization", "Bearer " + localStorage.getItem('token'));
if (custId != null) {
headers = headers.set("cmpUserId", custId);
}
apiUrl = this.replaceParamsWithValues(apiUrl, pathParams);
constructor(private http: HttpClient) {
let formData = data;
formData = this.setCommonParams(formData);
if (isMultipart) {
formData = this.convertToFormData(data);
}
try {
let response = this.http.post(apiUrl, formData, { headers: headers });
if (!(response instanceof HttpErrorResponse)) {
if (showLoader) {
this.miscService.hideLoader();
requestPOST<T>(url: string, body: any, headers?: HttpHeaders, params?: HttpParams): Observable<T> {
this.setLoading(true);
if (headers == undefined) {
headers = new HttpHeaders().set('Content-Type', 'application/json');
}
return response;
headers = headers.set(FormConstants.POR_ORGACODE, HiddenValues.POR_ORGACODE).set(FormConstants.CHANNEL_CODE, HiddenValues.CHANNEL_CODE)
if (params == undefined) {
return this.http.post<T>(url, body, { headers: headers })
} else {
url = this.substituePathVariables(url, params);
return this.http.post<T>(url, body, { params: params, headers: headers });
}
else {
this.miscService.handleError(this.translateService.instant('ServerError'));
return null;
}
requestPOSTMultipart<T>(url: string, body: any, headers?: HttpHeaders, params?: HttpParams): Observable<T> {
this.setLoading(true);
if (headers == undefined) {
headers = new HttpHeaders();
}
catch (e) {
console.log(e);
return null;
headers = headers.set(FormConstants.POR_ORGACODE, HiddenValues.POR_ORGACODE).set(FormConstants.CHANNEL_CODE, HiddenValues.CHANNEL_CODE)
if (params == undefined) {
return this.http.post<T>(url, body, { headers: headers })
} else {
url = this.substituePathVariables(url, params);
return this.http.post<T>(url, body, { params: params, headers: headers });
}
}
putRequest(url: string, data: any, pathParams?: any, isMultipart = false, showLoader = true) {
const custId: any = localStorage.getItem("userId");
let headers = new HttpHeaders().set("Content-Type", "application/json");
headers = headers.set("cmpUserId", custId);
headers = headers.set("Authorization", "Bearer " + localStorage.getItem('token'));
let apiUrl = this.API_PATH + url;
apiUrl = this.replaceParamsWithValues(apiUrl, pathParams);
this.miscService.showLoader();
let formData = data;
formData = this.setCommonParams(formData);
if (isMultipart) {
formData = this.convertToFormData(data);
}
try {
let response = this.http.put(apiUrl, formData, { headers: headers });
requestGET<T>(url: string, reqParams?: HttpParams): Observable<T> {
this.setLoading(true);
let httpHeaders: HttpHeaders = new HttpHeaders();
httpHeaders = httpHeaders.set(FormConstants.POR_ORGACODE,HiddenValues.POR_ORGACODE).set(FormConstants.CHANNEL_CODE,HiddenValues.CHANNEL_CODE);
if (reqParams == undefined) {
return this.http.get<T>(url, { headers: httpHeaders })
} else {
url = this.substituePathVariables(url, reqParams);
return this.http.get<T>(url, { params: reqParams, headers: httpHeaders });
}
if (!(response instanceof HttpErrorResponse)) {
if (showLoader) {
this.miscService.hideLoader();
}
return response;
requestDELETE<T>(url: string, reqParams: HttpParams): Observable<T> {
this.setLoading(true);
url = this.substituePathVariables(url, reqParams);
let httpHeaders: HttpHeaders = new HttpHeaders().set(FormConstants.POR_ORGACODE,HiddenValues.POR_ORGACODE).set(FormConstants.CHANNEL_CODE,HiddenValues.CHANNEL_CODE);
if (reqParams.keys().length > 0) {
return this.http.delete<T>(url, { params: reqParams, headers: httpHeaders });
}
else {
this.miscService.handleError(this.translateService.instant('ServerError'));
return null;
}
return this.http.delete<T>(url, { headers: httpHeaders });
}
catch (e) {
console.log(e);
return null;
}
}
deleteRequest(url: any, data: any, pathParams?: any, isMultipart = false, showLoader = true) {
const custId: any = localStorage.getItem("userId");
let apiUrl = this.API_PATH + url;
let headers = new HttpHeaders().set("Content-Type", "application/json");
headers = headers.set("Authorization", "Bearer " + localStorage.getItem('token'));
headers = headers.set("cmpUserId", custId);
apiUrl = this.replaceParamsWithValues(apiUrl, pathParams);
this.miscService.showLoader();
let formData = data;
formData = this.setCommonParams(formData);
if (isMultipart) {
formData = this.convertToFormData(data);
}
try {
let response = this.http.delete(apiUrl, { headers: headers, body: formData });
if (!(response instanceof HttpErrorResponse)) {
if (showLoader) {
this.miscService.hideLoader();
}
return response;
requestPATCH<T>(url: string, body: any, headers?: HttpHeaders, params?: HttpParams): Observable<T> {
this.setLoading(true);
if (headers == undefined) {
headers = new HttpHeaders().set('Content-Type', 'application/json');
}
else {
this.miscService.handleError(this.translateService.instant('ServerError'));
return null;
if (params != undefined) {
url = this.substituePathVariables(url, params);
}
headers = headers.set(FormConstants.POR_ORGACODE,HiddenValues.POR_ORGACODE).set(FormConstants.CHANNEL_CODE, HiddenValues.CHANNEL_CODE);
return this.http.patch<T>(url, body, { headers: headers, params: params });
}
catch (e) {
console.log(e);
return null;
requestPUT<T>(url: string, body: any, headers?: HttpHeaders, params?: HttpParams): Observable<T> {
this.setLoading(true);
if (headers == undefined) {
headers = new HttpHeaders().set('Content-Type', 'application/json');
}
if (params != undefined) {
url = this.substituePathVariables(url, params);
}
addQueryParamsToUrl(url: any, queryParams: any) {
if (queryParams && Object.keys(queryParams).length > 0) {
let toReturn = url + '?';
Object.keys(queryParams).forEach((key, index, arr) => {
toReturn += `${key}=${queryParams[key]}`;
toReturn += index === arr.length - 1 ? '' : '&';
});
return toReturn;
headers = headers.set(FormConstants.POR_ORGACODE,HiddenValues.POR_ORGACODE).set(FormConstants.CHANNEL_CODE, HiddenValues.CHANNEL_CODE);
return this.http.put<T>(url, body, { headers: headers, params: params });
}
return url;
private substituePathVariables(url: string, params: HttpParams): string {
params.keys().forEach(param => {
let pathVariable: string = `{${param}}`;
let pathValue = params.get(param);
if (url.includes(pathVariable) && pathValue != null) {
url = url.replace(pathVariable, pathValue);
params.delete(param);
}
convertToFormData(data: any) {
const formData = new FormData();
Object.keys(data).forEach((k) => {
formData.append(k, data[k]);
});
return formData;
}
replaceParamsWithValues(url: any, data: any) {
data = data ?? {};
data['porOrgacode'] = CONSTANTS.POR_ORGACODE;
if (data && Object.keys(data).length > 0) {
Object.keys(data).forEach((k) => {
url = url.replace(`{${k}}`, data[k]);
});
}
return url;
}
setCommonParams(data: any = {}) {
data = data ?? {};
data['porOrgacode'] = CONSTANTS.POR_ORGACODE;
return data;
}
}

@ -0,0 +1,40 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, timer } from 'rxjs';
import { switchMap, startWith } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class NotificationService {
private notificationSubject = new BehaviorSubject<{ type: string, message: string } | null>(null);
notifications$ = this.notificationSubject.asObservable();
success(message: string) {
this.notify('success', 'Success: ' + message);
}
error(message: string) {
this.notify('error', 'Error: ' + message);
}
warning(message: string) {
this.notify('warning', 'Warning: ' + message);
}
info(message: string) {
this.notify('info', 'Info: ' + message);
}
private notify(type: string, message: string) {
this.notificationSubject.next({ type, message });
// Automatically clear notification after 3 seconds using RxJS timer
this.notifications$.pipe(
startWith(null),
switchMap(() => timer(5000))
).subscribe(() => this.notificationSubject.next(null));
}
clearNotification() {
this.notificationSubject.next(null);
}
}

@ -59,6 +59,7 @@
</div>
</div>
</div>
<div *ngIf="!isFirstLogin" class="full-width-page">
<div class="row">
<div class="col-12">

@ -41,12 +41,16 @@ passwordType2: string = 'password';
}
ngOnInit(): void {
const fromMenu = history.state?.['fromMenu'];
if(fromMenu){
this.checkIfFirstTimeChangePasswordOrNot();
}
checkIfFirstTimeChangePasswordOrNot(){
let currentUser: any = JSON.parse(this.storageService.getItem('user')!)
if(currentUser.user.isFirstLogin){
this.isFirstLogin = true;
}
else{
this.isFirstLogin = false;
}else{
const firstLoginFlag = this.storageService.getItem('firstLogin');
this.isFirstLogin = firstLoginFlag === 'true';
}
}

@ -7,3 +7,11 @@ export const pageSizeOptions = [
{ label: '10 items', value: 10 },
{ label: '20 items', value: 20 }
];
export interface PermissionNode {
name: string;
checked: boolean;
expanded: boolean;
children?: PermissionNode[];
buttons?: PermissionNode[];
}

@ -1,9 +1,11 @@
export enum ErrorMessages{
INTERNAL_SERVER_ERROR = "ERR_APP_B_0001",
CONNECTION_ERROR = "ERR_APP_B_0002",
BAD_REQUEST = "ERR_APP_B_0003",
FORBIDDEN_REQUEST = "ERR_APP_B_0004",
UNAUTHORIZED_REQUEST = "ERR_APP_B_0005",
INTERNAL_SERVER_ERROR = "INTERNAL_SERVER_ERROR",
CONNECTION_ERROR = "CONNECTION_ERROR",
BAD_REQUEST = "BAD_REQUEST",
FORBIDDEN_REQUEST = "FORBIDDEN_REQUEST",
UNAUTHORIZED_REQUEST = "UNAUTHORIZED_REQUEST",
ALREADY_LOGGED_IN = "ALREADY_LOGGED_IN",
ACCESS_DENIED = "ACCESS_DENIED",
}
export enum supportedLanguages{
@ -25,3 +27,44 @@ export enum selectedGatewayType{
TWILIO = 'Twilio',
JAZZ = 'Jazz'
}
export enum FormConstants{
POR_ORGACODE = "POR_ORGACODE",
USER_ID = "USER_ID",
PASSWORD = "PASSWORD",
CHANNEL_CODE = "CHANNEL_CODE"
}
export enum HiddenValues {
POR_ORGACODE = "0005",
CHANNEL_CODE = "01",
ORGANIZATION_USER = "O",
VAC_USER = "V",
SUPERADMIN_USER = "S",
DEFAULT_PASSWORD = "12345678",
REVOLVING_FUND_PRODUCT = "101",
INTERNAL_LENDING_PRODUCT = "102",
REVOLVING = "R",
CREDIT = "C",
CASH_GL = "11100001"
}
export enum SuccessMessages {
SAVED_SUCESSFULLY = "SUC_APP_F_0001",
LOGIN_SUCCESSFULLY = "LOGIN_SUCCESSFULLY",
TRANSACTION_SUCCESSFUL = "TRANSACTION_SUCCESSFUL",
SAVED_SUCCESSFULLY = "SAVED_SUCCESSFULLY",
RECORD_DELETED_SUCCESSFULY = "RECORD_DELETED_SUCCESSFULY",
ACCOUNT_CLOSED_SUCCESSFULLY = "ACCOUNT_CLOSED_SUCCESSFULLY",
SUCCESS_MESSAGE = "SUCCESS_MESSAGE"
}
export enum MESSAGEKEY {
SUCCESS = "SUCCESS",
ERROR = "ERROR",
WARN = "WARN",
INFO = "INFO",
NOTIFICATION = "NOTIFICATION",
FORM = "FORM"
}

@ -0,0 +1,5 @@
export enum URIKey {
USER_LOGIN_URI = "USER_LOGIN_URI",
USER_REFRESH_TOKEN = "USER_REFRESH_TOKEN"
}

@ -0,0 +1,25 @@
[
{
"Id": "ACONNECT_DOMAIN_URI",
"URI": "",
"Modules": [
{
"Id": "ACONNECT_URI",
"URI": "/aconnect",
"Pages": [
{
"Id": "ENTITY_USER_LOGIN_URI",
"URI": "/authentication/login",
"UUID": "USER_LOGIN_URI"
},
{
"Id": "ENTITY_USER_REFRESH_TOKEN",
"URI": "/refreshtoken",
"UUID": "USER_REFRESH_TOKEN"
}
]
}
]
}
]

@ -212,5 +212,13 @@
"totalItems": "السجلات",
"record": "سِجِلّ",
"previous": "سابق",
"next": "التالي"
"next": "التالي",
"LOGIN_SUCCESSFULLY":"تم تسجيل الدخول بنجاح",
"ALREADY_LOGGED_IN": "المستخدم مسجل دخوله بالفعل",
"ACCESS_DENIED" : "تم الرفض",
"INTERNAL_SERVER_ERROR": "خطأ في الخادم الداخلي",
"CONNECTION_ERROR": "خطأ في الاتصال",
"BAD_REQUEST": "اقتراح غير جيد",
"FORBIDDEN_REQUEST": "طلب ممنوع",
"UNAUTHORIZED_REQUEST": "طلب غير مصرح به"
}

@ -211,5 +211,13 @@
"totalItems": "Records",
"record": "Record",
"previous": "Previous",
"next": "Next"
"next": "Next",
"LOGIN_SUCCESSFULLY":"Login SucessFully",
"ALREADY_LOGGED_IN": "User Already Logged In",
"ACCESS_DENIED" : "Access Denied",
"INTERNAL_SERVER_ERROR": "Internal Server Error",
"CONNECTION_ERROR": "Connection Error",
"BAD_REQUEST": "Bad Request",
"FORBIDDEN_REQUEST": "Forbidden Request",
"UNAUTHORIZED_REQUEST": "Unauthorized Request"
}

@ -3,7 +3,8 @@ export const environment = {
versionNumber: '1.0.0.0',
buildNumber: '1.0',
buildDate: '27-11-2025',
apiPath: new Map([
["API_PATH", "http://localhost:8080/aconnect"]
enableEncryption: true,
moduleHost: new Map([
["ACONNECT_DOMAIN_URI", "http://localhost:8080"]
])
};

@ -3,7 +3,8 @@ export const environment = {
versionNumber: '1.0.0.0',
buildNumber: '1.0',
buildDate: '27-11-2025',
apiPath: new Map([
["API_PATH", "http://localhost:8080/aconnect"]
enableEncryption: false,
moduleHost: new Map([
["ACONNECT_DOMAIN_URI", "http://localhost:8080"]
])
};

Loading…
Cancel
Save