diff --git a/npm/ng-packs/apps/dev-app/src/app/home/home.component.html b/npm/ng-packs/apps/dev-app/src/app/home/home.component.html index 2733150b71..ae3196c0c6 100644 --- a/npm/ng-packs/apps/dev-app/src/app/home/home.component.html +++ b/npm/ng-packs/apps/dev-app/src/app/home/home.component.html @@ -8,12 +8,7 @@ abp.io - {{ 'AbpIdentity::Login' | abpLocalization }} diff --git a/npm/ng-packs/apps/dev-app/src/app/home/home.component.ts b/npm/ng-packs/apps/dev-app/src/app/home/home.component.ts index a42b960493..3790f8fe3f 100644 --- a/npm/ng-packs/apps/dev-app/src/app/home/home.component.ts +++ b/npm/ng-packs/apps/dev-app/src/app/home/home.component.ts @@ -1,3 +1,4 @@ +import { AuthService } from '@abp/ng.core'; import { Component } from '@angular/core'; import { OAuthService } from 'angular-oauth2-oidc'; @@ -10,5 +11,9 @@ export class HomeComponent { return this.oAuthService.hasValidAccessToken(); } - constructor(private oAuthService: OAuthService) {} + constructor(private oAuthService: OAuthService, private authService: AuthService) {} + + login() { + this.authService.initLogin(); + } } diff --git a/npm/ng-packs/apps/dev-app/src/environments/environment.prod.ts b/npm/ng-packs/apps/dev-app/src/environments/environment.prod.ts index 21e1302773..70af33346f 100644 --- a/npm/ng-packs/apps/dev-app/src/environments/environment.prod.ts +++ b/npm/ng-packs/apps/dev-app/src/environments/environment.prod.ts @@ -1,20 +1,21 @@ import { Config } from '@abp/ng.core'; +const baseUrl = 'http://localhost:4200'; + export const environment = { production: true, hmr: false, application: { - baseUrl: 'http://localhost:4200/', + baseUrl, name: 'MyProjectName', logoUrl: '', }, oAuthConfig: { issuer: 'https://localhost:44305', + redirectUri: baseUrl, clientId: 'MyProjectName_App', - dummyClientSecret: '1q2w3e*', - scope: 'MyProjectName', - oidc: false, - requireHttps: true, + responseType: 'code', + scope: 'offline_access MyProjectName', }, apis: { default: { diff --git a/npm/ng-packs/apps/dev-app/src/environments/environment.ts b/npm/ng-packs/apps/dev-app/src/environments/environment.ts index 8cae243d46..2bf42cf7dc 100644 --- a/npm/ng-packs/apps/dev-app/src/environments/environment.ts +++ b/npm/ng-packs/apps/dev-app/src/environments/environment.ts @@ -1,20 +1,21 @@ import { Config } from '@abp/ng.core'; +const baseUrl = 'http://localhost:4200'; + export const environment = { production: false, hmr: false, application: { - baseUrl: 'http://localhost:4200/', + baseUrl, name: 'MyProjectName', logoUrl: '', }, oAuthConfig: { issuer: 'https://localhost:44305', + redirectUri: baseUrl, clientId: 'MyProjectName_App', - dummyClientSecret: '1q2w3e*', - scope: 'MyProjectName', - oidc: false, - requireHttps: true, + responseType: 'code', + scope: 'offline_access MyProjectName', }, apis: { default: { diff --git a/npm/ng-packs/package.json b/npm/ng-packs/package.json index fa58409270..0951ad2d1c 100644 --- a/npm/ng-packs/package.json +++ b/npm/ng-packs/package.json @@ -51,7 +51,7 @@ "@fortawesome/fontawesome-free": "^5.13.0", "@ng-bootstrap/ng-bootstrap": "^6.1.0", "@ngneat/spectator": "^5.11.0", - "@ngx-validate/core": "^0.0.10", + "@ngx-validate/core": "^0.0.11", "@ngxs/devtools-plugin": "^3.6.2", "@ngxs/logger-plugin": "^3.6.2", "@ngxs/router-plugin": "^3.6.2", @@ -60,7 +60,7 @@ "@swimlane/ngx-datatable": "^17.0.0", "@types/jest": "^25.2.3", "@types/node": "^12.11.1", - "angular-oauth2-oidc": "^9.2.2", + "angular-oauth2-oidc": "^10.0.3", "bootstrap": "^4.5.0", "chart.js": "^2.9.3", "codelyzer": "^5.1.2", diff --git a/npm/ng-packs/packages/account/src/lib/account-routing.module.ts b/npm/ng-packs/packages/account/src/lib/account-routing.module.ts index 2225e7c592..6883921202 100644 --- a/npm/ng-packs/packages/account/src/lib/account-routing.module.ts +++ b/npm/ng-packs/packages/account/src/lib/account-routing.module.ts @@ -10,6 +10,7 @@ import { LoginComponent } from './components/login/login.component'; import { ManageProfileComponent } from './components/manage-profile/manage-profile.component'; import { RegisterComponent } from './components/register/register.component'; import { eAccountComponents } from './enums/components'; +import { AuthenticationFlowGuard } from './guards/authentication-flow.guard'; const routes: Routes = [ { path: '', pathMatch: 'full', redirectTo: 'login' }, @@ -20,6 +21,7 @@ const routes: Routes = [ { path: 'login', component: ReplaceableRouteContainerComponent, + canActivate: [AuthenticationFlowGuard], data: { replaceableComponent: { key: eAccountComponents.Login, @@ -30,6 +32,7 @@ const routes: Routes = [ { path: 'register', component: ReplaceableRouteContainerComponent, + canActivate: [AuthenticationFlowGuard], data: { replaceableComponent: { key: eAccountComponents.Register, diff --git a/npm/ng-packs/packages/account/src/lib/account.module.ts b/npm/ng-packs/packages/account/src/lib/account.module.ts index 0ee605a75a..7f2151dfd1 100644 --- a/npm/ng-packs/packages/account/src/lib/account.module.ts +++ b/npm/ng-packs/packages/account/src/lib/account.module.ts @@ -14,6 +14,7 @@ import { TenantBoxComponent } from './components/tenant-box/tenant-box.component import { Options } from './models/options'; import { ACCOUNT_OPTIONS } from './tokens/options.token'; import { accountOptionsFactory } from './utils/factory-utils'; +import { AuthenticationFlowGuard } from './guards/authentication-flow.guard'; @NgModule({ declarations: [ @@ -39,6 +40,7 @@ export class AccountModule { return { ngModule: AccountModule, providers: [ + AuthenticationFlowGuard, { provide: ACCOUNT_OPTIONS, useValue: options }, { provide: 'ACCOUNT_OPTIONS', diff --git a/npm/ng-packs/packages/account/src/lib/guards/authentication-flow.guard.ts b/npm/ng-packs/packages/account/src/lib/guards/authentication-flow.guard.ts new file mode 100644 index 0000000000..7cb719628e --- /dev/null +++ b/npm/ng-packs/packages/account/src/lib/guards/authentication-flow.guard.ts @@ -0,0 +1,15 @@ +import { AuthService } from '@abp/ng.core'; +import { Injectable } from '@angular/core'; +import { CanActivate } from '@angular/router'; + +@Injectable() +export class AuthenticationFlowGuard implements CanActivate { + constructor(private authService: AuthService) {} + + canActivate() { + if (this.authService.isInternalAuth) return true; + + this.authService.initLogin(); + return false; + } +} diff --git a/npm/ng-packs/packages/account/src/lib/guards/index.ts b/npm/ng-packs/packages/account/src/lib/guards/index.ts new file mode 100644 index 0000000000..382170b2b1 --- /dev/null +++ b/npm/ng-packs/packages/account/src/lib/guards/index.ts @@ -0,0 +1 @@ +export * from './authentication-flow.guard'; diff --git a/npm/ng-packs/packages/account/src/public-api.ts b/npm/ng-packs/packages/account/src/public-api.ts index 8d1ef3c43a..aebccb74cc 100644 --- a/npm/ng-packs/packages/account/src/public-api.ts +++ b/npm/ng-packs/packages/account/src/public-api.ts @@ -1,6 +1,7 @@ export * from './lib/account.module'; export * from './lib/components'; export * from './lib/enums'; -export * from './lib/tokens'; +export * from './lib/guards'; export * from './lib/models'; export * from './lib/services'; +export * from './lib/tokens'; diff --git a/npm/ng-packs/packages/core/package.json b/npm/ng-packs/packages/core/package.json index 4053f0fcc4..4ccafae3a0 100644 --- a/npm/ng-packs/packages/core/package.json +++ b/npm/ng-packs/packages/core/package.json @@ -12,7 +12,7 @@ "@ngxs/router-plugin": "^3.6.2", "@ngxs/storage-plugin": "^3.6.2", "@ngxs/store": "^3.6.2", - "angular-oauth2-oidc": "^9.2.2", + "angular-oauth2-oidc": "^10.0.0", "just-clone": "^3.1.0", "just-compare": "^1.3.0", "snq": "^1.0.3", diff --git a/npm/ng-packs/packages/core/src/lib/handlers/oauth-configuration.handler.ts b/npm/ng-packs/packages/core/src/lib/handlers/oauth-configuration.handler.ts index d9c6806900..e0505d2f2d 100644 --- a/npm/ng-packs/packages/core/src/lib/handlers/oauth-configuration.handler.ts +++ b/npm/ng-packs/packages/core/src/lib/handlers/oauth-configuration.handler.ts @@ -16,8 +16,6 @@ export class OAuthConfigurationHandler { private oAuthService: OAuthService, @Inject(CORE_OPTIONS) private options: ABP.Root, ) { - this.oAuthService.configure(this.options.environment.oAuthConfig); - this.listenToSetEnvironment(); } diff --git a/npm/ng-packs/packages/core/src/lib/services/auth.service.ts b/npm/ng-packs/packages/core/src/lib/services/auth.service.ts index 3a343fd2cb..6b86b580df 100644 --- a/npm/ng-packs/packages/core/src/lib/services/auth.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/auth.service.ts @@ -1,26 +1,58 @@ import { HttpHeaders } from '@angular/common/http'; -import { Inject, Injectable, Optional } from '@angular/core'; +import { Inject, Injectable, Injector, Optional } from '@angular/core'; import { Navigate } from '@ngxs/router-plugin'; -import { Store } from '@ngxs/store'; +import { Actions, ofActionSuccessful, Store } from '@ngxs/store'; import { OAuthService } from 'angular-oauth2-oidc'; import { from, Observable } from 'rxjs'; -import { switchMap, tap, take } from 'rxjs/operators'; +import { switchMap, take, tap } from 'rxjs/operators'; import snq from 'snq'; -import { GetAppConfiguration } from '../actions/config.actions'; +import { GetAppConfiguration, SetEnvironment } from '../actions/config.actions'; +import { ConfigState } from '../states/config.state'; import { SessionState } from '../states/session.state'; +import { AuthFlowStrategy, AUTH_FLOW_STRATEGY } from '../strategies/auth-flow.strategy'; import { RestService } from './rest.service'; -import { ConfigState } from '../states/config.state'; @Injectable({ providedIn: 'root', }) export class AuthService { + private flow: string; + private strategy: AuthFlowStrategy; + + get isInternalAuth() { + return this.strategy.isInternalAuth; + } + constructor( + private actions: Actions, + private injector: Injector, private rest: RestService, private oAuthService: OAuthService, private store: Store, @Optional() @Inject('ACCOUNT_OPTIONS') private options: any, - ) {} + ) { + this.setStrategy(); + this.listenToSetEnvironment(); + } + + private setStrategy = () => { + const flow = + this.store.selectSnapshot(ConfigState.getDeep('environment.oAuthConfig.responseType')) || + 'password'; + if (this.flow === flow) return; + + if (this.strategy) this.strategy.destroy(); + + this.flow = flow; + this.strategy = + this.flow === 'code' + ? AUTH_FLOW_STRATEGY.Code(this.injector) + : AUTH_FLOW_STRATEGY.Password(this.injector); + }; + + private listenToSetEnvironment() { + this.actions.pipe(ofActionSuccessful(SetEnvironment)).subscribe(this.setStrategy); + } login(username: string, password: string): Observable { const tenant = this.store.selectSnapshot(SessionState.getTenant); @@ -45,23 +77,15 @@ export class AuthService { ); } - logout(): Observable { - const issuer = this.store.selectSnapshot(ConfigState.getDeep('environment.oAuthConfig.issuer')); + async init() { + return await this.strategy.init(); + } + + logout(): Observable { + return this.strategy.logout(); + } - return this.rest - .request( - { - method: 'GET', - url: '/api/account/logout', - }, - null, - issuer, - ) - .pipe( - switchMap(() => { - this.oAuthService.logOut(true); - return this.store.dispatch(new GetAppConfiguration()); - }), - ); + initLogin() { + this.strategy.login(); } } diff --git a/npm/ng-packs/packages/core/src/lib/strategies/auth-flow.strategy.ts b/npm/ng-packs/packages/core/src/lib/strategies/auth-flow.strategy.ts new file mode 100644 index 0000000000..b7aa5601e2 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/strategies/auth-flow.strategy.ts @@ -0,0 +1,108 @@ +import { Injector } from '@angular/core'; +import { Store } from '@ngxs/store'; +import { AuthConfig, OAuthService } from 'angular-oauth2-oidc'; +import { ConfigState } from '../states/config.state'; +import { CORE_OPTIONS } from '../tokens/options.token'; +import { Router } from '@angular/router'; +import { Observable, of } from 'rxjs'; +import { RestService } from '../services/rest.service'; +import { switchMap } from 'rxjs/operators'; +import { GetAppConfiguration } from '../actions/config.actions'; + +export abstract class AuthFlowStrategy { + abstract readonly isInternalAuth: boolean; + + protected oAuthService: OAuthService; + protected oAuthConfig: AuthConfig; + abstract checkIfInternalAuth(): boolean; + abstract login(): void; + abstract logout(): Observable; + abstract destroy(): void; + + private catchError = err => { + // TODO: handle the error + }; + + constructor(protected injector: Injector) { + this.oAuthService = injector.get(OAuthService); + this.oAuthConfig = injector.get(CORE_OPTIONS).environment.oAuthConfig; + } + + async init(): Promise { + this.oAuthService.configure(this.oAuthConfig); + return this.oAuthService.loadDiscoveryDocument().catch(this.catchError); + } +} + +export class AuthCodeFlowStrategy extends AuthFlowStrategy { + readonly isInternalAuth = false; + + async init() { + return super + .init() + .then(() => this.oAuthService.tryLogin()) + .then(() => this.oAuthService.setupAutomaticSilentRefresh()); + } + + login() { + this.oAuthService.initCodeFlow(); + } + + checkIfInternalAuth() { + this.oAuthService.initCodeFlow(); + return false; + } + + logout() { + this.oAuthService.logOut(); + return of(null); + } + + destroy() {} +} + +export class AuthPasswordFlowStrategy extends AuthFlowStrategy { + readonly isInternalAuth = true; + + login() { + const router = this.injector.get(Router); + router.navigateByUrl('/account/login'); + } + + checkIfInternalAuth() { + return true; + } + + logout() { + const store = this.injector.get(Store); + const rest = this.injector.get(RestService); + + const issuer = store.selectSnapshot(ConfigState.getDeep('environment.oAuthConfig.issuer')); + return rest + .request( + { + method: 'GET', + url: '/api/account/logout', + }, + null, + issuer, + ) + .pipe( + switchMap(() => { + this.oAuthService.logOut(); + return store.dispatch(new GetAppConfiguration()); + }), + ); + } + + destroy() {} +} + +export const AUTH_FLOW_STRATEGY = { + Code(injector: Injector) { + return new AuthCodeFlowStrategy(injector); + }, + Password(injector: Injector) { + return new AuthPasswordFlowStrategy(injector); + }, +}; diff --git a/npm/ng-packs/packages/core/src/lib/strategies/index.ts b/npm/ng-packs/packages/core/src/lib/strategies/index.ts index 2e621e7907..d71f952307 100644 --- a/npm/ng-packs/packages/core/src/lib/strategies/index.ts +++ b/npm/ng-packs/packages/core/src/lib/strategies/index.ts @@ -1,3 +1,4 @@ +export * from './auth-flow.strategy'; export * from './container.strategy'; export * from './content-security.strategy'; export * from './content.strategy'; diff --git a/npm/ng-packs/packages/core/src/lib/tests/initial-utils.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/initial-utils.spec.ts index c81ce081b2..07dfc84d67 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/initial-utils.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/initial-utils.spec.ts @@ -6,8 +6,8 @@ import { of } from 'rxjs'; import { GetAppConfiguration } from '../actions'; import { CORE_OPTIONS } from '../tokens/options.token'; import { checkAccessToken, getInitialData, localeInitializer } from '../utils'; -import * as multiTenancyUtils from '../utils/multi-tenancy-utils'; import * as environmentUtils from '../utils/environment-utils'; +import * as multiTenancyUtils from '../utils/multi-tenancy-utils'; @Component({ selector: 'abp-dummy', @@ -40,6 +40,7 @@ describe('InitialUtils', () => { injectorSpy.mockReturnValueOnce(store); injectorSpy.mockReturnValueOnce({ skipGetAppConfiguration: false }); + injectorSpy.mockReturnValueOnce({ init: () => null }); injectorSpy.mockReturnValueOnce({ hasValidAccessToken: () => false }); dispatchSpy.mockReturnValue(of('test')); diff --git a/npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts b/npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts index a79077b89d..36e2c22bca 100644 --- a/npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts +++ b/npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts @@ -5,6 +5,7 @@ import { OAuthService } from 'angular-oauth2-oidc'; import { tap } from 'rxjs/operators'; import { GetAppConfiguration } from '../actions/config.actions'; import { ABP } from '../models/common'; +import { AuthService } from '../services/auth.service'; import { ConfigState } from '../states/config.state'; import { CORE_OPTIONS } from '../tokens/options.token'; import { getRemoteEnv } from './environment-utils'; @@ -17,6 +18,7 @@ export function getInitialData(injector: Injector) { await getRemoteEnv(injector, options.environment); await parseTenantFromUrl(injector); + await injector.get(AuthService).init(); if (options.skipGetAppConfiguration) return; diff --git a/npm/ng-packs/packages/identity/src/lib/identity-routing.module.ts b/npm/ng-packs/packages/identity/src/lib/identity-routing.module.ts index f7d5463fcd..27986ae0d7 100644 --- a/npm/ng-packs/packages/identity/src/lib/identity-routing.module.ts +++ b/npm/ng-packs/packages/identity/src/lib/identity-routing.module.ts @@ -2,12 +2,11 @@ import { AuthGuard, DynamicLayoutComponent, PermissionGuard, - CoreModule, - ReplaceableRouteContainerComponent, ReplaceableComponents, + ReplaceableRouteContainerComponent, } from '@abp/ng.core'; -import { NgModule, Type } from '@angular/core'; -import { RouterModule, Routes, Router, ActivatedRoute } from '@angular/router'; +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; import { RolesComponent } from './components/roles/roles.component'; import { UsersComponent } from './components/users/users.component'; import { eIdentityComponents } from './enums/components'; @@ -46,7 +45,7 @@ const routes: Routes = [ ]; @NgModule({ - imports: [RouterModule.forChild(routes), CoreModule], + imports: [RouterModule.forChild(routes)], exports: [RouterModule], }) export class IdentityRoutingModule {} diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.ts b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.ts index 70238d3538..6f362b0ee8 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.ts +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.ts @@ -1,4 +1,4 @@ -import { ApplicationConfiguration, AuthService, ConfigState } from '@abp/ng.core'; +import { ApplicationConfiguration, ConfigState, AuthService } from '@abp/ng.core'; import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { Select } from '@ngxs/store'; diff --git a/npm/ng-packs/packages/theme-shared/package.json b/npm/ng-packs/packages/theme-shared/package.json index 1558f1c824..ee2b5d7ffa 100644 --- a/npm/ng-packs/packages/theme-shared/package.json +++ b/npm/ng-packs/packages/theme-shared/package.json @@ -10,7 +10,7 @@ "@abp/ng.core": "~3.0.5", "@fortawesome/fontawesome-free": "^5.13.1", "@ng-bootstrap/ng-bootstrap": "^6.1.0", - "@ngx-validate/core": "^0.0.10", + "@ngx-validate/core": "^0.0.11", "@swimlane/ngx-datatable": "^17.0.0", "bootstrap": "^4.5.0", "chart.js": "^2.9.3", diff --git a/npm/ng-packs/yarn.lock b/npm/ng-packs/yarn.lock index 56434e11b2..612ce7011d 100644 --- a/npm/ng-packs/yarn.lock +++ b/npm/ng-packs/yarn.lock @@ -715,9 +715,9 @@ js-tokens "^4.0.0" "@babel/parser@^7.1.0", "@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.11.1", "@babel/parser@^7.8.3", "@babel/parser@^7.8.6", "@babel/parser@^7.9.6": - version "7.11.1" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.1.tgz#d91a387990b21e5d20047b336bb19b0553f02ff5" - integrity sha512-u9QMIRdKVF7hfEkb3nu2LgZDIzCQPv+yHD9Eg6ruoJLjkrQ9fFz4IBSlF/9XwoNri9+2F1IY+dYuOfZrXq8t3w== + version "7.11.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.2.tgz#0882ab8a455df3065ea2dcb4c753b2460a24bead" + integrity sha512-Vuj/+7vLo6l1Vi7uuO+1ngCDNeVmNbTngcJFKCR/oEtz8tKz0CJxZEGmPt9KcIloZhOZ3Zit6xbpXT2MDlS9Vw== "@babel/plugin-proposal-async-generator-functions@^7.8.3": version "7.10.5" @@ -1224,9 +1224,9 @@ regenerator-runtime "^0.13.4" "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4": - version "7.11.1" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.1.tgz#087afc57e7bf1073e792fe54f8fb3cfa752f9230" - integrity sha512-nH5y8fLvVl3HAb+ezbgcgwrH8QbClWo8xzkOu7+oyqngo3EVorwpWJQaqXPjGRpfj7mQvsJCl/S8knkfkPWqrw== + version "7.11.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736" + integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw== dependencies: regenerator-runtime "^0.13.4" @@ -2736,9 +2736,9 @@ integrity sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g== "@types/node@^12.11.1": - version "12.12.53" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.53.tgz#be0d375933c3d15ef2380dafb3b0350ea7021129" - integrity sha512-51MYTDTyCziHb70wtGNFRwB4l+5JNvdqzFSkbDvpbftEgVUBEE+T5f7pROhWMp/fxp07oNIEQZd5bbfAH22ohQ== + version "12.12.54" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.54.tgz#a4b58d8df3a4677b6c08bfbc94b7ad7a7a5f82d1" + integrity sha512-ge4xZ3vSBornVYlDnk7yZ0gK6ChHf/CHB7Gl1I0Jhah8DDnEQqBzgohYG4FX4p81TNirSETOiSyn+y1r9/IR6w== "@types/node@^8.0.31": version "8.10.62" @@ -2814,9 +2814,9 @@ integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw== "@types/yargs@^13.0.0": - version "13.0.9" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.9.tgz#44028e974343c7afcf3960f1a2b1099c39a7b5e1" - integrity sha512-xrvhZ4DZewMDhoH1utLtOAwYQy60eYFoXeje30TzM3VOvQlBwQaEpKFq5m34k1wOw2AKIi2pwtiAjdmhvlBUzg== + version "13.0.10" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.10.tgz#e77bf3fc73c781d48c2eb541f87c453e321e5f4b" + integrity sha512-MU10TSgzNABgdzKvQVW1nuuT+sgBMWeXNc3XOs5YXV5SDAK+PPja2eUuBNB9iqElu03xyEDqlnGw0jgl4nbqGQ== dependencies: "@types/yargs-parser" "*" @@ -3120,6 +3120,13 @@ alphanum-sort@^1.0.0: resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= +angular-oauth2-oidc@^10.0.3: + version "10.0.3" + resolved "https://registry.yarnpkg.com/angular-oauth2-oidc/-/angular-oauth2-oidc-10.0.3.tgz#612ef75c2e07b56592d2506f9618ee6a61857ad9" + integrity sha512-9wC8I3e3cN6rMBOlo5JB2y3Fd2erp8pJ67t4vEVzyPbnRG6BJ4rreSOznSL9zw/2SjhC9kRV2OfFie29CUCzEg== + dependencies: + tslib "^2.0.0" + angular-oauth2-oidc@^9.2.2: version "9.2.2" resolved "https://registry.yarnpkg.com/angular-oauth2-oidc/-/angular-oauth2-oidc-9.2.2.tgz#2b888337953a8773e0269b5ef1709f30316448f1" @@ -3678,9 +3685,9 @@ boolbase@^1.0.0, boolbase@~1.0.0: integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= bootstrap@^4.5.0: - version "4.5.1" - resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.5.1.tgz#f7322c7dd3e6376d430efc0c3f57e4d8005eb5b2" - integrity sha512-bxUooHBSbvefnIZfjD0LE8nfdPKrtiFy2sgrxQwUZ0UpFzpjVbVMUxaGIoo9XWT4B2LG1HX6UQg0UMOakT0prQ== + version "4.5.2" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.5.2.tgz#a85c4eda59155f0d71186b6e6ad9b875813779ab" + integrity sha512-vlGn0bcySYl/iV+BGA544JkkZP5LB3jsmkeKLFQakCOwCM3AOk7VkldBz4jrzSe+Z0Ezn99NVXa1o45cQY4R6A== boxen@^4.2.0: version "4.2.0" @@ -3806,14 +3813,14 @@ browserify-zlib@^0.2.0: pako "~1.0.5" browserslist@^4.0.0, browserslist@^4.11.1, browserslist@^4.12.0, browserslist@^4.7.0, browserslist@^4.8.5, browserslist@^4.9.1: - version "4.13.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.13.0.tgz#42556cba011e1b0a2775b611cba6a8eca18e940d" - integrity sha512-MINatJ5ZNrLnQ6blGvePd/QOz9Xtu+Ne+x29iQSCHfkU5BugKVJwZKn/iiL8UbpIpa3JhviKjz+XxMo0m2caFQ== + version "4.14.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.0.tgz#2908951abfe4ec98737b72f34c3bcedc8d43b000" + integrity sha512-pUsXKAF2lVwhmtpeA3LJrZ76jXuusrNyhduuQs7CDFf9foT4Y38aQOserd2lMe5DSSrjf3fx34oHwryuvxAUgQ== dependencies: - caniuse-lite "^1.0.30001093" - electron-to-chromium "^1.3.488" - escalade "^3.0.1" - node-releases "^1.1.58" + caniuse-lite "^1.0.30001111" + electron-to-chromium "^1.3.523" + escalade "^3.0.2" + node-releases "^1.1.60" browserstack@^1.5.1: version "1.6.0" @@ -4095,10 +4102,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001032, caniuse-lite@^1.0.30001061, caniuse-lite@^1.0.30001093, caniuse-lite@^1.0.30001109: - version "1.0.30001111" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001111.tgz#dd0ce822c70eb6c7c068e4a55c22e19ec1501298" - integrity sha512-xnDje2wchd/8mlJu8sXvWxOGvMgv+uT3iZ3bkIAynKOzToCssWCmkz/ZIkQBs/2pUB4uwnJKVORWQ31UkbVjOg== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001032, caniuse-lite@^1.0.30001061, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001111: + version "1.0.30001112" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001112.tgz#0fffc3b934ff56ff0548c37bc9dad7d882bcf672" + integrity sha512-J05RTQlqsatidif/38aN3PGULCLrg8OYQOlJUKbeYVzC2mGZkZLIztwRlB3MtrfLmawUmjFlNJvy/uhwniIe1Q== canonical-path@1.0.0: version "1.0.0" @@ -4182,9 +4189,9 @@ chartjs-color@^2.1.0: color-convert "^1.9.3" "chokidar@>=2.0.0 <4.0.0", chokidar@^3.0.0, chokidar@^3.0.2, chokidar@^3.2.1, chokidar@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.1.tgz#e905bdecf10eaa0a0b1db0c664481cc4cbc22ba1" - integrity sha512-TQTJyr2stihpC4Sya9hs2Xh+O2wf+igjL36Y75xx2WdHuiICcn/XJza46Jwt0eT5hVpQOzo3FpY3cj3RVYLX0g== + version "3.4.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.2.tgz#38dc8e658dec3809741eb3ef7bb0a47fe424232d" + integrity sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A== dependencies: anymatch "~3.1.1" braces "~3.0.2" @@ -5675,10 +5682,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.3.488: - version "1.3.520" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.520.tgz#dfda0a14a4aed785cbddfdb505ea122f75978392" - integrity sha512-q6H9E1sXDCjRHP+X06vcP+N0ki8ZvYoRPZfKnDuiRX10WWXxEHzKFVf4O9rBFMpuPtR3M+2KAdJnugJoBBp3Rw== +electron-to-chromium@^1.3.523: + version "1.3.524" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.524.tgz#dd49646594466192de35956a5369bb20d616aa78" + integrity sha512-ZUvklIBkfXQyA6IeiEss1nfKRICcdB5afAGZAaPGaExdfrkpUu/WWVO+X7QpNnphaVMllXnAcvKnVPdyM+DCPQ== elliptic@^6.5.3: version "6.5.3" @@ -5848,7 +5855,7 @@ es6-symbol@^3.1.1, es6-symbol@~3.1.3: d "^1.0.1" ext "^1.1.2" -escalade@^3.0.1: +escalade@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.2.tgz#6a580d70edb87880f22b4c91d0d56078df6962c4" integrity sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ== @@ -9565,7 +9572,7 @@ node-notifier@^6.0.0: shellwords "^0.1.1" which "^1.3.1" -node-releases@^1.1.58: +node-releases@^1.1.60: version "1.1.60" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.60.tgz#6948bdfce8286f0b5d0e5a88e8384e954dfe7084" integrity sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA== @@ -13092,16 +13099,16 @@ ts-pnp@^1.1.6: integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== ts-toolbelt@^6.9.9: - version "6.14.0" - resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-6.14.0.tgz#6f1082c5f59b39ff5d71ff427207bb92ffca4534" - integrity sha512-/EihMSk7AQn1n1zad6765tZNr7OCxAP75nS/VGzcZlWLlDa2izLJZV7SJSNDweSKusKuTDyHZhKFyUZW6UUnqg== + version "6.15.0" + resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-6.15.0.tgz#e1806c4904f5dc819d8dd2c48e09ccc60bfb742f" + integrity sha512-WuXbnXmVgzAGdruH7jbYf4j/0Y4anfMOD0KUU8iw6/4SbzdQVpfso4BJ1Z/t7hKLN2++gWYIseaw/ciyWKLreQ== tsickle@^0.38.1: version "0.38.1" resolved "https://registry.yarnpkg.com/tsickle/-/tsickle-0.38.1.tgz#30762db759d40c435943093b6972c7f2efb384ef" integrity sha512-4xZfvC6+etRu6ivKCNqMOd1FqcY/m6JY3Y+yr5+Xw+i751ciwrWINi6x/3l1ekcODH9GZhlf0ny2LpzWxnjWYA== -tslib@2.0.0, tslib@^2.0.0: +tslib@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.0.tgz#18d13fc2dce04051e20f074cc8387fd8089ce4f3" integrity sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g== @@ -13111,6 +13118,11 @@ tslib@^1.10.0, tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== +tslib@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.1.tgz#410eb0d113e5b6356490eec749603725b021b43e" + integrity sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ== + tslint@~6.1.0: version "6.1.3" resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.1.3.tgz#5c23b2eccc32487d5523bd3a470e9aa31789d904" diff --git a/templates/app/angular/src/app/home/home.component.html b/templates/app/angular/src/app/home/home.component.html index f4d41daf4f..fc7a0a4183 100644 --- a/templates/app/angular/src/app/home/home.component.html +++ b/templates/app/angular/src/app/home/home.component.html @@ -8,13 +8,7 @@ abp.io - {{ 'AbpAccount::Login' | abpLocalization }} diff --git a/templates/app/angular/src/app/home/home.component.ts b/templates/app/angular/src/app/home/home.component.ts index a42b960493..3790f8fe3f 100644 --- a/templates/app/angular/src/app/home/home.component.ts +++ b/templates/app/angular/src/app/home/home.component.ts @@ -1,3 +1,4 @@ +import { AuthService } from '@abp/ng.core'; import { Component } from '@angular/core'; import { OAuthService } from 'angular-oauth2-oidc'; @@ -10,5 +11,9 @@ export class HomeComponent { return this.oAuthService.hasValidAccessToken(); } - constructor(private oAuthService: OAuthService) {} + constructor(private oAuthService: OAuthService, private authService: AuthService) {} + + login() { + this.authService.initLogin(); + } } diff --git a/templates/app/angular/src/environments/environment.prod.ts b/templates/app/angular/src/environments/environment.prod.ts index cfe0401dee..719dd1fe53 100644 --- a/templates/app/angular/src/environments/environment.prod.ts +++ b/templates/app/angular/src/environments/environment.prod.ts @@ -1,26 +1,24 @@ import { Config } from '@abp/ng.core'; +const baseUrl = 'http://localhost:4200'; + export const environment = { production: true, application: { - baseUrl: 'http://localhost:4200/', + baseUrl, name: 'MyProjectName', logoUrl: '', }, oAuthConfig: { issuer: 'https://localhost:44305', + redirectUri: baseUrl, clientId: 'MyProjectName_App', - dummyClientSecret: '1q2w3e*', - scope: 'MyProjectName', - oidc: false, - requireHttps: true, + responseType: 'code', + scope: 'offline_access MyProjectName', }, apis: { default: { url: 'https://localhost:44305', }, }, - localization: { - defaultResourceName: 'MyProjectName', - }, } as Config.Environment; diff --git a/templates/app/angular/src/environments/environment.ts b/templates/app/angular/src/environments/environment.ts index 2039e8a2dc..cb0be073c2 100644 --- a/templates/app/angular/src/environments/environment.ts +++ b/templates/app/angular/src/environments/environment.ts @@ -1,27 +1,24 @@ import { Config } from '@abp/ng.core'; +const baseUrl = 'http://localhost:4200'; + export const environment = { production: false, application: { - baseUrl: 'http://localhost:4200/', + baseUrl, name: 'MyProjectName', logoUrl: '', }, oAuthConfig: { issuer: 'https://localhost:44305', + redirectUri: baseUrl, clientId: 'MyProjectName_App', - dummyClientSecret: '1q2w3e*', - scope: 'MyProjectName', - showDebugInformation: true, - oidc: false, - requireHttps: true, + responseType: 'code', + scope: 'offline_access MyProjectName', }, apis: { default: { url: 'https://localhost:44305', }, }, - localization: { - defaultResourceName: 'MyProjectName', - }, } as Config.Environment;