diff --git a/angular.json b/angular.json index ea586cd101..edf769730d 100644 --- a/angular.json +++ b/angular.json @@ -204,6 +204,14 @@ } ] }, + "canary": { + "fileReplacements": [ + { + "replace": "demo-shell/src/environments/environment.ts", + "with": "demo-shell/src/environments/environment.canary.ts" + } + ] + }, "e2e": { "budgets": [ { diff --git a/demo-shell/src/app.config.json b/demo-shell/src/app.config.json index 072fd0d2cc..35cfe0fef9 100644 --- a/demo-shell/src/app.config.json +++ b/demo-shell/src/app.config.json @@ -15,6 +15,16 @@ "upload": { "threads": 1 }, + "authentication": { + "issuer": "{protocol}//{hostname}{:port}/auth/realms/alfresco", + "loginUrl": "{protocol}//{hostname}{:port}/auth/realms/alfresco/protocol/openid-connect/auth", + "silentRefreshRedirectUri": "{protocol}//{hostname}{:port}/assets/silent-refresh.html", + "redirectUri": "/", + "postLogoutRedirectUri": "#/logout", + "clientId": "alfresco", + "scope": "openid profile email", + "responseType": "code" + }, "oauth2": { "host": "{protocol}//{hostname}{:port}/auth/realms/alfresco", "clientId": "alfresco", diff --git a/demo-shell/src/app/app.module.ts b/demo-shell/src/app/app.module.ts index c736763b8c..0a658ff5e9 100644 --- a/demo-shell/src/app/app.module.ts +++ b/demo-shell/src/app/app.module.ts @@ -29,7 +29,8 @@ import { DebugAppConfigService, CoreModule, CoreAutomationService, - AuthBearerInterceptor + AuthBearerInterceptor, + AppConfigModule } from '@alfresco/adf-core'; import { ExtensionsModule } from '@alfresco/adf-extensions'; import { AppComponent } from './app.component'; @@ -115,6 +116,7 @@ import localeSv from '@angular/common/locales/sv'; import { setupAppNotifications } from './services/app-notifications-factory'; import { AppNotificationsService } from './services/app-notifications.service'; import { SearchFilterChipsComponent } from './components/search/search-filter-chips.component'; +import { AuthModule } from '@alfresco/adf-core/auth'; registerLocaleData(localeFr); registerLocaleData(localeDe); @@ -133,18 +135,42 @@ registerLocaleData(localeFi); registerLocaleData(localeDa); registerLocaleData(localeSv); +debugger; + @NgModule({ imports: [ BrowserModule, environment.e2e ? NoopAnimationsModule : BrowserAnimationsModule, + ...(environment.oidc ? + [ + // Initial navigation must be disabled when we use the OIDC package with HashLocationStrategy, check its documentation + RouterModule.forRoot(appRoutes, { useHash: true, relativeLinkResolution: 'legacy', initialNavigation: 'disabled' }), + + // With this, we bypass the legacy behaviour, and won't load the app config and don't initialize the JS API + CoreModule.forRoot({ authByJsApi: false }), + + // So, instead, we need to load the app config. hence the forRoot() method: + AppConfigModule.forRoot(), + + // and here we need to initialize the auth module + AuthModule + + // And finally, we can initialize the api services to wotk with the new authentication + // TODO: new form of AlfrescoApiService, which is compatible with the new authentication + ]: + // CANARY: remove this when we can use the new authentication + // ------------------------------------------------------------------ + [ + RouterModule.forRoot(appRoutes, { useHash: true, relativeLinkResolution: 'legacy' }), + CoreModule.forRoot({ authByJsApi: true }) + ] + ), ReactiveFormsModule, - RouterModule.forRoot(appRoutes, { useHash: true, relativeLinkResolution: 'legacy' }), FormsModule, HttpClientModule, MaterialModule, FlexLayoutModule, TranslateModule.forRoot(), - CoreModule.forRoot(), ContentModule.forRoot(), InsightsModule.forRoot(), ProcessModule.forRoot(), diff --git a/demo-shell/src/environments/environment.canary.ts b/demo-shell/src/environments/environment.canary.ts new file mode 100644 index 0000000000..4b6209c1bf --- /dev/null +++ b/demo-shell/src/environments/environment.canary.ts @@ -0,0 +1,27 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// The file contents for the current environment will overwrite these during build. +// The build system defaults to the dev environment which uses `environment.ts`, but if you do +// `ng build --env=prod` then `environment.prod.ts` will be used instead. +// The list of which env maps to which file can be found in `.angular-cli.json`. + +export const environment = { + production: false, + e2e: false, + oidc: true +}; diff --git a/demo-shell/src/environments/environment.e2e.ts b/demo-shell/src/environments/environment.e2e.ts index 75794a8611..0529498e74 100644 --- a/demo-shell/src/environments/environment.e2e.ts +++ b/demo-shell/src/environments/environment.e2e.ts @@ -17,5 +17,6 @@ export const environment = { production: false, - e2e: true + e2e: true, + oidc: false }; diff --git a/demo-shell/src/environments/environment.prod.ts b/demo-shell/src/environments/environment.prod.ts index 774915cd9e..3c4cf0fd7b 100644 --- a/demo-shell/src/environments/environment.prod.ts +++ b/demo-shell/src/environments/environment.prod.ts @@ -17,5 +17,6 @@ export const environment = { production: true, - e2e: false + e2e: false, + oidc: false }; diff --git a/demo-shell/src/environments/environment.ts b/demo-shell/src/environments/environment.ts index 3461759621..e305cf8648 100644 --- a/demo-shell/src/environments/environment.ts +++ b/demo-shell/src/environments/environment.ts @@ -22,5 +22,6 @@ export const environment = { production: false, - e2e: false + e2e: false, + oidc: false }; diff --git a/lib/core/auth/src/index.ts b/lib/core/auth/src/index.ts index 28b7be220c..bd83e04721 100644 --- a/lib/core/auth/src/index.ts +++ b/lib/core/auth/src/index.ts @@ -15,5 +15,6 @@ * limitations under the License. */ -export * from './authentication'; -export * from './authentication-interceptor/authentication.interceptor'; +export * from './lib/authentication'; +export * from './lib/authentication-interceptor/authentication.interceptor'; +export * from './lib/auth.module'; diff --git a/lib/core/auth/src/lib/auth.module.ts b/lib/core/auth/src/lib/auth.module.ts new file mode 100644 index 0000000000..41782fba75 --- /dev/null +++ b/lib/core/auth/src/lib/auth.module.ts @@ -0,0 +1,48 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { HttpClientModule } from '@angular/common/http'; +import { APP_INITIALIZER, NgModule } from '@angular/core'; +import { OAuthModule } from 'angular-oauth2-oidc'; +// import { AuthenticationService } from '@alfresco/adf-core'; +import { AuthGuard } from './guards/oidc-auth.guard'; +import { AuthConfigService, configureAuth } from './services/auth-config.service'; +// import { AuthService } from './services/oidc-authentication.service'; + +@NgModule({ + imports: [ + HttpClientModule, + OAuthModule.forRoot() + ], + providers: [ + AuthGuard, + AuthConfigService, + // AuthService, + { + provide: APP_INITIALIZER, + useFactory: configureAuth, + deps: [ AuthConfigService ] + }, + // TODO: CANARY: This is temporary, we are reproviding ADF's AuthenticationService with our own implementation to work with the new auth library + // TODO: But we need definitely need a cleaner solution for this. Which means, first we need to make the apis capable of handling multiple http clients + // { + // provide: AuthenticationService, + // useExisting: AuthService + // } + ] +}) +export class AuthModule {} diff --git a/lib/core/auth/src/authentication-interceptor/README.md b/lib/core/auth/src/lib/authentication-interceptor/README.md similarity index 100% rename from lib/core/auth/src/authentication-interceptor/README.md rename to lib/core/auth/src/lib/authentication-interceptor/README.md diff --git a/lib/core/auth/src/authentication-interceptor/authentication.interceptor.spec.ts b/lib/core/auth/src/lib/authentication-interceptor/authentication.interceptor.spec.ts similarity index 100% rename from lib/core/auth/src/authentication-interceptor/authentication.interceptor.spec.ts rename to lib/core/auth/src/lib/authentication-interceptor/authentication.interceptor.spec.ts diff --git a/lib/core/auth/src/authentication-interceptor/authentication.interceptor.ts b/lib/core/auth/src/lib/authentication-interceptor/authentication.interceptor.ts similarity index 100% rename from lib/core/auth/src/authentication-interceptor/authentication.interceptor.ts rename to lib/core/auth/src/lib/authentication-interceptor/authentication.interceptor.ts diff --git a/lib/core/auth/src/authentication.ts b/lib/core/auth/src/lib/authentication.ts similarity index 100% rename from lib/core/auth/src/authentication.ts rename to lib/core/auth/src/lib/authentication.ts diff --git a/lib/core/auth/src/lib/guards/oidc-auth.guard.ts b/lib/core/auth/src/lib/guards/oidc-auth.guard.ts new file mode 100644 index 0000000000..a64de27ae6 --- /dev/null +++ b/lib/core/auth/src/lib/guards/oidc-auth.guard.ts @@ -0,0 +1,47 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Injectable } from '@angular/core'; +import { CanActivate, CanActivateChild } from '@angular/router'; +import { OAuthService } from 'angular-oauth2-oidc'; +import { AuthConfigService } from '../services/auth-config.service'; + +@Injectable() +export class AuthGuard implements CanActivate, CanActivateChild { + + constructor( + private authConfigService: AuthConfigService, + private oauthService: OAuthService + ) {} + + canActivate(): boolean { + if (!this.oauthService.hasValidAccessToken()) { + if (this.authConfigService.isCodeFlow()) { + this.oauthService.initCodeFlow(); + } else { + this.oauthService.initLoginFlow(); + } + return false; + } + + return true; + } + + canActivateChild(): boolean { + return this.canActivate(); + } +} diff --git a/lib/core/auth/src/lib/services/auth-config.service.ts b/lib/core/auth/src/lib/services/auth-config.service.ts new file mode 100644 index 0000000000..b1cb6401dd --- /dev/null +++ b/lib/core/auth/src/lib/services/auth-config.service.ts @@ -0,0 +1,81 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Injectable } from '@angular/core'; +import { AuthConfig, OAuthService } from 'angular-oauth2-oidc'; +import { JwksValidationHandler } from 'angular-oauth2-oidc-jwks'; +import { take } from 'rxjs/operators'; +import { Router } from '@angular/router'; +import { StorageService } from '@alfresco/adf-core/common'; +import { AppConfigService, AppConfigValues } from '@alfresco/adf-core/config'; + +export const configureAuth = (oidcAuthentication: AuthConfigService) => () => oidcAuthentication.init(); + +@Injectable() +export class AuthConfigService { + + _authConfig: AuthConfig; + + constructor( + private appConfigService: AppConfigService, + private storageService: StorageService, + private oauthService: OAuthService, + private router: Router + ) {} + + public init() { + debugger; + this.appConfigService.onLoad + .pipe(take(1)) + .toPromise() + .then(this.configure.bind(this)); + } + + private configure() { + this._authConfig = this.appConfigService.get(AppConfigValues.AUTH_CONFIG, null); + // TODO: add the authenticaion object's schema to the app.config.schema.json + this.oauthService.configure(this._authConfig); + this.oauthService.tokenValidationHandler = new JwksValidationHandler(); + this.oauthService.setStorage(this.storageService); + this.oauthService.setupAutomaticSilentRefresh(); + + // This is what deald with the responded code and does the magic + this.oauthService.loadDiscoveryDocumentAndTryLogin().then(() => { + // initialNavigation: false needs because of the OIDC package!!! + // https://manfredsteyer.github.io/angular-oauth2-oidc/docs/additional-documentation/routing-with-the-hashstrategy.html + this.router.navigate(['/']); + }); + } + + isCodeFlow(): boolean { + return this._authConfig.responseType === 'code'; + } + + // private getAuthConfig(codeFlow = false): AuthConfig { + // const oauth2: OauthConfigModel = Object.assign({}); + // return { + // issuer: oauth2.host, + // loginUrl: `${oauth2.host}/protocol/openid-connect/auth`, + // silentRefreshRedirectUri: oauth2.redirectSilentIframeUri, + // redirectUri: window.location.origin + oauth2.redirectUri, + // postLogoutRedirectUri: window.location.origin + oauth2.redirectUriLogout, + // clientId: oauth2.clientId, + // scope: oauth2.scope, + // ...(codeFlow ? { responseType: 'code' } : {}) + // }; + // } +} diff --git a/lib/core/auth/src/lib/services/oidc-authentication.service.ts b/lib/core/auth/src/lib/services/oidc-authentication.service.ts new file mode 100644 index 0000000000..6604df7a1d --- /dev/null +++ b/lib/core/auth/src/lib/services/oidc-authentication.service.ts @@ -0,0 +1,203 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Injectable } from '@angular/core'; +import { Observable, from, throwError, ReplaySubject, of } from 'rxjs'; +import { LogService } from '../../../../src/lib/common/services/log.service'; +import { RedirectionModel } from '../../models/redirection.model'; +import { AppConfigService, AppConfigValues } from '@alfresco/adf-core'; +import { PeopleApi, UserProfileApi, UserRepresentation } from '@alfresco/js-api'; +import { JwtHelperService } from '../../services/jwt-helper.service'; +import { StorageService } from '../../../../src/lib/common/services/storage.service'; +import { OauthConfigModel } from '../../models/oauth-config.model'; +import { BaseAuthenticationService } from '../base-authentication.service'; +import { ADFAuthenticationService } from '../authentication.interface'; +import { AlfrescoApiClientFactory } from '../../alfresco-api'; +import { OAuthService } from 'angular-oauth2-oidc'; +import minimatch from 'minimatch'; + +@Injectable({ + providedIn: 'root' +}) +export class AuthService extends BaseAuthenticationService implements ADFAuthenticationService { + onLogin: ReplaySubject = new ReplaySubject(1); + onLogout: ReplaySubject = new ReplaySubject(1); + + get peopleApi(): PeopleApi { + return this.alfrescoApiClientFactory.getPeopleApi(); + } + get profileApi(): UserProfileApi { + return this.alfrescoApiClientFactory.getProfileApi(); + } + + constructor( + private alfrescoApiClientFactory: AlfrescoApiClientFactory, + private appConfig: AppConfigService, + private storageService: StorageService, + private oauthService: OAuthService, + private logService: LogService) { + super(); + // this.alfrescoApi.alfrescoApiInitialized.subscribe(() => { + // this.alfrescoApi.getInstance().reply('logged-in', () => { + // this.onLogin.next(); + // }); + + // if (this.isKerberosEnabled()) { + // this.loadUserDetails(); + // } + // }); + } + + // private loadUserDetails() { + // const ecmUser$ = from(this.peopleApi.getPerson('-me-')); + // const bpmUser$ = this.getBpmLoggedUser(); + + // if (this.isALLProvider()) { + // forkJoin([ecmUser$, bpmUser$]).subscribe(() => this.onLogin.next()); + // } else if (this.isECMProvider()) { + // ecmUser$.subscribe(() => this.onLogin.next()); + // } else { + // bpmUser$.subscribe(() => this.onLogin.next()); + // } + // } + + isLoggedIn(): boolean { + return this.oauthService.hasValidAccessToken() && this.oauthService.hasValidIdToken(); + } + + isLoggedInWith(provider?: string): boolean { + console.log(provider); + return this.isLoggedIn(); + } + + isKerberosEnabled(): boolean { + return this.appConfig.get(AppConfigValues.AUTH_WITH_CREDENTIALS, false); + } + + isOauth(): boolean { + return this.appConfig.get(AppConfigValues.AUTHTYPE) === 'OAUTH'; + } + + oidcHandlerEnabled(): boolean { + const oauth2: OauthConfigModel = Object.assign({}, this.appConfig.get(AppConfigValues.OAUTHCONFIG, null)); + return oauth2?.handler === 'oidc'; + } + + isImplicitFlow() { + const oauth2: OauthConfigModel = Object.assign({}, this.appConfig.get(AppConfigValues.OAUTHCONFIG, null)); + return !!oauth2?.implicitFlow; + } + + isAuthCodeFlow() { + const oauth2: OauthConfigModel = Object.assign({}, this.appConfig.get(AppConfigValues.OAUTHCONFIG, null)); + return !!oauth2?.codeFlow; + } + + isPublicUrl(): boolean { + const oauth2: OauthConfigModel = Object.assign({}, this.appConfig.get(AppConfigValues.OAUTHCONFIG, null)); + const publicUrls = oauth2.publicUrls || []; + + if (Array.isArray(publicUrls)) { + return publicUrls.length > 0 && + publicUrls.some((urlPattern: string) => minimatch(window.location.href, urlPattern)); + } + return false; + } + + isECMProvider(): boolean { + return this.appConfig.get(AppConfigValues.PROVIDERS).toUpperCase() === 'ECM'; + } + isBPMProvider(): boolean { + return this.appConfig.get(AppConfigValues.PROVIDERS).toUpperCase() === 'BPM'; + } + + isALLProvider(): boolean { + return this.appConfig.get(AppConfigValues.PROVIDERS).toUpperCase() === 'ALL'; + } + + login(): Observable<{ type: string; ticket: any }> { + return of(); + } + + ssoImplicitLogin() { + this.oauthService.initLoginFlow(); + } + + ssoCodeFlowLogin() { + this.oauthService.initCodeFlow(); + } + + isRememberMeSet(): boolean { + return true; + } + + logout() { + this.oauthService.logOut(); + return of(); + } + + getTicketEcm(): string | null { + return null; + } + + getTicketBpm(): string | null { + return null; + } + + getTicketEcmBase64(): string | null { + return null; + } + + isEcmLoggedIn(): boolean { + return this.isLoggedIn(); + } + + isBpmLoggedIn(): boolean { + return this.isLoggedIn(); + } + + getEcmUsername(): string { + return 'To Be Implemented'; + } + + getBpmUsername(): string { + return 'To Be Implemented'; + } + + setRedirect(url?: RedirectionModel) { + console.log(url); + // noop + } + + getRedirect(): string { + // noop + return 'noop'; + } + + getBpmLoggedUser(): Observable { + return from(this.profileApi.getProfile()); + } + + handleError(error: any): Observable { + this.logService.error('Error when logging in', error); + return throwError(error || 'Server error'); + } + + getToken(): string { + return this.storageService.getItem(JwtHelperService.USER_ACCESS_TOKEN); + } +} diff --git a/lib/core/src/lib/app-config/app-config.loader.ts b/lib/core/src/lib/app-config/app-config.loader.ts new file mode 100644 index 0000000000..84460caac1 --- /dev/null +++ b/lib/core/src/lib/app-config/app-config.loader.ts @@ -0,0 +1,25 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { StorageService } from '../common'; +import { AppConfigService, AppConfigValues } from './app-config.service'; + +export function loadAppConfig(appConfigService: AppConfigService, storageService: StorageService) { + return () => appConfigService.load().then(() => { + storageService.prefix = appConfigService.get(AppConfigValues.STORAGE_PREFIX, ''); + }); +} diff --git a/lib/core/src/lib/app-config/app-config.module.ts b/lib/core/src/lib/app-config/app-config.module.ts index 7a140d5981..86f7dc0494 100644 --- a/lib/core/src/lib/app-config/app-config.module.ts +++ b/lib/core/src/lib/app-config/app-config.module.ts @@ -16,8 +16,19 @@ */ import { HttpClientModule } from '@angular/common/http'; -import { NgModule } from '@angular/core'; +import { APP_INITIALIZER, ModuleWithProviders, NgModule } from '@angular/core'; +import { StorageService } from '../common'; +import { loadAppConfig } from './app-config.loader'; import { AppConfigPipe } from './app-config.pipe'; +import { AppConfigService } from './app-config.service'; + +interface AppConfigModuleConfig { + loadConfig: boolean; +} + +const defaultConfig: AppConfigModuleConfig = { + loadConfig: true +}; @NgModule({ imports: [ @@ -31,4 +42,18 @@ import { AppConfigPipe } from './app-config.pipe'; ] }) export class AppConfigModule { + static forRoot(config: AppConfigModuleConfig = defaultConfig): ModuleWithProviders { + return { + ngModule: AppConfigModule, + providers: [ + ...(config.loadConfig ? + [{ + provide: APP_INITIALIZER, + useFactory: loadAppConfig, + deps: [ AppConfigService, StorageService ], multi: true } + ] : [] + ) + ] + }; + } } diff --git a/lib/core/src/lib/app-config/app-config.service.ts b/lib/core/src/lib/app-config/app-config.service.ts index 1cbba21630..613e6debeb 100644 --- a/lib/core/src/lib/app-config/app-config.service.ts +++ b/lib/core/src/lib/app-config/app-config.service.ts @@ -28,6 +28,7 @@ import { OpenidConfiguration } from '../auth/interfaces/openid-configuration.int export enum AppConfigValues { APP_CONFIG_LANGUAGES_KEY = 'languages', PROVIDERS = 'providers', + AUTH_CONFIG = 'authentication', OAUTHCONFIG = 'oauth2', ECMHOST = 'ecmHost', BASESHAREURL = 'baseShareUrl', diff --git a/lib/core/src/lib/core.module.ts b/lib/core/src/lib/core.module.ts index fdf14d1062..222f6096ba 100644 --- a/lib/core/src/lib/core.module.ts +++ b/lib/core/src/lib/core.module.ts @@ -64,6 +64,14 @@ import { HttpClientModule, HttpClientXsrfModule, HTTP_INTERCEPTORS } from '@angu import { AuthenticationService } from './auth/services/authentication.service'; import { MAT_SNACK_BAR_DEFAULT_OPTIONS } from '@angular/material/snack-bar'; +interface LegacyMonolithCoreModuleConfig { + authByJsApi: boolean; +} + +const defaultConfig: LegacyMonolithCoreModuleConfig = { + authByJsApi: true +}; + @NgModule({ imports: [ TranslateModule, @@ -142,21 +150,20 @@ import { MAT_SNACK_BAR_DEFAULT_OPTIONS } from '@angular/material/snack-bar'; ] }) export class CoreModule { - static forRoot(): ModuleWithProviders { + static forRoot(config: LegacyMonolithCoreModuleConfig = defaultConfig): ModuleWithProviders { + debugger; return { ngModule: CoreModule, providers: [ TranslateStore, TranslateService, { provide: TranslateLoader, useClass: TranslateLoaderService }, - { - provide: APP_INITIALIZER, - useFactory: startupServiceFactory, - deps: [ - AlfrescoApiService - ], - multi: true - }, + ...(config.authByJsApi ? + [{ + provide: APP_INITIALIZER, + useFactory: startupServiceFactory, + deps: [ AlfrescoApiService ], multi: true + }] : []), { provide: APP_INITIALIZER, useFactory: directionalityConfigFactory, diff --git a/package-lock.json b/package-lock.json index 553d77b541..e76a8498f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26984,6 +26984,15 @@ "tslib": "^2.0.0" } }, + "angular-oauth2-oidc-jwks": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/angular-oauth2-oidc-jwks/-/angular-oauth2-oidc-jwks-15.0.1.tgz", + "integrity": "sha512-70IEHYqh+tnsGJ56HKKghzEV597G1EgCZ5k2spp/GosBBPMi/PhCriVHgnsDWwS+ayE7HL9IU2+mc6oCh/t4mA==", + "requires": { + "jsrsasign": "^10.3.0", + "tslib": "^2.0.0" + } + }, "ansi-align": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", @@ -36811,6 +36820,11 @@ "verror": "1.10.0" } }, + "jsrsasign": { + "version": "10.6.1", + "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-10.6.1.tgz", + "integrity": "sha512-emiQ05haY9CRj1Ho/LiuCqr/+8RgJuWdiHYNglIg2Qjfz0n+pnUq9I2QHplXuOMO2EnAW1oCGC1++aU5VoWSlw==" + }, "jszip": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.0.tgz", diff --git a/package.json b/package.json index c4fb4b479e..2c98ed424e 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,7 @@ "@ngx-translate/core": "^14.0.0", "@storybook/core-server": "6.4.22", "angular-oauth2-oidc": "^14.0.1", + "angular-oauth2-oidc-jwks": "^15.0.1", "apollo-angular": "^4.0.1", "chart.js": "2.9.4", "cropperjs": "1.5.13", diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 0000000000..56819505fa --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,53 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "downlevelIteration": true, + "module": "esnext", + "rootDir": ".", + "outDir": "./dist/out-tsc", + "baseUrl": ".", + "sourceMap": true, + "declaration": false, + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "skipLibCheck": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "target": "es2015", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "typeRoots": ["node_modules/@types"], + "types": ["jasmine", "node", "jasminewd2"], + "lib": ["es2018", "esnext.array", "esnext.asynciterable", "dom"], + "paths": { + "@alfresco/adf-content-services": ["lib/content-services"], + "@alfresco/adf-core": ["lib/core"], + "@alfresco/adf-core/auth": ["lib/core/auth/src/index.ts"], + "@alfresco/adf-core/shell": ["lib/core/shell/src/index.ts"], + "@alfresco/adf-core/common": ["lib/core/src/lib/common/index.ts"], + "@alfresco/adf-core/config": ["lib/core/src/lib/app-config/index.ts"], + "@alfresco/adf-core/*": ["lib/core/*/public-api.ts"], + "@alfresco/adf-extensions": ["lib/extensions"], + "@alfresco/adf-insights": ["lib/insights"], + "@alfresco/adf-process-services": ["lib/process-services"], + "@alfresco/adf-process-services-cloud": ["lib/process-services-cloud"], + "@alfresco/adf-testing": ["lib/testing"], + "@alfresco/js-api": ["node_modules/@alfresco/js-api"] + } + }, + "exclude": [ + "lib/config", + "integration", + "scripts", + "assets", + "tools", + "node_modules" + ], + "angularCompilerOptions": { + "fullTemplateTypeCheck": true, + "strictInjectionParameters": true, + "strictTemplates": true + } +} diff --git a/tsconfig.json b/tsconfig.json index fd926c0005..ffcbb9477e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,51 +1,3 @@ { - "compileOnSave": false, - "compilerOptions": { - "downlevelIteration": true, - "module": "esnext", - "rootDir": ".", - "outDir": "./dist/out-tsc", - "baseUrl": ".", - "sourceMap": true, - "declaration": false, - "moduleResolution": "node", - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "skipLibCheck": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "target": "es2015", - "allowSyntheticDefaultImports": true, - "resolveJsonModule": true, - "typeRoots": ["node_modules/@types"], - "types": ["jasmine", "node", "jasminewd2"], - "lib": ["es2018", "esnext.array", "esnext.asynciterable", "dom"], - "paths": { - "@alfresco/adf-content-services": ["lib/content-services"], - "@alfresco/adf-core": ["lib/core"], - "@alfresco/adf-core/*": ["lib/core/*/public-api.ts"], - "@alfresco/adf-core/auth": ["lib/core/auth/src/index.ts"], - "@alfresco/adf-core/shell": ["lib/core/shell/src/index.ts"], - "@alfresco/adf-extensions": ["lib/extensions"], - "@alfresco/adf-insights": ["lib/insights"], - "@alfresco/adf-process-services": ["lib/process-services"], - "@alfresco/adf-process-services-cloud": ["lib/process-services-cloud"], - "@alfresco/adf-testing": ["lib/testing"], - "@alfresco/js-api": ["node_modules/@alfresco/js-api"] - } - }, - "exclude": [ - "lib/config", - "integration", - "scripts", - "assets", - "tools", - "node_modules" - ], - "angularCompilerOptions": { - "fullTemplateTypeCheck": true, - "strictInjectionParameters": true, - "strictTemplates": true - } + "extends": "./tsconfig.base.json" }