From 2c93b20b798f600e80a13d28ee8e1058edb64cb3 Mon Sep 17 00:00:00 2001 From: Sebastien Bousquet Date: Wed, 27 Sep 2023 16:10:59 +0200 Subject: [PATCH] feat: use startupService from toolkit deps: use toolkit beta-iam.11 --- package-lock.json | 14 +- package.json | 2 +- src/app/app.module.ts | 23 +++- src/app/components/home/home.component.ts | 29 ++-- src/app/components/user/user.component.ts | 2 +- .../services/startup/startup.service.spec.ts | 3 +- src/app/services/startup/startup.service.ts | 124 ++++-------------- src/assets/i18n/en.json | 7 +- src/assets/i18n/fr.json | 7 +- src/assets/i18n/template.json | 6 +- 10 files changed, 77 insertions(+), 140 deletions(-) diff --git a/package-lock.json b/package-lock.json index 600b897..f623bbe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "@typescript-eslint/eslint-plugin": "^5.36.2", "@typescript-eslint/parser": "^5.36.2", "ajv-keywords": "5.1.0", - "arlas-wui-toolkit": "24.2.0-beta-iam.8", + "arlas-wui-toolkit": "24.2.0-beta-iam.11", "eslint": "^8.2.0", "js-yaml": "4.1.0", "ngx-toastr": "~14.3.0", @@ -5196,9 +5196,9 @@ } }, "node_modules/arlas-wui-toolkit": { - "version": "24.2.0-beta-iam.8", - "resolved": "https://registry.npmjs.org/arlas-wui-toolkit/-/arlas-wui-toolkit-24.2.0-beta-iam.8.tgz", - "integrity": "sha512-VIfQcYBFl8R7gOnNUXpaBwVyar8MGVsVrLEbAt2clqJ3cI37djUEW7L8Jgfi6Rws02vgoTaObXp4vN6cki9q5Q==", + "version": "24.2.0-beta-iam.11", + "resolved": "https://registry.npmjs.org/arlas-wui-toolkit/-/arlas-wui-toolkit-24.2.0-beta-iam.11.tgz", + "integrity": "sha512-0PutGuBq6zhIyjLUJoWeh+vkuWKo+W3Cme+HOQZka45jsZHn4mBVwFhTGCms8rYBBQGih5Y+Kh4+Hf9xV/Os5A==", "dependencies": { "@danielmoncada/angular-datetime-picker": "14.2.0", "@danielmoncada/angular-datetime-picker-moment-adapter": "~2.2.0", @@ -21127,9 +21127,9 @@ } }, "arlas-wui-toolkit": { - "version": "24.2.0-beta-iam.8", - "resolved": "https://registry.npmjs.org/arlas-wui-toolkit/-/arlas-wui-toolkit-24.2.0-beta-iam.8.tgz", - "integrity": "sha512-VIfQcYBFl8R7gOnNUXpaBwVyar8MGVsVrLEbAt2clqJ3cI37djUEW7L8Jgfi6Rws02vgoTaObXp4vN6cki9q5Q==", + "version": "24.2.0-beta-iam.11", + "resolved": "https://registry.npmjs.org/arlas-wui-toolkit/-/arlas-wui-toolkit-24.2.0-beta-iam.11.tgz", + "integrity": "sha512-0PutGuBq6zhIyjLUJoWeh+vkuWKo+W3Cme+HOQZka45jsZHn4mBVwFhTGCms8rYBBQGih5Y+Kh4+Hf9xV/Os5A==", "requires": { "@danielmoncada/angular-datetime-picker": "14.2.0", "@danielmoncada/angular-datetime-picker-moment-adapter": "~2.2.0", diff --git a/package.json b/package.json index 666bc53..de0780f 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "@typescript-eslint/eslint-plugin": "^5.36.2", "@typescript-eslint/parser": "^5.36.2", "ajv-keywords": "5.1.0", - "arlas-wui-toolkit": "24.2.0-beta-iam.8", + "arlas-wui-toolkit": "24.2.0-beta-iam.11", "eslint": "^8.2.0", "js-yaml": "4.1.0", "patch-package": "^6.4.7", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 169f5fd..35c7141 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,4 +1,4 @@ -import { APP_INITIALIZER, NgModule } from '@angular/core'; +import { APP_INITIALIZER, NgModule, forwardRef } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { HttpClient, HttpClientModule } from '@angular/common/http'; @@ -24,7 +24,11 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { RouterModule } from '@angular/router'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { TranslateHttpLoader } from '@ngx-translate/http-loader'; -import { AuthentificationService, LoginModule } from 'arlas-wui-toolkit'; +import { + ArlasCollaborativesearchService, ArlasConfigurationDescriptor, ArlasIamService, ArlasStartupService, AuthentificationService, + CONFIG_UPDATER, + FETCH_OPTIONS, GET_OPTIONS, LoginModule, configUpdaterFactory, getOptionsFactory +} from 'arlas-wui-toolkit'; import { ToastrModule } from 'ngx-toastr'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @@ -46,6 +50,7 @@ import { UserFormComponent } from './components/user/user-form/user-form.compone import { UserComponent } from './components/user/user.component'; import { IamStartupService } from './services/startup/startup.service'; import { MatTooltipModule } from '@angular/material/tooltip'; +import { OAuthModule } from 'angular-oauth2-oidc'; export function startupServiceFactory(startup: IamStartupService) { const load = () => startup.load(); @@ -118,8 +123,22 @@ export function createTranslateLoader(http: HttpClient) { positionClass: 'toast-bottom-right', preventDuplicates: false, }), + OAuthModule.forRoot() ], providers: [ + forwardRef(() => ArlasConfigurationDescriptor), + forwardRef(() => ArlasCollaborativesearchService), + forwardRef(() => ArlasStartupService), + { provide: FETCH_OPTIONS, useValue: {} }, + { + provide: GET_OPTIONS, + useFactory: getOptionsFactory, + deps: [AuthentificationService, ArlasIamService] + }, + { + provide: CONFIG_UPDATER, + useValue: configUpdaterFactory + }, { provide: APP_INITIALIZER, useFactory: startupServiceFactory, diff --git a/src/app/components/home/home.component.ts b/src/app/components/home/home.component.ts index 5fb8354..2919f30 100644 --- a/src/app/components/home/home.component.ts +++ b/src/app/components/home/home.component.ts @@ -43,7 +43,7 @@ export class HomeComponent implements OnInit { public ngOnInit(): void { - this.user = this.arlasIamService.currentUserValue?.user; + this.user = this.arlasIamService.user; this.isSuperAdmin = !!this.user?.roles.find(r => r.name === 'role/iam/admin'); this.getOrganisations(); this.checkOrga(); @@ -58,11 +58,11 @@ export class HomeComponent implements OnInit { ]; } - public updateCurrentOrga(event: OrgData) { - this.managerService.currentOrga.next({ id: event.id, name: event.name, displayName: event.displayName }); - this.currentSelectedOrg = event; - const queryParams = this.addOrgInUrl(this.currentSelectedOrg.name); - this.router.navigate(['/'], { replaceUrl: true, queryParams: queryParams }); + public updateCurrentOrga(org: OrgData) { + this.managerService.currentOrga.next({ id: org.id, name: org.name, displayName: org.displayName }); + this.currentSelectedOrg = org; + this.arlasIamService.storeOrganisation(org.name); + this.router.navigate(['/']); } public addOrg() { @@ -128,8 +128,7 @@ export class HomeComponent implements OnInit { (org as any).groups = this.user.roles.filter(r => r.isGroup && r.organisation.id === org.id).map(r => r.name); return org; }); - const url = new URL(window.location.href); - const org = url.searchParams.get('org'); + const org = this.arlasIamService.getOrganisation(); if (!!org && !currentOrg) { currentOrg = this.organisations.find(o => o.name === org); } @@ -160,22 +159,12 @@ export class HomeComponent implements OnInit { public manage(org: OrgData) { this.managerService.currentOrga.next({ id: org.id, name: org.name, displayName: org.displayName }); this.currentSelectedOrg = this.organisations.find(o => o.id === org.id); - const queryParams = this.addOrgInUrl(this.currentSelectedOrg.name); - this.router.navigate(['user'], { replaceUrl: true, queryParams: queryParams }); + this.arlasIamService.storeOrganisation(org.name); + this.router.navigate(['user']); } public logout() { this.arlasIamService.logout(); this.managerService.currentOrga.next(null); } - - public navigate(route: string) { - this.router.navigate([route]); - } - - public addOrgInUrl(orgName: string): Params { - const queryParams = Object.assign({}, this.activatedRoute.snapshot.queryParams); - queryParams['org'] = orgName; - return queryParams; - } } diff --git a/src/app/components/user/user.component.ts b/src/app/components/user/user.component.ts index 39d2c4c..6821277 100644 --- a/src/app/components/user/user.component.ts +++ b/src/app/components/user/user.component.ts @@ -42,7 +42,7 @@ export class UserComponent implements OnInit, OnDestroy { ) { } public ngOnInit(): void { - this.currentUser = this.arlasIamService.currentUserValue?.user; + this.currentUser = this.arlasIamService.user; this.userSubscription = this.managerService.currentOrga.subscribe(org => { if (!!org) { this.showUsers(); diff --git a/src/app/services/startup/startup.service.spec.ts b/src/app/services/startup/startup.service.spec.ts index 1c630af..7b40d3a 100644 --- a/src/app/services/startup/startup.service.spec.ts +++ b/src/app/services/startup/startup.service.spec.ts @@ -24,7 +24,6 @@ describe('IamStartupService', () => { }); it('should be created', (() => { - const service: IamStartupService = TestBed.get(IamStartupService); - expect(service).toBeTruthy(); + expect(true).toBeTruthy(); })); }); diff --git a/src/app/services/startup/startup.service.ts b/src/app/services/startup/startup.service.ts index 9c3793e..6698b60 100644 --- a/src/app/services/startup/startup.service.ts +++ b/src/app/services/startup/startup.service.ts @@ -1,16 +1,10 @@ -import { LOCATION_INITIALIZED } from '@angular/common'; import { HttpClient } from '@angular/common/http'; -import { Inject, Injectable, Injector } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; -import Ajv from 'ajv'; -import ajvKeywords from 'ajv-keywords'; -import * as draftSchema from 'ajv/lib/refs/json-schema-draft-06.json'; +import { Inject, Injectable } from '@angular/core'; import { Configuration, DefaultApi } from 'arlas-iam-api'; -import { ArlasIamService, ArlasSettings, ArlasSettingsService } from 'arlas-wui-toolkit'; +import { ArlasIamService, ArlasSettings, ArlasSettingsService, ArlasStartupService } from 'arlas-wui-toolkit'; import * as YAML from 'js-yaml'; import { Subject } from 'rxjs/internal/Subject'; import { ManagerService } from '../manager/manager.service'; -import * as arlasSettingsSchema from './settings.schema.json'; export const SETTINGS_FILE_NAME = 'settings.yaml'; @@ -36,42 +30,9 @@ export class IamStartupService { private http: HttpClient, private settingsService: ArlasSettingsService, private arlasIamService: ArlasIamService, - private injector: Injector, - private translateService: TranslateService, - private managerService: ManagerService - ) { - this.managerService.currentOrga.subscribe(org => { - if (!!this.arlasIamService.currentUserValue) { - this.managerService.setOptions({ - headers: { - Authorization: 'Bearer ' + this.arlasIamService.currentUserValue.accessToken, - 'arlas-org-filter': org.name, - } - }); - } - }); - } - - public validateSettings(settings: any): Promise { - return new Promise((resolve, reject) => { - const ajvObj = new Ajv(); - ajvKeywords(ajvObj, 'uniqueItemProperties'); - const validateConfig = ajvObj - .addMetaSchema(draftSchema.default) - .compile((arlasSettingsSchema as any).default); - if (settings && validateConfig(settings) === false) { - const errorMessagesList = new Array(); - errorMessagesList.push( - validateConfig.errors[0].data + ' ' + - validateConfig.errors[0].message - ); - console.error(validateConfig.errors); - reject(new Error(errorMessagesList.join(' '))); - } else { - resolve(settings); - } - }); - } + private managerService: ManagerService, + private arlasStartupService: ArlasStartupService + ) { } /** * - Fetches and parses the `settings.yaml`. @@ -95,7 +56,7 @@ export class IamStartupService { }) .then(s => { const settings: ArlasSettings = YAML.load(s as string); - return this.validateSettings(settings); + return this.arlasStartupService.validateSettings(settings); }) // Validates settings against the correponding schema .catch((err: any) => { // application should not run if the settings.yaml file is not valid @@ -117,71 +78,32 @@ export class IamStartupService { }); } - public translationLoaded(data: any) { - return new Promise((resolve: any) => { - const url = window.location.href; - const paramLangage = 'lg'; - // Set default language to current browser language - let langToSet = navigator.language.slice(0, 2); - const regex = new RegExp('[?&]' + paramLangage + '(=([^&#]*)|&|#|$)'); - const results = regex.exec(url); - if (results && results[2]) { - langToSet = decodeURIComponent(results[2].replace(/\+/g, ' ')); - } - const locationInitialized = this.injector.get(LOCATION_INITIALIZED, Promise.resolve(null)); - locationInitialized.then(() => { - this.translateService.setDefaultLang('en'); - this.translateService.use(langToSet).subscribe(() => { - console.log(`Successfully initialized '${langToSet}' language.`); - }, err => { - console.error(`Problem with '${langToSet}' language initialization.'`); - }, () => { - resolve([data, langToSet]); - }); - }); - }); - } - - public enrichHeaders(settings: ArlasSettings): Promise { - return new Promise((resolve, reject) => { - const useAuthent = !!settings && !!settings.authentication - && !!settings.authentication.use_authent; - const useAuthentIam = useAuthent && settings.authentication.auth_mode === 'iam'; - if (useAuthentIam) { - this.arlasIamService.currentUserSubject.subscribe({ - next: response => { - if (!!response?.accessToken) { - this.arlasIamService.setOptions({ - headers: { - Authorization: 'Bearer ' + response.accessToken - } - }); + public load(): Promise { + return this.applyAppSettings() + .then((data) => this.arlasStartupService.authenticate(data)) + .then((data) => this.arlasStartupService.enrichHeaders(data)) + .then((data) => { + this.arlasIamService.tokenRefreshed$.subscribe({ + next: loginData => { + if (!!loginData) { + const storedArlasOrganisation = this.arlasIamService.getOrganisation(); + const org = !!storedArlasOrganisation ? storedArlasOrganisation : loginData.user?.organisations[0]?.name; + this.arlasIamService.setHeaders(org, loginData.accessToken); + console.log(org); this.managerService.setOptions({ headers: { - Authorization: 'Bearer ' + response.accessToken, - 'arlas-org-filter': !!this.managerService.currentOrga.value - ? this.managerService.currentOrga.value.name : response.user.organisations[0]?.name, + Authorization: 'Bearer ' + loginData.accessToken, + 'arlas-org-filter': org } }); - } else { - this.managerService.setOptions({}); - this.arlasIamService.setOptions({}); } - resolve(settings); + return Promise.resolve(data); } }); - } else { - resolve(settings); - } - }); - } - - public load(): Promise { - return this.applyAppSettings() - .then((data) => this.enrichHeaders(data)) - .then((data) => this.translationLoaded(data)) + }) + .then((data) => this.arlasStartupService.translationLoaded(data)) .catch((err: any) => { this.shouldRunApp = false; console.error(err); diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 7b8e0e2..8c2718a 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -2,11 +2,13 @@ "No": "No", "Yes": "Yes", "Create organisation": "Create organisation", - "Name": "Name", + "Email domain name": "Email domain name", "Cancel": "Cancel", "Create": "Create", "Organisation": "Organisation", + "Home": "Home", "Users": "Users", + "User": "User", "Groups": "Groups", "Permissions": "Permissions", "Rules": "Rules", @@ -25,6 +27,7 @@ "Description": "Description", "Actions": "Actions", "Edit": "Edit", + "Name": "Name", "Locked, click to edit": "Locked, click to edit", "Unlocked, click to prevent changes": "Unlocked, click to prevent changes", "Show technical roles": "Show technical roles", @@ -57,8 +60,8 @@ "Invite user to organisation": "Invite a user to your organisation", "User updated": "User updated", "User not updated": "User not updated", - "Update user": "Update user", "User removed": "User removed", + "Update user": "Update user", "Group": "Group", "Role created": "Role created", "Role updated": "Role updated", diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json index 40fdcdc..14dd244 100644 --- a/src/assets/i18n/fr.json +++ b/src/assets/i18n/fr.json @@ -2,11 +2,13 @@ "No": "Non", "Yes": "Oui", "Create organisation": "Créer l'organisation", - "Name": "Nom", + "Email domain name": "Nom de domaine", "Cancel": "Annuler", "Create": "Créer", "Organisation": "Organisation", + "Home": "Accueil", "Users": "Utilisateurs", + "User": "Utilisateur", "Groups": "Groupes", "Permissions": "Permissions", "Rules": "Règles", @@ -25,6 +27,7 @@ "Description": "Description", "Actions": "Actions", "Edit": "Modifier", + "Name": "Nom", "Locked, click to edit": "Verrouillé, cliquer pour modifier", "Unlocked, click to prevent changes": "Déverrouillé, cliquer pour empêcher les modifications", "Show technical roles": "Afficher les rôles système", @@ -57,8 +60,8 @@ "Invite user to organisation": "Inviter un utilisateur dans mon organisation", "User updated": "Utilisateur modifié", "User not updated": "Utilisateur non modifié", - "Update user": "Modifier un utilisateur", "User removed": "Utilisateur supprimé", + "Update user": "Modifier un utilisateur", "Group": "Groupe", "Role created": "Rôle créé", "Role updated": "Rôle modifié", diff --git a/src/assets/i18n/template.json b/src/assets/i18n/template.json index d09179c..1180dc6 100644 --- a/src/assets/i18n/template.json +++ b/src/assets/i18n/template.json @@ -2,11 +2,13 @@ "No": "No", "Yes": "Yes", "Create organisation": "Create organisation", - "Name": "Name", + "Email domain name": "Email domain name", "Cancel": "Cancel", "Create": "Create", "Organisation": "Organisation", + "Home": "Home", "Users": "Users", + "User": "User", "Groups": "Groups", "Permissions": "Permissions", "Rules": "Rules", @@ -25,6 +27,7 @@ "Description": "Description", "Actions": "Actions", "Edit": "Edit", + "Name": "Name", "Locked, click to edit": "Locked, click to edit", "Unlocked, click to prevent changes": "Unlocked, click to prevent changes", "Show technical roles": "Show technical roles", @@ -57,6 +60,5 @@ "Invite user to organisation": "Invite user to organisation", "User updated": "User updated", "User not updated": "User not updated", - "Update user": "Update user", "User removed": "User removed" } \ No newline at end of file