X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=src%2Fservices%2FSharedService.ts;h=8abe1d295e80c6b750ca430aece68d7f2639e053;hb=1b17c432991a95035a1732426f0c11db57e511c9;hp=41f3d76ada7aac5f32a1eea2f4bd2cafd0accad8;hpb=403234ed6120ba4bc01578b3ec237fa5fd4c0f6d;p=osm%2FNG-UI.git diff --git a/src/services/SharedService.ts b/src/services/SharedService.ts index 41f3d76..8abe1d2 100644 --- a/src/services/SharedService.ts +++ b/src/services/SharedService.ts @@ -18,20 +18,35 @@ /** * @file Provider for Shared Service */ +import { isNullOrUndefined } from 'util'; import { HttpErrorResponse, HttpHeaders } from '@angular/common/http'; import { EventEmitter, Injectable, Output } from '@angular/core'; import { FormArray, FormGroup } from '@angular/forms'; import { Router } from '@angular/router'; -import { CONSTANTNUMBER, ERRORDATA, GETAPIURLHEADER, PACKAGEINFO, PAGERSMARTTABLE, SMARTTABLECLASS, TARSETTINGS } from 'CommonModel'; +import { TranslateService } from '@ngx-translate/core'; +import { + CONSTANTNUMBER, + DOMAINS, + ERRORDATA, + FILESETTINGS, + GETAPIURLHEADER, + PACKAGEINFO, + PAGERSMARTTABLE, + SMARTTABLECLASS, + TARSETTINGS, + TYPESECTION +} from 'CommonModel'; import { environment } from 'environment'; import * as HttpStatus from 'http-status-codes'; import * as untar from 'js-untar'; +import { ActiveToast, ToastrService } from 'ngx-toastr'; import * as pako from 'pako'; import { RestService } from 'RestService'; -import { isNullOrUndefined } from 'util'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; /** This is added globally by the tar.js library */ -// tslint:disable-next-line: no-any +// eslint-disable-next-line @typescript-eslint/no-explicit-any declare const Tar: any; /** @@ -47,27 +62,32 @@ export class SharedService { @Output() public dataEvent: EventEmitter<{}> = new EventEmitter<{}>(); /** Variables to hold regexp pattern for URL */ - // tslint:disable-next-line: max-line-length public REGX_URL_PATTERN: RegExp = new RegExp(/^(http?|ftp|https):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.[a-zA-Z0-9]{2,15})(:((6553[0-5])|(655[0-2][0-9])|(65[0-4][0-9]{2})|(6[0-4][0-9]{3})|([1-5][0-9]{4})|([0-5]{0,5})|([0-9]{1,4})))*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/); /** Variables to hold regexp pattern for IP Address */ public REGX_IP_PATTERN: RegExp = new RegExp(/^(?:(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(?!$)|$)){4}$/); /** Variables to hold regexp pattern for Port Number */ - // tslint:disable-next-line: max-line-length public REGX_PORT_PATTERN: RegExp = new RegExp(/^((6553[0-5])|(655[0-2][0-9])|(65[0-4][0-9]{2})|(6[0-4][0-9]{3})|([1-5][0-9]{4})|([0-5]{0,5})|([0-9]{1,4}))$/); /** Variables to hold regexp pattern for DPID */ public REGX_DPID_PATTERN: RegExp = new RegExp(/^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){7}$/); /** Variable to hold regexp pattern for password */ - // tslint:disable-next-line: max-line-length public REGX_PASSWORD_PATTERN: RegExp = new RegExp(/^.*(?=.{8,})((?=.*[!@#$%^&*()\-_=+{};:,<.>]){1})(?=.*\d)((?=.*[a-z]){1})((?=.*[A-Z]){1}).*$/); + /** Variables to hold regexp pattern for Latitude */ + public REGX_LAT_PATTERN: RegExp = new RegExp(/^(\+|-)?(?:90(?:(?:\.0{1,6})?)|(?:[0-9]|[1-8][0-9])(?:(?:\.[0-9]{1,15})?))$/); + + /** Variables to hold regexp pattern for Longitude */ + public REGX_LONG_PATTERN: RegExp = new RegExp(/^(\+|-)?(?:180(?:(?:\.0{1,6})?)|(?:[0-9]|[1-9][0-9]|1[0-7][0-9])(?:(?:\.[0-9]{1,15})?))$/); + /** Variables to hold maxlength for the description @public */ + // eslint-disable-next-line @typescript-eslint/no-magic-numbers public MAX_LENGTH_DESCRIPTION: number = 500; /** Variables to hold maxlength for the name @public */ + // eslint-disable-next-line @typescript-eslint/no-magic-numbers public MAX_LENGTH_NAME: number = 50; /** FormGroup instance added to the form @ html @public */ @@ -79,15 +99,39 @@ export class SharedService { /** Holds OSM Version value @public */ public osmVersion: string; + /** Holds Last Login Toaster Message @public */ + public lastLoginMessage: string; + + /** Holds Failed Attempts Toaster Message @public */ + public failedAttemptsMessage: string; + + /** Holds No Of Days Toaster Message @public */ + public daysMessage: string; + /** express number for time manupulation -2 */ + // eslint-disable-next-line @typescript-eslint/no-magic-numbers private epochTimeMinus2: number = -2; /** express number for time manupulation 1000 */ + // eslint-disable-next-line @typescript-eslint/no-magic-numbers private epochTime1000: number = 1000; + /** express number for time manupulation 60 */ + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + private epochTime60: number = 60; + + /** express number for time manupulation 24 */ + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + private epochTime24: number = 24; + /** Random string generator length */ + // eslint-disable-next-line @typescript-eslint/no-magic-numbers private randomStringLength: number = 4; + /** Max length of Uint8Array */ + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + private unit8Array: number = 255; + /** Instance of the rest service @private */ private restService: RestService; @@ -95,40 +139,110 @@ export class SharedService { private router: Router; /** Random color string generator length @private */ + // eslint-disable-next-line @typescript-eslint/no-magic-numbers private colorStringLength: number = 256; /** Check for the root directory @private */ + // eslint-disable-next-line @typescript-eslint/no-magic-numbers private directoryCount: number = 2; - constructor(restService: RestService, router: Router) { + /** express number for time manupulation 1000 */ + private toasterSettings: {} = { + enableHtml: true, + closeButton: true, + timeOut: 2000 + }; + + /** Contains tranlsate instance @private */ + private translateService: TranslateService; + + /** Contains toaster instance @private */ + private toaster: ToastrService; + + constructor(restService: RestService, router: Router, translateService: TranslateService, toaster: ToastrService) { this.restService = restService; this.router = router; + this.translateService = translateService; + this.toaster = toaster; } /** convert epoch time function @public */ public convertEpochTime(unixtimestamp: number): string { - const monthsArr: string[] = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; - const date: Date = new Date(unixtimestamp * this.epochTime1000); - const year: number = date.getFullYear(); - const month: string = monthsArr[date.getMonth()]; - const day: number = date.getDate(); - const hours: number = date.getHours(); - const minutes: string = '0' + date.getMinutes(); - const seconds: string = '0' + date.getSeconds(); - return month + '-' + day + '-' + year + ' ' + hours + ':' + minutes.substr(this.epochTimeMinus2) + ':' - + seconds.substr(this.epochTimeMinus2); + if (!isNullOrUndefined(unixtimestamp)) { + const monthsArr: string[] = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; + const date: Date = new Date(unixtimestamp * this.epochTime1000); + const year: number = date.getFullYear(); + const month: string = monthsArr[date.getMonth()]; + const day: number = date.getDate(); + const hours: number = date.getHours(); + const minutes: string = '0' + date.getMinutes(); + const seconds: string = '0' + date.getSeconds(); + // eslint-disable-next-line deprecation/deprecation + return month + '-' + day + '-' + year + ' ' + hours + ':' + minutes.substr(this.epochTimeMinus2) + ':' + // eslint-disable-next-line deprecation/deprecation + + seconds.substr(this.epochTimeMinus2); + } + return this.translateService.instant('NODATE'); + } + + /** convert epoch time function to No of days @public */ + public converEpochToDays(date: string): number { + if (!isNullOrUndefined(date)) { + const today: Date = new Date(); + const accountDate: Date = new Date(date); + return Math.floor((accountDate.getTime() - + today.getTime()) / this.epochTime1000 / this.epochTime60 / this.epochTime60 / this.epochTime24); + } + return this.translateService.instant('N/A'); + } + + /** show toaster for password & account expiry @public */ + public showToaster(lastLogin: string, failedAttempts: string, passwordNoOfDays: string, + accountNoOfDays: string, passwordExpireMessage: string, accountExpireMessage: string, + passwordMessage: string, accountMessage: string): ActiveToast { + this.lastLoginMessage = this.translateService.instant('PAGE.LOGIN.LASTACCESS'); + this.failedAttemptsMessage = this.translateService.instant('PAGE.LOGIN.FAILED'); + return this.toaster.info(this.lastLoginMessage + ':' + ' ' + lastLogin + + '
' + this.failedAttemptsMessage + ':' + ' ' + failedAttempts + + '
' + passwordExpireMessage + ' ' + passwordNoOfDays + ' ' + passwordMessage + + '
' + accountExpireMessage + ' ' + accountNoOfDays + ' ' + accountMessage, + this.translateService.instant('PAGE.LOGIN.LOGINHISTORY'), this.toasterSettings); + } + + /** show toaster for password expiry @public */ + public passwordToaster(lastLogin: string, failedAttempts: string, passwordNoOfDays: string, + passwordExpireMessage: string, passwordMessage: string): ActiveToast { + this.lastLoginMessage = this.translateService.instant('PAGE.LOGIN.LASTACCESS'); + this.failedAttemptsMessage = this.translateService.instant('PAGE.LOGIN.FAILED'); + return this.toaster.info(this.lastLoginMessage + ':' + ' ' + lastLogin + + '
' + this.failedAttemptsMessage + ':' + ' ' + failedAttempts + + '
' + passwordExpireMessage + ' ' + passwordNoOfDays + ' ' + passwordMessage, + this.translateService.instant('PAGE.LOGIN.LOGINHISTORY'), this.toasterSettings); + } + + /** show toaster for account expiry @public */ + public accountToaster(lastLogin: string, failedAttempts: string, + accountNoOfDays: string, accountExpireMessage: string, accountMessage: string): ActiveToast { + this.lastLoginMessage = this.translateService.instant('PAGE.LOGIN.LASTACCESS'); + this.failedAttemptsMessage = this.translateService.instant('PAGE.LOGIN.FAILED'); + return this.toaster.info(this.lastLoginMessage + ':' + ' ' + lastLogin + + '
' + this.failedAttemptsMessage + ':' + ' ' + failedAttempts + + '
' + accountExpireMessage + ' ' + accountNoOfDays + ' ' + accountMessage, + this.translateService.instant('PAGE.LOGIN.LOGINHISTORY'), this.toasterSettings); } /** Download Files function @public */ - public downloadFiles(shortName: string, binaryData: Blob[], filetype: string): void { + public downloadFiles(name: string, binaryData: Blob[], filetype: string): void { const downloadLink: HTMLAnchorElement = document.createElement('a'); downloadLink.href = window.URL.createObjectURL(new Blob(binaryData, { type: filetype })); - if (shortName !== undefined) { - if (window.navigator.msSaveOrOpenBlob) { - window.navigator.msSaveBlob(new Blob(binaryData, { type: filetype }), 'OSM_Export_' + shortName + '.tar.gz'); + if (name !== undefined) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const newVariable: any = window.navigator; + if (newVariable.msSaveOrOpenBlob) { + newVariable.msSaveBlob(new Blob(binaryData, { type: filetype }), 'OSM_Export_' + name + '.tar.gz'); } else { - downloadLink.setAttribute('download', 'OSM_Export_' + shortName + '.tar.gz'); + downloadLink.setAttribute('download', 'OSM_Export_' + name + '.tar.gz'); document.body.appendChild(downloadLink); downloadLink.click(); } @@ -144,12 +258,12 @@ export class SharedService { public randomString(): string { const chars: string = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; let result: string = ''; - // tslint:disable-next-line:no-increment-decrement for (let randomStringRef: number = this.randomStringLength; randomStringRef > 0; --randomStringRef) { result += chars[Math.floor(Math.random() * chars.length)]; } return result; } + /** Function to read uploaded file String @public */ public async getFileString(files: FileList, fileType: string): Promise { const reader: FileReader = new FileReader(); @@ -170,6 +284,7 @@ export class SharedService { }; }); } + /** Method to handle tar and tar.gz file for shared YAML file content @public */ public async targzFile(packageInfo: PACKAGEINFO): Promise { return new Promise((resolve: Function, reject: Function): void => { @@ -177,38 +292,41 @@ export class SharedService { let apiUrl: string = ''; apiUrl = packageInfo.packageType === 'nsd' ? environment.NSDESCRIPTORS_URL + '/' + packageInfo.id + '/nsd_content' : environment.VNFPACKAGES_URL + '/' + packageInfo.id + '/package_content'; - this.restService.getResource(apiUrl, httpOptions).subscribe((response: ArrayBuffer) => { + this.restService.getResource(apiUrl, httpOptions).subscribe((response: ArrayBuffer): void => { try { - // tslint:disable-next-line: no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any const tar: any = new Tar(); const originalInput: Uint8Array = pako.inflate(response, { to: 'Uint8Array' }); - untar(originalInput.buffer).then((extractedFiles: TARSETTINGS[]) => { + untar(originalInput.buffer).then((extractedFiles: TARSETTINGS[]): void => { const getFoldersFiles: {}[] = extractedFiles; const folderNameStr: string = extractedFiles[0].name; - getFoldersFiles.forEach((value: TARSETTINGS) => { + getFoldersFiles.forEach((value: TARSETTINGS): void => { + const fileValueObj: FILESETTINGS = this.createFileValueObject(value); const getRootFolder: string[] = value.name.split('/'); if (value.name.startsWith(folderNameStr) && (value.name.endsWith('.yaml') || value.name.endsWith('.yml')) && getRootFolder.length === this.directoryCount) { - tar.append(value.name, packageInfo.descriptor, { type: value.type }); + tar.append(value.name, packageInfo.descriptor, fileValueObj); } else { if (value.type !== 'L') { - tar.append(value.name, new Uint8Array(value.buffer), { type: value.type }); + tar.append(value.name, new Uint8Array(value.buffer), fileValueObj); } } }); const out: Uint8Array = tar.out; const originalOutput: Uint8Array = pako.gzip(out); resolve(originalOutput.buffer); - }, (err: string) => { + }, (err: string): void => { reject(''); }); } catch (e) { reject(''); } - }, (error: HttpErrorResponse) => { + }, (error: HttpErrorResponse): void => { if (error.status === HttpStatus.NOT_FOUND || error.status === HttpStatus.UNAUTHORIZED) { - this.router.navigateByUrl('404', { skipLocationChange: true }).catch(); + this.router.navigateByUrl('404', { skipLocationChange: true }).catch((): void => { + // Catch Navigation Error + }); } else { this.restService.handleError(error, 'get'); reject(''); @@ -216,6 +334,17 @@ export class SharedService { }); }); } + + /** Method to return the file information @public */ + public createFileValueObject(value: TARSETTINGS): FILESETTINGS { + return { + type: value.type, + linkname: value.linkname, + owner: value.uname, + group: value.gname + }; + } + /** Method to check given string is JSON or not @public */ public checkJson(jsonString: string): boolean { jsonString = jsonString.replace(/'/g, '"'); @@ -226,12 +355,14 @@ export class SharedService { } return true; } + /** Clean the form before submit @public */ public cleanForm(formGroup: FormGroup, formName?: String): void { Object.keys(formGroup.controls).forEach((key: string) => { if ((!isNullOrUndefined((formGroup.get(key) as FormArray | FormGroup).controls)) && key !== 'config') { - // tslint:disable-next-line: no-shadowed-variable + // eslint-disable-next-line @typescript-eslint/no-shadow for (const { item, index } of (formGroup.get(key).value).map((item: {}, index: number) => ({ item, index }))) { + // eslint-disable-next-line security/detect-object-injection const newFormGroup: FormGroup = (formGroup.get(key) as FormArray).controls[index] as FormGroup; this.cleanForm(newFormGroup); } @@ -247,6 +378,7 @@ export class SharedService { } }); } + /** Method to return the config of pager value for ngSmarttable @public */ public paginationPagerConfig(): PAGERSMARTTABLE { return { @@ -254,12 +386,14 @@ export class SharedService { perPage: environment.paginationNumber }; } + /** Method to return the class for the table for ngSmarttable @public */ public tableClassConfig(): SMARTTABLECLASS { return { class: 'table list-data' }; } + /** Method to return all languages name and its code @public */ public languageCodeList(): {}[] { return [ @@ -269,20 +403,22 @@ export class SharedService { { code: 'de', language: 'German' } ]; } + /** Fetch OSM Version @public */ public fetchOSMVersion(): void { - this.restService.getResource(environment.OSM_VERSION_URL).subscribe((res: { version: string }) => { + this.restService.getResource(environment.OSM_VERSION_URL).subscribe((res: { version: string }): void => { const version: string[] = res.version.split('+'); if (!isNullOrUndefined(version[0])) { this.osmVersion = version[0]; } else { this.osmVersion = null; } - }, (error: ERRORDATA) => { + }, (error: ERRORDATA): void => { this.osmVersion = null; this.restService.handleError(error, 'get'); }); } + /** Random RGB color code generator @public */ public generateColor(): string { const x: number = Math.floor(Math.random() * this.colorStringLength); @@ -296,6 +432,38 @@ export class SharedService { return tag; } + /** Fetch file extension @public */ + public fetchFileExtension(fileInfo: FileList): string { + return fileInfo[0].name.substring(fileInfo[0].name.lastIndexOf('.') + 1); + } + + /** Get domain name @private */ + public getDomainName(): Observable { + return this.restService.getResource(environment.DOMAIN_URL).pipe(map((domains: DOMAINS): TYPESECTION[] => { + const domainList: TYPESECTION[] = []; + try { + let domainNames: string[] = []; + if (!isNullOrUndefined(domains.project_domain_name)) { + domainNames = domainNames.concat(domains.project_domain_name.split(',')); + } + if (!isNullOrUndefined(domains.user_domain_name)) { + domainNames = domainNames.concat(domains.user_domain_name.split(',')); + } + domainNames = Array.from(new Set(domainNames)); + if (domainNames.length > 0) { + domainNames.forEach((domainName: string): void => { + if (!domainName.endsWith(':ro')) { + domainList.push({ title: domainName, value: domainName }); + } + }); + } + return domainList; + } catch (e) { + return domainList; + } + })); + } + /** Method to validate file extension and size @private */ private vaildataFileInfo(fileInfo: File, fileType: string): boolean { const extension: string = fileInfo.name.substring(fileInfo.name.lastIndexOf('.') + 1); @@ -308,6 +476,7 @@ export class SharedService { } return false; } + /** Method to read file content based on type @private */ private readFileContent(reader: FileReader, fileInfo: File, fileType: string): void { if (fileType === 'gz') { @@ -316,6 +485,7 @@ export class SharedService { reader.readAsText(fileInfo); } } + /** Method to handle http options @public */ private getHttpOptions(): GETAPIURLHEADER { return {