fix(console): auth response interceptor, new assets, async route guard, pipe modules cleanup, disable custom idp editation for orgs, refresh list on idp creation (#793)

* chore(deps-dev): bump @angular/cli from 10.0.8 to 10.1.3 in /console (#785)

Bumps [@angular/cli](https://github.com/angular/angular-cli) from 10.0.8 to 10.1.3.
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Commits](https://github.com/angular/angular-cli/compare/v10.0.8...v10.1.3)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps-dev): bump @angular-devkit/build-angular in /console (#784)

Bumps [@angular-devkit/build-angular](https://github.com/angular/angular-cli) from 0.1000.8 to 0.1001.3.
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Commits](https://github.com/angular/angular-cli/commits)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Max Peintner <max@caos.ch>

* chore(deps-dev): bump @angular/language-service in /console (#783)

Bumps [@angular/language-service](https://github.com/angular/angular/tree/HEAD/packages/language-service) from 10.1.0 to 10.1.3.
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/master/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/10.1.3/packages/language-service)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps-dev): bump stylelint from 13.7.1 to 13.7.2 in /console (#782)

Bumps [stylelint](https://github.com/stylelint/stylelint) from 13.7.1 to 13.7.2.
- [Release notes](https://github.com/stylelint/stylelint/releases)
- [Changelog](https://github.com/stylelint/stylelint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stylelint/stylelint/compare/13.7.1...13.7.2)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps-dev): bump karma from 5.2.1 to 5.2.3 in /console (#781)

Bumps [karma](https://github.com/karma-runner/karma) from 5.2.1 to 5.2.3.
- [Release notes](https://github.com/karma-runner/karma/releases)
- [Changelog](https://github.com/karma-runner/karma/blob/master/CHANGELOG.md)
- [Commits](https://github.com/karma-runner/karma/compare/v5.2.1...v5.2.3)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump moment from 2.27.0 to 2.29.0 in /console (#780)

Bumps [moment](https://github.com/moment/moment) from 2.27.0 to 2.29.0.
- [Release notes](https://github.com/moment/moment/releases)
- [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/moment/moment/compare/2.27.0...2.29.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps-dev): bump @types/node from 14.6.4 to 14.11.2 in /console (#778)

Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.6.4 to 14.11.2.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps-dev): bump prettier from 2.1.1 to 2.1.2 in /console (#757)

Bumps [prettier](https://github.com/prettier/prettier) from 2.1.1 to 2.1.2.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/2.1.1...2.1.2)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump ts-protoc-gen from 0.12.0 to 0.13.0 in /console (#737)

Bumps [ts-protoc-gen](https://github.com/improbable-eng/ts-protoc-gen) from 0.12.0 to 0.13.0.
- [Release notes](https://github.com/improbable-eng/ts-protoc-gen/releases)
- [Changelog](https://github.com/improbable-eng/ts-protoc-gen/blob/master/CHANGELOG.md)
- [Commits](https://github.com/improbable-eng/ts-protoc-gen/compare/0.12.0...0.13.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps-dev): bump jasmine-spec-reporter in /console (#762)

Bumps [jasmine-spec-reporter](https://github.com/bcaudan/jasmine-spec-reporter) from 5.0.2 to 6.0.0.
- [Release notes](https://github.com/bcaudan/jasmine-spec-reporter/releases)
- [Changelog](https://github.com/bcaudan/jasmine-spec-reporter/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bcaudan/jasmine-spec-reporter/compare/v5.0.2...v6.0.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Max Peintner <max@caos.ch>

* fix: package

* change html lang to translation lang

* disable detail view org idp

* catch errorcode 16 in auth response interceptor

* new icons

* refactor pipes, idp table config

* fix router guard

* lint

* allowed commonjs deps

* Update console/src/assets/i18n/en.json

Co-authored-by: Florian Forster <florian@caos.ch>

* Update console/src/assets/i18n/de.json

Co-authored-by: Florian Forster <florian@caos.ch>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Florian Forster <florian@caos.ch>
This commit is contained in:
Max Peintner
2020-09-29 13:21:40 +02:00
committed by GitHub
parent 83b0ac1fdb
commit dd1ccefd29
59 changed files with 646 additions and 449 deletions

View File

@@ -1,12 +1,12 @@
import { BreakpointObserver } from '@angular/cdk/layout';
import { OverlayContainer } from '@angular/cdk/overlay';
import { ViewportScroller } from '@angular/common';
import { DOCUMENT, ViewportScroller } from '@angular/common';
import { Component, HostBinding, Inject, OnDestroy, ViewChild } from '@angular/core';
import { MatIconRegistry } from '@angular/material/icon';
import { MatDrawer } from '@angular/material/sidenav';
import { DomSanitizer } from '@angular/platform-browser';
import { Router, RouterOutlet } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { LangChangeEvent, TranslateService } from '@ngx-translate/core';
import { Observable, of, Subscription } from 'rxjs';
import { map } from 'rxjs/operators';
@@ -70,6 +70,7 @@ export class AppComponent implements OnDestroy {
private toast: ToastService,
private router: Router,
update: UpdateService,
@Inject(DOCUMENT) private document: Document,
) {
console.log('%cWait!', 'text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; color: #5282c1; font-size: 50px');
console.log('%cInserting something here could give attackers access to your zitadel account.', 'color: red; font-size: 18px');
@@ -160,6 +161,10 @@ export class AppComponent implements OnDestroy {
this.isDarkTheme = this.themeService.isDarkTheme;
this.isDarkTheme.subscribe(thema => this.onSetTheme(thema ? 'dark-theme' : 'light-theme'));
this.translate.onLangChange.subscribe((language: LangChangeEvent) => {
this.document.documentElement.lang = language.lang;
});
}
public ngOnDestroy(): void {
@@ -202,6 +207,8 @@ export class AppComponent implements OnDestroy {
this.profile = userprofile;
const lang = userprofile.preferredLanguage.match(/en|de/) ? userprofile.preferredLanguage : 'en';
this.translate.use(lang);
console.log(this.document.documentElement.lang);
this.document.documentElement.lang = lang;
});
}

View File

@@ -21,7 +21,7 @@ import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { AuthConfig, OAuthModule, OAuthStorage } from 'angular-oauth2-oidc';
import { QuicklinkModule } from 'ngx-quicklink';
import { RegExpPipeModule } from 'src/app/pipes/regexp-pipe.module';
import { RegExpPipeModule } from 'src/app/pipes/regexp-pipe/regexp-pipe.module';
import { environment } from '../environments/environment';
import { AppRoutingModule } from './app-routing.module';
@@ -32,7 +32,7 @@ import { AccountsCardModule } from './modules/accounts-card/accounts-card.module
import { AvatarModule } from './modules/avatar/avatar.module';
import { WarnDialogModule } from './modules/warn-dialog/warn-dialog.module';
import { SignedoutComponent } from './pages/signedout/signedout.component';
import { HasRolePipeModule } from './pipes/has-role-pipe.module';
import { HasRolePipeModule } from './pipes/has-role-pipe/has-role-pipe.module';
import { GrpcAuthService } from './services/grpc-auth.service';
import { GrpcService } from './services/grpc.service';
import { AuthInterceptor } from './services/interceptors/auth.interceptor';

View File

@@ -1,6 +1,7 @@
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { filter, first, switchMap } from 'rxjs/operators';
import { GrpcAuthService } from '../services/grpc-auth.service';
@@ -15,6 +16,11 @@ export class RoleGuard implements CanActivate {
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
): Observable<boolean> {
return this.authService.isAllowed(route.data['roles']);
return this.authService.fetchedZitadelPermissions.pipe(
filter((permissionsFetched) => !!permissionsFetched),
first(),
).pipe(
switchMap(_ => this.authService.isAllowed(route.data['roles'])),
);
}
}

View File

@@ -4,9 +4,9 @@ import { NgModule } from '@angular/core';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { TranslateModule } from '@ngx-translate/core';
import { ScrollableModule } from 'src/app/directives/scrollable/scrollable.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
import { ChangesComponent } from './changes.component';

View File

@@ -1,20 +1,23 @@
<app-refresh-table [loading]="loading$ | async" (refreshed)="refreshPage()" [dataSize]="dataSource.data.length"
[timestamp]="idpResult?.viewTimestamp" [selection]="selection">
emitRefreshOnPreviousRoute="/iam/idp/create" [timestamp]="idpResult?.viewTimestamp" [selection]="selection">
<ng-template appHasRole [appHasRole]="['iam.write']" actions>
<button (click)="deactivateSelectedIdps()" matTooltip="{{'IDP.DEACTIVATE' | translate}}" class="icon-button"
mat-icon-button *ngIf="selection.hasValue() && serviceType!=PolicyComponentServiceType.MGMT" [disabled]="disabled">
mat-icon-button *ngIf="selection.hasValue() && serviceType!=PolicyComponentServiceType.MGMT"
[disabled]="disabled">
<mat-icon svgIcon="mdi_account_cancel"></mat-icon>
</button>
<button (click)="reactivateSelectedIdps()" matTooltip="{{'IDP.ACTIVATE' | translate}}" class="icon-button"
mat-icon-button *ngIf="selection.hasValue() && serviceType!=PolicyComponentServiceType.MGMT" [disabled]="disabled">
mat-icon-button *ngIf="selection.hasValue() && serviceType!=PolicyComponentServiceType.MGMT"
[disabled]="disabled">
<mat-icon svgIcon="mdi_account_check_outline"></mat-icon>
</button>
<button color="warn" (click)="removeSelectedIdps()" matTooltip="{{'IDP.DELETE' | translate}}"
class="icon-button" mat-icon-button *ngIf="selection.hasValue() && serviceType!=PolicyComponentServiceType.MGMT" [disabled]="disabled">
class="icon-button" mat-icon-button
*ngIf="selection.hasValue() && serviceType!=PolicyComponentServiceType.MGMT" [disabled]="disabled">
<i class="las la-trash"></i>
</button>
<a class="add-button" [routerLink]="createRouterLink" color="primary" mat-raised-button [disabled]="disabled"
*ngIf="serviceType!=PolicyComponentServiceType.MGMT">
*ngIf="serviceType!=PolicyComponentServiceType.MGMT">
<mat-icon class="icon">add</mat-icon>{{ 'ACTIONS.NEW' | translate }}
</a>
</ng-template>
@@ -74,13 +77,22 @@
{{idp.changeDate | timestampToDate | localizedDate: 'dd. MMM, HH:mm' }} </td>
</ng-container>
<ng-container matColumnDef="type">
<th mat-header-cell *matHeaderCellDef> {{ 'IDP.TYPE' | translate }} </th>
<td class="pointer" mat-cell *matCellDef="let idp">
{{'IDP.TYPES.'+idp.providerType | translate }} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr class="data-row" mat-row *matRowDef="let row; columns: displayedColumns;"
[routerLink]="row.id ? [serviceType == PolicyComponentServiceType.ADMIN ? '/iam' : '/org', 'idp', row.id ]: null">
<tr class="data-row"
[ngClass]="{'disabled': serviceType==PolicyComponentServiceType.MGMT && row?.providerType == IdpProviderType.IDPPROVIDERTYPE_SYSTEM}"
mat-row *matRowDef="let row; columns: displayedColumns;"
[routerLink]="serviceType==PolicyComponentServiceType.ADMIN ? routerLinkForRow(row): null">
</tr>
</table>
<mat-paginator #paginator class="paginator" [length]="idpResult?.totalResult || 0" [pageSize]="10"
[pageSizeOptions]="[5, 10, 20]" (page)="changePage($event)"></mat-paginator>
</div>
</app-refresh-table>
</app-refresh-table>

View File

@@ -32,6 +32,10 @@
tr {
outline: none;
&.disabled * {
color: #8795a1;
}
}
.add-button {
@@ -57,14 +61,22 @@ tr {
.flex-row {
display: flex;
justify-content: space-between;
padding: 2px 0;
width: 250px;
.key {
margin-right: 1rem;
font-size: 14px;
margin-right: .5rem;
font-size: 12px;
flex: 1 0 50%;
overflow: hidden;
text-overflow: ellipsis;
}
.value {
font-size: 14px;
font-size: 12px;
flex: 1 0 50%;
overflow: hidden;
text-overflow: ellipsis;
}
&:first-child {

View File

@@ -6,7 +6,7 @@ import { RouterLink } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { IdpSearchResponse as AdminIdpSearchResponse, IdpView as AdminIdpView } from 'src/app/proto/generated/admin_pb';
import { IdpView as MgmtIdpView } from 'src/app/proto/generated/management_pb';
import { IdpProviderType, IdpView as MgmtIdpView } from 'src/app/proto/generated/management_pb';
import { AdminService } from 'src/app/services/admin.service';
import { ManagementService } from 'src/app/services/mgmt.service';
import { ToastService } from 'src/app/services/toast.service';
@@ -31,6 +31,7 @@ export class IdpTableComponent implements OnInit {
private loadingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
public loading$: Observable<boolean> = this.loadingSubject.asObservable();
public PolicyComponentServiceType: any = PolicyComponentServiceType;
public IdpProviderType: any = IdpProviderType;
@Input() public displayedColumns: string[] = ['select', 'name', 'config', 'creationDate', 'changeDate', 'state'];
@Output() public changedSelection: EventEmitter<Array<AdminIdpView.AsObject | MgmtIdpView.AsObject>>
@@ -44,6 +45,9 @@ export class IdpTableComponent implements OnInit {
ngOnInit(): void {
this.getData(10, 0);
if (this.serviceType === PolicyComponentServiceType.MGMT) {
this.displayedColumns = ['select', 'name', 'config', 'creationDate', 'changeDate', 'state', 'type'];
}
}
public isAllSelected(): boolean {
@@ -96,9 +100,10 @@ export class IdpTableComponent implements OnInit {
// let query: AdminIdpSearchQuery | MgmtIdpSearchQuery;
// if (this.service instanceof AdminService) {
// query = new AdminIdpSearchQuery();
// query.setKey(AdminIdpSearchKey.)
// query.setKey(AdminIdpSearchKey.IDPSEARCHKEY_IDP_CONFIG_ID);
// } else if (this.service instanceof ManagementService) {
// return ['/org', 'idp', 'create'];
// query = new MgmtIdpSearchQuery();
// query.setKey(MgmtIdpSearchKey.IDPSEARCHKEY_PROVIDER_TYPE);
// }
this.service.SearchIdps(limit, offset).then(resp => {
@@ -123,4 +128,15 @@ export class IdpTableComponent implements OnInit {
return ['/org', 'idp', 'create'];
}
}
public routerLinkForRow(row: MgmtIdpView.AsObject | AdminIdpView.AsObject): any {
if (row.id) {
switch (this.serviceType) {
case PolicyComponentServiceType.MGMT:
return ['/org', 'idp', row.id];
case PolicyComponentServiceType.ADMIN:
return ['/iam', 'idp', row.id];
}
}
}
}

View File

@@ -11,8 +11,9 @@ import { RouterModule } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
import { TruncatePipeModule } from 'src/app/pipes/truncate-pipe/truncate-pipe.module';
import { IdpTableComponent } from './idp-table.component';
@@ -34,6 +35,7 @@ import { IdpTableComponent } from './idp-table.component';
RouterModule,
RefreshTableModule,
HasRoleModule,
TruncatePipeModule,
],
exports: [
IdpTableComponent,

View File

@@ -1,5 +1,5 @@
<app-detail-layout [backRouterLink]="backroutes" [title]="'ORG.POLICY.LOGIN_POLICY.TITLECREATE' | translate"
[description]="'ORG.POLICY.LOGIN_POLICY.DESCRIPTIONCREATE' | translate">
[description]="serviceType==PolicyComponentServiceType.MGMT ? 'ORG.POLICY.LOGIN_POLICY.DESCRIPTIONCREATEMGMT' : PolicyComponentServiceType.ADMIN ? 'ORG.POLICY.LOGIN_POLICY.DESCRIPTIONCREATEADMIN' : '' | translate">
<ng-container *ngIf="(['policy.delete'] | hasRole | async) && serviceType == PolicyComponentServiceType.MGMT">
<!--<button matTooltip="{{'ORG.POLICY.DELETE' | translate}}" color="warn" (click)="deletePolicy()"
mat-stroked-button>
@@ -19,14 +19,14 @@
<span class="left-desc">{{'ORG.POLICY.DATA.ALLOWREGISTER' | translate}}</span>
<span class="fill-space"></span>
<mat-slide-toggle color="primary" name="hasNumber" ngDefaultControl [(ngModel)]="loginData.allowRegister"
[disabled]="serviceType==PolicyComponentServiceType.MGMT">
[disabled]="serviceType==PolicyComponentServiceType.MGMT">
</mat-slide-toggle>
</div>
<div class="row">
<span class="left-desc">{{'ORG.POLICY.DATA.ALLOWEXTERNALIDP' | translate}}</span>
<span class="fill-space"></span>
<mat-slide-toggle color="primary" name="hasNumber" ngDefaultControl [disabled]="serviceType==PolicyComponentServiceType.MGMT"
[(ngModel)]="loginData.allowExternalIdp">
<mat-slide-toggle color="primary" name="hasNumber" ngDefaultControl
[disabled]="serviceType==PolicyComponentServiceType.MGMT" [(ngModel)]="loginData.allowExternalIdp">
</mat-slide-toggle>
</div>
</div>
@@ -35,7 +35,8 @@
<div class="idps">
<div class="idp" *ngFor="let idp of idps">
<mat-icon *ngIf="serviceType!=PolicyComponentServiceType.MGMT" (click)="removeIdp(idp)" class="rm">remove_circle</mat-icon>
<mat-icon *ngIf="serviceType!=PolicyComponentServiceType.MGMT" (click)="removeIdp(idp)" class="rm">
remove_circle</mat-icon>
<span>{{idp.name}}</span>
<span class="meta">{{ 'IDP.TYPE' | translate }}: {{ 'IDP.TYPES.'+idp.type | translate }}</span>
<span class="meta">{{ 'IDP.ID' | translate }}: {{idp.idpConfigId}}</span>
@@ -46,16 +47,17 @@
</div>
<div class="btn-container">
<button (click)="savePolicy()" color="primary" type="submit" [disabled]="serviceType==PolicyComponentServiceType.MGMT"
<button (click)="savePolicy()" color="primary" type="submit"
[disabled]="serviceType==PolicyComponentServiceType.MGMT"
mat-raised-button>{{ 'ACTIONS.SAVE' | translate }}</button>
</div>
<ng-template appHasRole [appHasRole]="['org.idp.read']">
<app-card title="{{ 'IDP.LIST.TITLE' | translate }}" description="{{ 'IDP.LIST.DESCRIPTION' | translate }}">
<app-idp-table [service]="service" [serviceType]="serviceType"
[disabled]="(['iam.idp.write'] | hasRole | async) == false">
</app-idp-table>
</app-card>
<app-card title="{{ 'IDP.LIST.TITLE' | translate }}" description="{{ 'IDP.LIST.DESCRIPTION' | translate }}">
<app-idp-table [service]="service" [serviceType]="serviceType"
[disabled]="(['iam.idp.write'] | hasRole | async) == false">
</app-idp-table>
</app-card>
</ng-template>
</app-detail-layout>
</app-detail-layout>

View File

@@ -2,21 +2,21 @@ import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { CardModule } from 'src/app/modules/card/card.module';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { MatTooltipModule } from '@angular/material/tooltip';
import { TranslateModule } from '@ngx-translate/core';
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { CardModule } from 'src/app/modules/card/card.module';
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
import { IdpTableModule } from 'src/app/modules/idp-table/idp-table.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
import { AddIdpDialogModule } from './add-idp-dialog/add-idp-dialog.module';
import { LoginPolicyRoutingModule } from './login-policy-routing.module';
import { LoginPolicyComponent } from './login-policy.component';
import { IdpTableModule } from 'src/app/modules/idp-table/idp-table.module';
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
@NgModule({
declarations: [LoginPolicyComponent],

View File

@@ -17,7 +17,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
import { TranslateModule } from '@ngx-translate/core';
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
import { RefreshTableModule } from '../refresh-table/refresh-table.module';
import { ProjectMembersRoutingModule } from './project-members-routing.module';

View File

@@ -15,9 +15,9 @@ import { MatTooltipModule } from '@angular/material/tooltip';
import { RouterModule } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
import { RefreshTableModule } from '../refresh-table/refresh-table.module';
import { ProjectRoleDetailComponent } from './project-role-detail/project-role-detail.component';

View File

@@ -6,13 +6,12 @@ import { MatIconModule } from '@angular/material/icon';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatTooltipModule } from '@angular/material/tooltip';
import { TranslateModule } from '@ngx-translate/core';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
import { RefreshTableComponent } from './refresh-table.component';
@NgModule({
declarations: [RefreshTableComponent],
imports: [

View File

@@ -13,9 +13,9 @@ import { MatTooltipModule } from '@angular/material/tooltip';
import { RouterModule } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
import { AvatarModule } from '../avatar/avatar.module';
import { RefreshTableModule } from '../refresh-table/refresh-table.module';

View File

@@ -17,7 +17,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
import { IamMembersRoutingModule } from './iam-members-routing.module';
import { IamMembersComponent } from './iam-members.component';

View File

@@ -24,22 +24,27 @@ const routes: Routes = [
},
},
{
path: 'idp/create',
loadChildren: () => import('src/app/modules/idp-create/idp-create.module').then(m => m.IdpCreateModule),
canActivate: [AuthGuard, RoleGuard],
data: {
roles: ['iam.idp.write'],
serviceType: PolicyComponentServiceType.ADMIN,
},
},
{
path: 'idp/:id',
loadChildren: () => import('src/app/modules/idp/idp.module').then(m => m.IdpModule),
canActivate: [AuthGuard, RoleGuard],
data: {
roles: ['iam.idp.read'],
serviceType: PolicyComponentServiceType.ADMIN,
},
path: 'idp',
children: [
{
path: 'create',
loadChildren: () => import('src/app/modules/idp-create/idp-create.module').then(m => m.IdpCreateModule),
canActivate: [AuthGuard, RoleGuard],
data: {
roles: ['iam.idp.write'],
serviceType: PolicyComponentServiceType.ADMIN,
},
},
{
path: ':id',
loadChildren: () => import('src/app/modules/idp/idp.module').then(m => m.IdpModule),
canActivate: [AuthGuard, RoleGuard],
data: {
roles: ['iam.idp.read'],
serviceType: PolicyComponentServiceType.ADMIN,
},
},
],
},
{
path: `policy/${PolicyComponentType.LOGIN}`,

View File

@@ -22,9 +22,9 @@ import { ContributorsModule } from 'src/app/modules/contributors/contributors.mo
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module';
import { SharedModule } from 'src/app/modules/shared/shared.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
import { FailedEventsComponent } from './failed-events/failed-events.component';
import { IamPolicyGridComponent } from './iam-policy-grid/iam-policy-grid.component';

View File

@@ -11,7 +11,7 @@ import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { TranslateModule } from '@ngx-translate/core';
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { PasswordComplexityViewModule } from 'src/app/modules/password-complexity-view/password-complexity-view.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
import { OrgCreateRoutingModule } from './org-create-routing.module';
import { OrgCreateComponent } from './org-create.component';

View File

@@ -17,7 +17,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
import { OrgMembersRoutingModule } from './org-members-routing.module';
import { OrgMembersComponent } from './org-members.component';

View File

@@ -39,7 +39,6 @@ const routes: Routes = [
},
],
},
{
path: 'policy',
children: [

View File

@@ -19,7 +19,7 @@ import { ContributorsModule } from 'src/app/modules/contributors/contributors.mo
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
import { SharedModule } from 'src/app/modules/shared/shared.module';
import { WarnDialogModule } from 'src/app/modules/warn-dialog/warn-dialog.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
import { ChangesModule } from '../../modules/changes/changes.module';
import { AddDomainDialogModule } from './org-detail/add-domain-dialog/add-domain-dialog.module';

View File

@@ -25,9 +25,9 @@ import { ProjectRolesModule } from 'src/app/modules/project-roles/project-roles.
import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module';
import { SharedModule } from 'src/app/modules/shared/shared.module';
import { UserGrantsModule } from 'src/app/modules/user-grants/user-grants.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
import { GrantedProjectDetailComponent } from './granted-project-detail/granted-project-detail.component';
import { GrantedProjectGridComponent } from './granted-project-list/granted-project-grid/granted-project-grid.component';

View File

@@ -24,9 +24,9 @@ import { ProjectRolesModule } from 'src/app/modules/project-roles/project-roles.
import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module';
import { UserGrantsModule } from 'src/app/modules/user-grants/user-grants.module';
import { WarnDialogModule } from 'src/app/modules/warn-dialog/warn-dialog.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
import { ApplicationGridComponent } from './application-grid/application-grid.component';
import { ApplicationsComponent } from './applications/applications.component';

View File

@@ -20,9 +20,9 @@ import { CardModule } from 'src/app/modules/card/card.module';
import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module';
import { SharedModule } from 'src/app/modules/shared/shared.module';
import { UserGrantsModule } from 'src/app/modules/user-grants/user-grants.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
import { OwnedProjectGridComponent } from './owned-project-list/owned-project-grid/owned-project-grid.component';
import { OwnedProjectListComponent } from './owned-project-list/owned-project-list.component';

View File

@@ -15,7 +15,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
import { TranslateModule } from '@ngx-translate/core';
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
import { ProjectGrantDetailRoutingModule } from './project-grant-detail-routing.module';
import { ProjectGrantDetailComponent } from './project-grant-detail.component';

View File

@@ -18,7 +18,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module';
import { SearchUserAutocompleteModule } from 'src/app/modules/search-user-autocomplete/search-user-autocomplete.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
import {
ProjectGrantMembersCreateDialogModule,

View File

@@ -13,7 +13,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
import { TranslateModule } from '@ngx-translate/core';
import { CardModule } from 'src/app/modules/card/card.module';
import { ProjectRolesModule } from 'src/app/modules/project-roles/project-roles.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
import { ProjectGrantCreateRoutingModule } from './project-grant-create-routing.module';
import { ProjectGrantCreateComponent } from './project-grant-create.component';

View File

@@ -2,8 +2,8 @@ import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { TranslateModule } from '@ngx-translate/core';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
import { ShowKeyDialogComponent } from './show-key-dialog.component';

View File

@@ -12,8 +12,8 @@ import { TranslateModule } from '@ngx-translate/core';
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
import { MembershipDetailComponent } from './membership-detail.component';

View File

@@ -26,9 +26,9 @@ import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.
import { SharedModule } from 'src/app/modules/shared/shared.module';
import { UserGrantsModule } from 'src/app/modules/user-grants/user-grants.module';
import { WarnDialogModule } from 'src/app/modules/warn-dialog/warn-dialog.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
import { AuthUserDetailComponent } from './auth-user-detail/auth-user-detail.component';
import { AuthUserMfaComponent } from './auth-user-detail/auth-user-mfa/auth-user-mfa.component';
@@ -37,6 +37,7 @@ import { DialogOtpComponent } from './auth-user-detail/dialog-otp/dialog-otp.com
import { ThemeSettingComponent } from './auth-user-detail/theme-setting/theme-setting.component';
import { DetailFormMachineModule } from './detail-form-machine/detail-form-machine.module';
import { DetailFormModule } from './detail-form/detail-form.module';
import { ExternalIdpsComponent } from './external-idps/external-idps.component';
import { AddKeyDialogModule } from './machine-keys/add-key-dialog/add-key-dialog.module';
import { MachineKeysComponent } from './machine-keys/machine-keys.component';
import { ShowKeyDialogModule } from './machine-keys/show-key-dialog/show-key-dialog.module';
@@ -45,7 +46,6 @@ import { PasswordComponent } from './password/password.component';
import { UserDetailRoutingModule } from './user-detail-routing.module';
import { UserDetailComponent } from './user-detail/user-detail.component';
import { UserMfaComponent } from './user-detail/user-mfa/user-mfa.component';
import { ExternalIdpsComponent } from './external-idps/external-idps.component';
@NgModule({
declarations: [

View File

@@ -15,7 +15,7 @@ import { AvatarModule } from 'src/app/modules/avatar/avatar.module';
import { CardModule } from 'src/app/modules/card/card.module';
import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module';
import { SharedModule } from 'src/app/modules/shared/shared.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
import { UserListRoutingModule } from './user-list-routing.module';
import { UserListComponent } from './user-list.component';

View File

@@ -1,7 +1,6 @@
import { Pipe, PipeTransform } from '@angular/core';
import { Observable } from 'rxjs';
import { GrpcAuthService } from '../services/grpc-auth.service';
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
@Pipe({
name: 'hasRole',

View File

@@ -0,0 +1,17 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { TruncatePipePipe } from './truncate-pipe.pipe';
@NgModule({
declarations: [TruncatePipePipe],
imports: [
CommonModule,
],
exports: [
TruncatePipePipe,
],
})
export class TruncatePipeModule { }

View File

@@ -0,0 +1,13 @@
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'truncate',
})
export class TruncatePipePipe implements PipeTransform {
transform(value: string, ...args: unknown[]): unknown {
const limit = args.length > 0 ? parseInt(args[0] as string, 10) : 20;
const trail = args.length > 1 ? args[1] : '...';
return value.length > limit ? value.substring(0, limit) + trail : value;
}
}

View File

@@ -44,6 +44,8 @@ export class GrpcAuthService {
private _activeOrgChanged: Subject<Org.AsObject> = new Subject();
public user!: Observable<UserProfileView.AsObject>;
private zitadelPermissions: BehaviorSubject<string[]> = new BehaviorSubject(['user.resourceowner']);
public readonly fetchedZitadelPermissions: BehaviorSubject<boolean> = new BehaviorSubject(false as boolean);
private cachedOrgs: Org.AsObject[] = [];
constructor(
@@ -125,6 +127,12 @@ export class GrpcAuthService {
first(),
switchMap(() => from(this.GetMyzitadelPermissions())),
map(rolesResp => rolesResp.toObject().permissionsList),
catchError(_ => {
return of([]);
}),
finalize(() => {
this.fetchedZitadelPermissions.next(true);
}),
).subscribe(roles => {
this.zitadelPermissions.next(roles);
});
@@ -136,9 +144,7 @@ export class GrpcAuthService {
*/
public isAllowed(roles: string[] | RegExp[]): Observable<boolean> {
if (roles && roles.length > 0) {
return this.zitadelPermissions.pipe(switchMap(zroles => {
return of(this.hasRoles(zroles, roles));
}));
return this.zitadelPermissions.pipe(switchMap(zroles => of(this.hasRoles(zroles, roles))));
} else {
return of(false);
}
@@ -220,6 +226,10 @@ export class GrpcAuthService {
return this.grpcService.auth.updateMyUserProfile(req);
}
public get zitadelPermissionsChanged(): Observable<string[]> {
return this.zitadelPermissions;
}
public async getMyUserSessions(): Promise<UserSessionViews> {
return this.grpcService.auth.getMyUserSessions(
new Empty(),
@@ -286,15 +296,15 @@ export class GrpcAuthService {
}
public async SearchExternalIdps(
userId: string,
limit: number,
offset: number,
asc?: boolean,
userId: string,
limit: number,
offset: number,
asc?: boolean,
): Promise<ExternalIDPSearchResponse> {
const req = new ExternalIDPSearchRequest();
req.setLimit(limit);
req.setOffset(offset);
return this.grpcService.auth.searchMyExternalIDPs(req);
const req = new ExternalIDPSearchRequest();
req.setLimit(limit);
req.setOffset(offset);
return this.grpcService.auth.searchMyExternalIDPs(req);
}
public async AddMfaOTP(): Promise<MfaOtpResponse> {

View File

@@ -1,6 +1,7 @@
import { PlatformLocation } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { AuthConfig } from 'angular-oauth2-oidc';
import { AdminServicePromiseClient } from '../proto/generated/admin_grpc_web_pb';
@@ -24,6 +25,8 @@ export class GrpcService {
private platformLocation: PlatformLocation,
private authenticationService: AuthenticationService,
private storageService: StorageService,
private dialog: MatDialog,
// private toast: ToastService,
) { }
public async loadAppEnvironment(): Promise<any> {
@@ -31,9 +34,9 @@ export class GrpcService {
.toPromise().then((data: any) => {
if (data && data.authServiceUrl && data.mgmtServiceUrl && data.issuer) {
const interceptors = {
'unaryInterceptors': [
new AuthInterceptor(this.authenticationService, this.storageService),
unaryInterceptors: [
new OrgInterceptor(this.storageService),
new AuthInterceptor(this.authenticationService, this.storageService, this.dialog),
],
};

View File

@@ -1,6 +1,8 @@
import { Injectable } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Request, UnaryInterceptor, UnaryResponse } from 'grpc-web';
import { filter, first } from 'rxjs/operators';
import { filter, first, take } from 'rxjs/operators';
import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component';
import { AuthenticationService } from '../authentication.service';
import { StorageService } from '../storage.service';
@@ -10,8 +12,15 @@ const authorizationKey = 'Authorization';
const bearerPrefix = 'Bearer';
const accessTokenStorageKey = 'access_token';
@Injectable({ providedIn: 'root' })
/**
* Set the authentication token
*/
export class AuthInterceptor<TReq = unknown, TResp = unknown> implements UnaryInterceptor<TReq, TResp> {
constructor(private authenticationService: AuthenticationService, private storageService: StorageService) { }
constructor(
private authenticationService: AuthenticationService,
private storageService: StorageService,
private dialog: MatDialog,
) { }
public async intercept(request: Request<TReq, TResp>, invoker: any): Promise<UnaryResponse<TReq, TResp>> {
await this.authenticationService.authenticationChanged.pipe(
@@ -24,17 +33,25 @@ export class AuthInterceptor<TReq = unknown, TResp = unknown> implements UnaryIn
metadata[authorizationKey] = `${bearerPrefix} ${accessToken}`;
return invoker(request).then((response: any) => {
// const message = response.getResponseMessage();
const respMetadata = response.getMetadata();
// TODO: intercept unauthenticated an authenticate
// const status = respMetadata['grpc-status'];
// console.log(respMetadata, status);
// if (status?.code === 16) {
// this.authenticationService.authenticate();
// }
return response;
}).catch((error: any) => {
console.error('error: ', error);
if (error.code === 16) {
const dialogRef = this.dialog.open(WarnDialogComponent, {
data: {
confirmKey: 'ACTIONS.LOGIN',
titleKey: 'ERRORS.TOKENINVALID.TITLE',
descriptionKey: 'ERRORS.TOKENINVALID.DESCRIPTION',
},
width: '400px',
});
dialogRef.afterClosed().pipe(take(1)).subscribe(resp => {
if (resp) {
this.authenticationService.authenticate(undefined, true, true);
}
});
}
});
}
}

View File

@@ -3,9 +3,7 @@ import { MatDialog } from '@angular/material/dialog';
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
import { TranslateService } from '@ngx-translate/core';
import { Observable } from 'rxjs';
import { take } from 'rxjs/operators';
import { WarnDialogComponent } from '../modules/warn-dialog/warn-dialog.component';
import { AuthenticationService } from './authentication.service';
@Injectable({
@@ -32,24 +30,8 @@ export class ToastService {
public showError(grpcError: any): void {
const { message, code, metadata } = grpcError;
// TODO: remove check for code === 7
if (code === 16 || (code === 7 && message === 'invalid token')) {
const dialogRef = this.dialog.open(WarnDialogComponent, {
data: {
confirmKey: 'ACTIONS.LOGIN',
titleKey: 'ERRORS.TOKENINVALID.TITLE',
descriptionKey: 'ERRORS.TOKENINVALID.DESCRIPTION',
},
width: '400px',
});
dialogRef.afterClosed().pipe(take(1)).subscribe(resp => {
if (resp) {
this.authService.authenticate(undefined, true, true);
}
});
} else {
this.showMessage(decodeURI(message), 'close', { duration: 3000 });
if (code !== 16) {
this.showMessage(decodeURI(message), 'close', { duration: 4000 });
}
}

View File

@@ -409,7 +409,8 @@
"TITLE":"Login Richtlinien",
"DESCRIPTION":"Definiere die Loginmethoden für Benutzer",
"TITLECREATE":"Definiere die Loginmethoden für Benutzer",
"DESCRIPTIONCREATE":"Nutzer können Sich mit den verfügbaren Idps authentifizieren."
"DESCRIPTIONCREATEADMIN":"Nutzer können Sich mit den verfügbaren Idps authentifizieren.",
"DESCRIPTIONCREATEMGMT":"Nutzer können Sich mit den verfügbaren Idps authentifizieren. Achtung: Es kann von System-, sowie von selbsterstellten Providern Ihrer Organisation gewählt werden."
},
"BTN_INSTALL":"Installieren",
"BTN_EDIT":"Modifizieren",

View File

@@ -409,7 +409,8 @@
"TITLE":"Login Policy",
"DESCRIPTION":"Define how Users can be authenticated",
"TITLECREATE":"Define how Users can be authenticated",
"DESCRIPTIONCREATE":"Users can choose from all of the available identity providers."
"DESCRIPTIONCREATEADMIN":"Users can choose from the available identity providers below.",
"DESCRIPTIONCREATEMGMT":"Users can choose from the available identity providers below. Note: You can use System-set providers as well as providers set for your organisation only."
},
"BTN_INSTALL":"Setup",
"BTN_EDIT":"Modify",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -1,47 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="1026.000000pt" height="1026.000000pt" viewBox="0 0 1026.000000 1026.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.11, written by Peter Selinger 2001-2013
</metadata>
<g transform="translate(0.000000,1026.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M2786 10150 c-8 -24 -67 -243 -72 -265 -2 -11 -17 -69 -34 -130 -17
-60 -59 -218 -94 -350 -36 -132 -89 -332 -119 -445 -31 -113 -67 -248 -81
-300 -14 -52 -37 -138 -51 -190 -31 -112 -86 -319 -90 -340 -2 -8 -10 -40 -18
-70 -9 -30 -47 -172 -86 -316 -38 -144 -95 -355 -126 -470 -50 -186 -156 -581
-185 -689 -6 -22 -15 -56 -20 -75 -8 -29 -175 -651 -184 -685 -2 -5 -6 -23
-11 -40 -4 -16 -18 -68 -31 -115 -12 -47 -25 -96 -28 -110 -3 -14 -46 -176
-96 -360 -93 -343 -168 -621 -175 -653 -2 -9 -17 -65 -34 -125 -17 -59 -41
-150 -55 -202 -13 -52 -63 -239 -110 -415 -48 -176 -102 -381 -122 -455 -20
-74 -44 -164 -54 -200 -10 -36 -51 -186 -90 -335 -40 -148 -105 -391 -145
-540 -40 -148 -101 -376 -135 -505 -35 -129 -71 -266 -82 -305 -35 -131 -69
-260 -73 -279 -3 -10 -16 -60 -31 -110 -14 -50 -28 -99 -30 -109 -2 -10 -6
-27 -9 -37 -3 -10 -8 -27 -10 -37 -2 -10 -49 -186 -105 -392 -55 -206 -99
-375 -97 -377 1 -2 39 6 82 17 44 12 87 23 95 25 12 3 198 52 260 69 8 2 58
16 110 30 52 14 138 37 190 51 52 14 102 28 110 30 8 2 33 8 55 14 22 6 47 12
56 14 24 6 279 75 334 91 28 7 138 37 245 65 107 29 209 56 225 61 17 5 82 22
145 39 63 17 225 60 360 96 135 36 252 68 260 70 8 1 98 25 200 53 102 27 311
83 465 125 377 100 561 150 880 236 105 28 197 53 205 55 26 5 812 215 880
235 36 10 126 35 200 54 74 20 221 59 325 87 105 28 197 52 205 54 8 2 58 15
110 30 91 25 185 50 350 94 189 49 280 74 340 91 36 11 119 33 185 51 66 17
167 44 225 59 138 37 807 216 1080 289 118 32 310 84 425 115 116 30 262 70
325 87 63 17 165 44 225 60 61 16 144 38 185 50 41 11 82 22 90 24 8 2 119 31
245 65 127 34 237 63 246 65 33 7 104 29 111 34 4 4 -544 558 -1218 1231
l-1225 1225 83 38 c473 221 834 631 991 1127 40 127 73 278 82 385 7 74 7 309
1 360 -59 472 -225 826 -537 1143 -278 283 -651 473 -1044 532 -44 7 -89 14
-100 16 -25 6 -320 5 -360 0 -154 -20 -160 -21 -247 -41 -277 -63 -591 -221
-795 -402 -216 -191 -375 -401 -479 -631 l-38 -83 -1227 1227 c-798 798 -1230
1223 -1233 1214z m2384 -3623 c0 -36 73 -233 125 -342 46 -93 163 -289 184
-305 3 -3 19 -23 36 -45 16 -21 36 -47 45 -55 8 -9 36 -39 61 -66 68 -74 151
-147 237 -211 42 -32 79 -61 80 -65 2 -5 8 -8 13 -8 5 0 39 -19 76 -41 124
-76 385 -185 487 -203 16 -3 30 -7 32 -8 2 -3 -1095 -301 -1226 -333 -26 -7
-231 -61 -335 -90 -55 -15 -107 -28 -115 -30 -8 -2 -59 -15 -113 -30 -54 -16
-100 -25 -104 -22 -3 4 -1 23 5 44 5 21 35 133 67 248 56 208 119 445 155 580
10 39 44 165 75 280 81 300 86 318 90 335 2 8 27 104 57 212 46 172 67 220 68
155z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
console/src/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB