import { Injectable } from "@angular/core"; import { Request } from 'src/app/hmg-common/services/models/request'; // import { Request } from "../models/request"; import { TranslatorService } from "../translator/translator.service"; import { ConnectorService } from "../connector/connector.service"; import { Observable, throwError } from "rxjs"; //import { CheckPatientRegisterationRequest } from "./models/check-patient-registeration.request"; import { LoginRequest } from "./models/login.request"; // import { Response } from "../models/response"; import { Response } from 'src/app/hmg-common/services/models/response'; import { AuthenticatedUser } from "./models/authenticated-user"; import { CommonService } from "../common/common.service"; import { CheckUserAuthenticationRequest } from "./models/check-user-auth.request"; import { CheckActivationCodeRequest } from "./models/check-activation-code.request"; import { CheckUserAuthenticationResponse } from "./models/check-user-auth.response"; import { CheckActivationCodeResponse } from "./models/check-activation-code.response"; import { NativeStorage } from "@ionic-native/native-storage/ngx"; import { CheckRegisterationCodeRequest } from "./models/check-registeration-code.request"; import { RegisterInformationRequest } from "./models/register-information.request"; import { ForgotFileIDResponse } from "./models/forgot-File-ID.response"; import { EmailRequest } from "../models/email-request"; import { EmailInput } from "../../ui/email/models/email-input"; //import { UserLocalNotificationService } from "../user-local-notification/user-local-notification.service"; import { GetLoginInfoRequest } from "./models/get-login-info.request"; import { GetLoginInfoResponse } from "./models/get-login-info.response"; import { analyzeAndValidateNgModules } from "@angular/compiler"; import { Events, MenuController, Platform } from "@ionic/angular"; import { InternationalMobileComponent } from "../../ui/mobile-number/international-mobile/international-mobile.component"; import { SMSCheckRequest } from "./models/smscheck.request"; import { SMSCheckResponse } from "./models/smscheck.response"; import { ForgetPassword } from 'src/app/authentication/models/forget.password'; import { CheckAppVersionResponse } from './models/check-app-version.response'; import { PrivilageModel } from './models/privilage-model'; import { SendActivationByType } from 'src/app/authentication/models/sendActivationByType'; @Injectable({ providedIn: "root" }) export class AuthenticationService { /* login methods */ public static loginURL = 'Services/Authentication.svc/REST/CheckPatientAuthentication'; public static checkUserAuthURL = 'Services/Authentication.svc/REST/CheckPatientAuthentication'; public static login = 'Services/ERP.svc/REST/MemberLogin'; public static activationCodeURL = 'Services/Authentication.svc/REST/CheckActivationCode'; public static getLoginInfoURL = 'Services/Authentication.svc/REST/GetMobileLoginInfo'; public static smsCheck = 'Services/ERP.svc/REST/CheckActivationCode'; public static smsCheckForget = 'Services/ERP.svc/REST/CheckPublicActivationCode'; public static smsSendCode = 'Services/ERP.svc/REST/SendPublicActivationCode'; public static sendActivationCodeByType = 'Services/ERP.svc/REST/Mohemm_SendActivationCodebyOTPNotificationType'; public static getMobileLoginInfo = 'Services/ERP.svc/REST/Mohemm_GetMobileLoginInfo_NEW';//Mohemm_GetMobileLoginInfo public static insertMobileLoginInfo = 'Services/ERP.svc/REST/Mohemm_InsertMobileLoginInfo'; /* register methods */ public static checkPatientForRegisterationURL = 'Services/Authentication.svc/REST/CheckPatientForRegisteration'; public static sendSmsForRegisterURL = 'Services/Authentication.svc/REST/SendSMSForPatientRegisteration'; public static registerTempUserURL = 'Services/Authentication.svc/REST/RegisterTempPatientWithoutSMS'; public static sendSMSForgotFileNoURL = 'Services/Authentication.svc/REST/SendPatientIDSMSByMobileNumber'; public static forgotFileIDURL = 'Services/Authentication.svc/REST/CheckActivationCodeForSendFileNo'; public static user: AuthenticatedUser; public static servicePrivilage: PrivilageModel[]; /*user checking methods */ public static userChecking = 'Services/ERP.svc/REST/Get_BasicUserInformation'; public static changePasswordForget = 'Services/ERP.svc/REST/ChangePassword_Forget'; public static changePassword = 'Services/ERP.svc/REST/ChangePassword_FromActiveSession'; public static expiredPassword = 'Services/ERP.svc/REST/ChangePassword_Expired'; public static checkAppVersion = 'Services/Utilities.svc/REST/CheckMobileAppVersion'; /* check survey or ads */ public static getITGPageNotification = 'Services/COCWS.svc/REST/Mohemm_ITG_GetPageNotification'; public static getITGPageNotificationDetails = 'Services/COCWS.svc/REST/Mohemm_ITG_GetPageNotificationDetails'; public static saveSurveyAds = 'Services/COCWS.svc/REST/Mohemm_ITG_Survey_Response'; public static setViewAdvertisement = 'Services/COCWS.svc/REST/Mohemm_ITG_UpdateAdvertisementAsViewed'; public static LOGIN_EVENT = 'user-login-event'; public static FAMILY_LOGIN_EVENT = 'family-login-event'; public static AUTHENTICATED_USER_KEY = 'save-authenticated-user'; public static LOGIN_DATA = "logindata"; public static DEVICE_TOKEN = "device_token"; public static LAST_LOGIN = 'last-login'; public static IMEI_USER_DATA = "imei-user-data"; public static SERVEY_DATA = "survey-data"; public static ADS_DATA = "ads-data"; // private static user: AuthenticatedUser; constructor( public con: ConnectorService, public cs: CommonService, public ts: TranslatorService, public nativeStorage: NativeStorage, // public localNotifications: UserLocalNotificationService, private events: Events, private menu: MenuController, public platform: Platform ) { } public authenticateRequest(request: Request, automaticLogin = true): Request { this.setPublicFields(request); const user = this.getAuthenticatedUser(); if (user) { request.P_SESSION_ID = user.P_SESSION_ID; request.MobileNumber = user.EMPLOYEE_MOBILE_NUMBER; request.LogInTokenID = user.LogInTokenID; request.TokenID = user.TokenID; request.P_USER_NAME = user.EMPLOYEE_NUMBER; request.UserName = user.EMPLOYEE_NUMBER; request.P_EMAIL_ADDRESS = user.EMPLOYEE_EMAIL_ADDRESS; if (AuthenticationService.requireRelogin) { this.sessionTimeOutDialog(); } } else { this.cs.userNeedToReLogin(); } /* else { if (automaticLogin) { this.cs.openUserLogin(); } } */ return request; } public setPublicFields(request: Request): Request { const isAndroid = this.platform.is('android'); const isIOS = this.platform.is('ios'); let mobileType = ''; if (isAndroid) { mobileType = 'android'; } else if (isIOS) { mobileType = 'ios'; } else { mobileType = 'android'; } request.VersionID = 2.9; request.Channel = 31; request.LanguageID = TranslatorService.getCurrentLanguageCode(); request.MobileType = mobileType; return request; } public authenticateAndSetPersonalInformation( request: EmailRequest, examinationInfo?: any ): EmailRequest { // if not authenticated will be redirected to login this.authenticateRequest(request); const user = this.getAuthenticatedUser(); if (user) { // request.To = user.Email; // request.DateofBirth = user.DateofBirth; // request.PatientIditificationNum = user.PatientIdentificationNo; // request.PatientMobileNumber = user.MobileNo; // request.PatientName = user.PatientName; // request.PatientOutSA = user.PatientOutSA ? 1 : 0; // request.PatientTypeID = user.PatientTypeID; if (examinationInfo) { if (examinationInfo.SetupID) { request.SetupID = examinationInfo.SetupID; } if (examinationInfo.ProjectName) { request.ProjectName = examinationInfo.ProjectName; } if (examinationInfo.ClinicName) { request.ClinicName = examinationInfo.ClinicDescription; } if (examinationInfo.DoctorName) { request.DoctorName = examinationInfo.DoctorName; } if (examinationInfo.ProjectID) { request.ProjectID = examinationInfo.ProjectID; } if (examinationInfo.InvoiceNo) { request.InvoiceNo = examinationInfo.InvoiceNo; } if (examinationInfo.OrderDate) { request.OrderDate = this.cs.getDateISO( this.cs.evaluteDateAsObject(examinationInfo.OrderDate) ); } } } return request; } public getAuthenticatedRequest(login = true): Request { const request = new Request(); this.authenticateRequest(request, login); return request; } public getPublicRequest(): Request { const request = new Request(); this.setPublicFields(request); return request; } public checkApplicationVersion(onError: any): Observable { const request = new Request(); this.setPublicFields(request); return this.con.post(AuthenticationService.checkAppVersion, request, onError); } public login(request: LoginRequest, onError: any, errorLabel: string): Observable { this.setPublicFields(request); request.P_APP_VERSION = "CS"; return this.con.post(AuthenticationService.login, request, onError, errorLabel); } public isAuthenticated(): boolean { return AuthenticationService.user != null; } /** * this fucntion load from user information if he logged in before * and save user into memory and local storage * disable notifications for previous user if new user logged in with different user * * * info: * 1- user stored in local storage without token * @param result check activation code result */ public setAuthenticatedUser( result: SMSCheckResponse ): Observable { return Observable.create(observer => { this.loadAuthenticatedUser().subscribe( (loadedUser: AuthenticatedUser) => { AuthenticationService.requireRelogin = false; this.startIdleMonitoring(); const user = this.updateAuthenticatedUser(result, loadedUser); /* we store in hd without token but with token in memory*/ this.saveUserInStorage(user).subscribe((success: boolean) => { AuthenticationService.user = user; this.publishUserChangeEvent(); observer.next(true); observer.complete(); }); } ); }); } public resetAuthenticatedUser(user: AuthenticatedUser) { AuthenticationService.user = user; AuthenticationService.requireRelogin = false; this.startIdleMonitoring(); this.publishUserChangeEvent(); } // public setAuthenticatedMemberFamilyUser(result: CheckActivationCodeResponse) { // const authUser = new AuthenticatedUser(); // AuthenticationService.requireRelogin = false; // this.startIdleMonitoring(); // const user = this.updateAuthenticatedUser(result, authUser); // // user["hello"]= "ok"; // /* we store in hd without token but with token in memory*/ // AuthenticationService.user = user; // this.publishFamilyMemeberUserChangeEvent(); // } public updateLoggedInUser(newUser: AuthenticatedUser): Observable { return Observable.create(observer => { /* we store in hd without token but with token in memory*/ this.saveUserInStorage(newUser).subscribe((success: boolean) => { AuthenticationService.requireRelogin = false; AuthenticationService.user = newUser; this.publishUserChangeEvent(); observer.next(success); observer.complete(); }); }); } public setDeviceToken(token: string) { const user = this.getAuthenticatedUser(); if (user) { // user.deviceToken = token; this.updateLoggedInUser(user).subscribe((success: boolean) => { // console.log('token stored:' + token); }); } } public registerTempUser( request: RegisterInformationRequest, onError: any, errorLabel: string ): Observable { this.setPublicFields(request); request.TokenID = ""; return this.con.post( AuthenticationService.registerTempUserURL, request, onError, errorLabel ); } public getLoginInfo( request: any, onError: any, errorLabel: string ): Observable { //this.setPublicFields(request); return this.con.post( AuthenticationService.getMobileLoginInfo, request, onError, errorLabel ); } /** *update new authenticated user from previously stored and loaded user */ private updateAuthenticatedUser( result: SMSCheckResponse, loadedUser: AuthenticatedUser ): AuthenticatedUser { const user = result.MemberInformationList[0]; user.P_SESSION_ID = result.P_SESSION_ID; user.MobileNumber = result.EMPLOYEE_MOBILE_NUMBER; user.TokenID = result.TokenID; user.CompanyImageDescription = result.CompanyImageDescription; user.CompanyImageURL = result.CompanyImageURL; user.CompanyBadge = result.CompanyBadge; user.CompanyMainCompany = result.CompanyMainCompany; user.LogInTokenID = this.cs.sharedService.getSharedData( AuthenticationService.LOGIN_DATA, false ).LogInTokenID; return user; } public isRealEmail(email: string): boolean { return EmailInput.isValidEmail(email); } public isAuthenticatedUserHasRealEmail(): boolean { const user = this.getAuthenticatedUser(); return user ? this.isRealEmail(user.EMPLOYEE_EMAIL_ADDRESS) : false; } /** * we store in localstorage without token but we keep it in the static member */ private saveUserInStorage(user: AuthenticatedUser): Observable { return Observable.create(observer => { if (user) { // const TokenID = user.TokenID; // user.TokenID = null; this.nativeStorage .setItem(AuthenticationService.AUTHENTICATED_USER_KEY, user) .then( () => { //user.TokenID = TokenID; observer.next(true); observer.complete(); }, error => { // user.TokenID = TokenID; observer.next(false); observer.complete(); } ); } else { observer.next(false); observer.complete(); } }); } /** * signout *clear user session and storage information */ public clearUser(): Observable { this.clearUserSession(); return Observable.create(observer => { this.publishUserChangeEvent(); this.nativeStorage .remove(AuthenticationService.AUTHENTICATED_USER_KEY) .then( () => { observer.next(true); observer.complete(); }, () => { observer.next(false); observer.complete(); } ); }); } private publishUserChangeEvent() { this.events.publish( AuthenticationService.LOGIN_EVENT, this.getAuthenticatedUser(), Date.now() ); } private publishFamilyMemeberUserChangeEvent() { this.events.publish( AuthenticationService.FAMILY_LOGIN_EVENT, this.getAuthenticatedUser(), Date.now() ); } public clearUserSession() { AuthenticationService.user = null; } public loadAuthenticatedUser(): Observable { return Observable.create(observer => { this.nativeStorage .getItem(AuthenticationService.AUTHENTICATED_USER_KEY) .then( user => { observer.next(user); observer.complete(); }, error => { // this.getAuthenticatedUser() //commented for now will uncomment when we are going to deploy on the device; //observer.next(null); observer.next(this.getAuthenticatedUser()); observer.complete(); } ); }); } // TODO you should read from local storage and update static member public getAuthenticatedUser(): AuthenticatedUser { /* if (AuthenticationService.requireRelogin) { this.sessionTimeOutDialog(); return new AuthenticatedUser(); } else { return AuthenticationService.user; } */ if (AuthenticationService.user) { return AuthenticationService.user; } else { this.cs.openLogin(); } } public checkUserAuthentication(request: CheckUserAuthenticationRequest, onError: any, errorLabel: string) : Observable { this.setPublicFields(request); request.P_APP_VERSION = "CS"; return this.con.post(AuthenticationService.userChecking, request, onError, errorLabel); } public checkActivationCode(request: CheckActivationCodeRequest, onError: any, errorLabel: string) : Observable { this.setPublicFields(request); return this.con.post(AuthenticationService.activationCodeURL, request, onError, errorLabel); } public checkSMS(request: SMSCheckRequest, onError: any, errorLabel: string, fromSMS = false ) : Observable { this.setPublicFields(request); return this.con.post(AuthenticationService.smsCheck, request, onError, errorLabel, fromSMS); } public checkForgetSMS(request: SMSCheckRequest, onError: any, errorLabel: string) : Observable { this.setPublicFields(request); return this.con.post(AuthenticationService.smsCheckForget, request, onError, errorLabel); } public sendPublicSMS(request: SMSCheckRequest, onError: any, errorLabel: string) : Observable { this.setPublicFields(request); return this.con.post(AuthenticationService.smsSendCode, request, onError, errorLabel); } /* client side: id no , mobile no , zip code */ /* client side: id no , mobile no , zip code */ // public sendSmsForPatientRegisteration(request: CheckPatientRegisterationRequest, onError: any, errorLabel: string) // : Observable { // this.setPublicFields(request); // request.TokenID = ''; // request.isRegister = false; // return this.con.post(AuthenticationService.sendSmsForRegisterURL, request, onError, errorLabel); // } public checkRegisterationActivationCode(request: CheckRegisterationCodeRequest, onError: any, errorLabel: string) : Observable { this.setPublicFields(request); return this.con.post(AuthenticationService.activationCodeURL, request, onError, errorLabel); } public sendForgetPassword(request: ForgetPassword, onError: any, errorLabel: string) : Observable { this.setPublicFields(request); return this.con.post(AuthenticationService.smsSendCode, request, onError, errorLabel); } public submitForgetPassword(request: ForgetPassword, onError: any, errorLabel: string) : Observable { this.setPublicFields(request); return this.con.post(AuthenticationService.changePasswordForget, request, onError, errorLabel); } public submitChangePassword(request: ForgetPassword, onError: any, errorLabel: string) : Observable { this.setPublicFields(request); this.authenticateRequest(request); return this.con.post(AuthenticationService.changePassword, request, onError, errorLabel); } public submitExpiredPassword(request: ForgetPassword, onError: any, errorLabel: string) : Observable { this.setPublicFields(request); return this.con.post(AuthenticationService.expiredPassword, request, onError, errorLabel); } public sendSMSForForgotFileNumber(request: CheckUserAuthenticationRequest, onError: any, errorLabel: string) : Observable { this.setPublicFields(request); request.TokenID = ''; //request.SearchType = 2; //request.isRegister = false; return this.con.post(AuthenticationService.sendSMSForgotFileNoURL, request, onError, errorLabel); } public forgotFileIdActivation(request: CheckActivationCodeRequest, onError: any, errorLabel: string) : Observable { this.setPublicFields(request); request.TokenID = ''; request.SearchType = 2; request.isRegister = false; return this.con.post(AuthenticationService.forgotFileIDURL, request, onError, errorLabel); } // tslint:disable-next-line: max-line-length public insertMobileLoginInfo(request: GetLoginInfoRequest, onError: any, errorLabel: string, isPostNoLoad = false): Observable { this.authenticateRequest(request); if (isPostNoLoad) { return this.con.postNoLoad(AuthenticationService.insertMobileLoginInfo, request, onError, errorLabel); } else { return this.con.post(AuthenticationService.insertMobileLoginInfo, request, onError, errorLabel); } } public isSAUDIIDValid(id: string): boolean { if (!id) { return false; } try { id = id.toString(); id = id.trim(); const returnValue = Number(id); let sum = 0; if (returnValue > 0) { const type = Number(id.charAt(0)); if (id.length !== 10) { return false; } if (type !== 2 && type !== 1) { return false; } for (let i = 0; i < 10; i++) { if (i % 2 === 0) { const a = id.charAt(i); const x = Number(a) * 2; let b = x.toString(); if (b.length === 1) { b = "0" + b; } sum += Number(b.charAt(0)) + Number(b.charAt(1)); } else { sum += Number(id.charAt(i)); } } return sum % 10 === 0; } } catch (err) { } return false; } public checkUserHasEmailDialog(): Observable { return Observable.create(observer => { if (this.isAuthenticatedUserHasRealEmail()) { const message = this.ts .trPK("general", "send-email") .replace("[0]", this.getAuthenticatedUser().EmailAddress); this.cs.presentConfirmDialog(message, () => { observer.next(); observer.complete(); }); } else { this.cs.presentConfirmDialog( this.ts.trPK("login", "enter-email"), () => { //this.cs.openPatientProfile(); observer.complete(); } ); } }); } /* user session timeout after idle for 20 Minute */ private static requireRelogin = false; public static monitorInterval_M = 20 * 60 * 1000; // public static monitorInterval_M = 15 * 1000; private static timerID; private stopIdleTimer() { if (AuthenticationService.timerID) { clearTimeout(AuthenticationService.timerID); } } private sessionTimeOutDialog() { this.cs.stopLoading(); this.cs.presentAcceptDialog( this.ts.trPK("general", "idle-relogin"), () => { this.cs.sharedService.clearAll(); // this.cs.openLogin(); this.getLastLoginInfo(); } ); } public getLastLoginInfo() { let deviceToken = localStorage.getItem('deviceToken'); const requestGetLoginInfo = { DeviceType: this.cs.getDeviceType(), DeviceToken: deviceToken }; this.getLoginInfo(requestGetLoginInfo, () => { }, this.ts.trPK('general', 'ok')).subscribe(res => { if (this.cs.validResponse(res)) { if (res.Mohemm_GetMobileLoginInfoList.length > 0) { this.cs.sharedService.setSharedData(res.Mohemm_GetMobileLoginInfoList[0], AuthenticationService.IMEI_USER_DATA); const user = true; this.events.publish('user', user); this.cs.openLogin(); } else { const user = false; this.events.publish('user', user); this.cs.openLogin(); } } else { } }); } /* reset and start idling interval */ private detectIdle() { this.stopIdleTimer(); AuthenticationService.timerID = setTimeout(() => { if (AuthenticationService.user) { AuthenticationService.requireRelogin = true; this.clearUserSession(); this.publishUserChangeEvent(); this.sessionTimeOutDialog(); // this.cs.openHome(); } }, AuthenticationService.monitorInterval_M); } private registerDocumentEvents(events: string[], handler: any) { for (const event of events) { document.addEventListener(event, handler); } } private static eventsRegistered = false; public startIdleMonitoring() { if (!AuthenticationService.eventsRegistered) { AuthenticationService.eventsRegistered = true; // every time we have and event this.registerDocumentEvents( ["mousedown", "touchstart", "click", "keyup"], () => { // if user still logged in and session not expired if ( AuthenticationService.user && !AuthenticationService.requireRelogin ) { // reset and start idling timer this.detectIdle(); } } ); } } checkAds(request, onError, errorLabel) { request = this.authenticateRequest(request); request.EmployeeNumber = request.UserName; return this.con.post(AuthenticationService.getITGPageNotification, request, onError, errorLabel); } adsDetails(request, onError, errorLabel) { request = this.authenticateRequest(request); request.EmployeeNumber = request.UserName; return this.con.post(AuthenticationService.getITGPageNotificationDetails, request, onError, errorLabel); } saveAdsStatus(request, onError, errorLabel) { request = this.authenticateRequest(request); request.EmployeeNumber = request.UserName; return this.con.post(AuthenticationService.saveSurveyAds, request, onError, errorLabel); } setViewAds(request, onError, errorLabel) { request = this.authenticateRequest(request); request.EmployeeNumber = request.UserName; return this.con.post(AuthenticationService.setViewAdvertisement, request, onError, errorLabel); } //**************************// public sendActivationCodeByType( request: SendActivationByType, onError: any, errorLabel: string ): Observable { this.setPublicFields(request); //below afifi code //return this.con.post(AuthenticationService.checkUserAuthURL, request, onError, errorLabel); //afifi code, edit it to display the error msg into pop up ofverfication code return this.con.post( AuthenticationService.sendActivationCodeByType, request, onError, errorLabel ); } }