feat: add additional origins on applications (#1691)

* feat: add additional origins on applications

* app additional redirects

* chore(deps-dev): bump @angular/cli from 11.2.8 to 11.2.11 in /console (#1706)

* fix: show org with regex (#1688)

* fix: flag mapping (#1699)

* chore(deps-dev): bump @angular/cli from 11.2.8 to 11.2.11 in /console

Bumps [@angular/cli](https://github.com/angular/angular-cli) from 11.2.8 to 11.2.11.
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Commits](https://github.com/angular/angular-cli/compare/v11.2.8...v11.2.11)

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

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

* chore(deps-dev): bump stylelint from 13.10.0 to 13.13.1 in /console (#1703)

* fix: show org with regex (#1688)

* fix: flag mapping (#1699)

* chore(deps-dev): bump stylelint from 13.10.0 to 13.13.1 in /console

Bumps [stylelint](https://github.com/stylelint/stylelint) from 13.10.0 to 13.13.1.
- [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.10.0...13.13.1)

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

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

* chore(deps-dev): bump @types/node from 14.14.37 to 15.0.1 in /console (#1702)

* fix: show org with regex (#1688)

* fix: flag mapping (#1699)

* chore(deps-dev): bump @types/node from 14.14.37 to 15.0.1 in /console

Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.37 to 15.0.1.
- [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: Max Peintner <max@caos.ch>
Co-authored-by: Silvan <silvan.reusser@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump ts-protoc-gen from 0.14.0 to 0.15.0 in /console (#1701)

* fix: show org with regex (#1688)

* fix: flag mapping (#1699)

* chore(deps): bump ts-protoc-gen from 0.14.0 to 0.15.0 in /console

Bumps [ts-protoc-gen](https://github.com/improbable-eng/ts-protoc-gen) from 0.14.0 to 0.15.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.14.0...0.15.0)

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

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

* chore(deps-dev): bump @types/jasmine from 3.6.9 to 3.6.10 in /console (#1682)

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

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

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

* chore(deps): bump @types/google-protobuf in /console (#1681)

Bumps [@types/google-protobuf](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/google-protobuf) from 3.7.4 to 3.15.2.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/google-protobuf)

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

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

* chore(deps): bump grpc from 1.24.5 to 1.24.7 in /console (#1666)

Bumps [grpc](https://github.com/grpc/grpc-node) from 1.24.5 to 1.24.7.
- [Release notes](https://github.com/grpc/grpc-node/releases)
- [Commits](https://github.com/grpc/grpc-node/compare/grpc@1.24.5...grpc@1.24.7)

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

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

* lock

* chore(deps-dev): bump @angular/language-service from 11.2.9 to 11.2.12 in /console (#1704)

* fix: show org with regex (#1688)

* fix: flag mapping (#1699)

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

Bumps [@angular/language-service](https://github.com/angular/angular/tree/HEAD/packages/language-service) from 11.2.9 to 11.2.12.
- [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/11.2.12/packages/language-service)

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

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

* package lock

* downgrade grpc

* downgrade protobuf types

* revert npm packs 🥸

Co-authored-by: Max Peintner <max@caos.ch>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Silvan <silvan.reusser@gmail.com>
This commit is contained in:
Livio Amstutz
2021-05-19 09:17:38 +02:00
committed by GitHub
parent 18ed6633be
commit 2e8fa82261
30 changed files with 380 additions and 17 deletions

View File

@@ -0,0 +1,28 @@
<form class="form" (ngSubmit)="add(originInput)">
<cnsl-form-field class="formfield">
<cnsl-label>{{ title }}</cnsl-label>
<input #originInput cnslInput [placeholder]="placeholder" [formControl]="redirectControl">
</cnsl-form-field>
<button matTooltip="{{'ACTIONS.ADD' | translate}}" type="submit" mat-icon-button
[disabled]="redirectControl.invalid || !canWrite">
<mat-icon>add</mat-icon>
</button>
</form>
<div class="uri-list">
<div *ngFor="let uri of urisList" class="uri-line">
<span class="uri"
[ngClass]="{'green': uri?.startsWith('https://'), 'red': !uri?.startsWith('https://')}">{{uri}}</span>
<span class="fill-space"></span>
<!-- TODO add regex later -->
<!-- <i *ngIf="!(uri | origin)" class="las la-exclamation red" [matTooltip]="'APP.NOTANORIGIN' | translate"></i> -->
<button matTooltip="{{'ACTIONS.DELETE' | translate}}" mat-icon-button (click)="remove(uri)" class="icon-button">
<mat-icon class="icon">cancel</mat-icon>
</button>
</div>
</div>
<p *ngIf="redirectControl.value && redirectControl.invalid" class="error">
{{'APP.OIDC.REDIRECTNOTVALID' | translate}}</p>

View File

@@ -0,0 +1,62 @@
.form {
display: flex;
align-items: flex-end;
min-width: 320px;
.formfield {
flex: 1;
}
button {
margin-bottom: 14px;
margin-right: -.5rem;
}
}
.uri-list {
margin: 0 .5rem;
width: 100%;
.uri-line {
display: flex;
align-items: center;
.uri {
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
font-size: 14px;
}
.fill-space {
flex: 1;
}
i.green {
font-size: 1rem;
line-height: 35px;
height: 30px;
}
i.red {
font-size: 1.2rem;
}
.icon-button {
height: 30px;
line-height: 30px;
.icon {
font-size: 1rem !important;
}
&:not(:hover) {
color: var(--grey);
}
}
}
}
.error {
font-size: 13px;
color: #f44336;
margin: 0 .5rem 1.5rem .5rem;
}

View File

@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AdditionalOriginsComponent } from './additional-origins.component';
describe('AdditionalOriginsComponent', () => {
let component: AdditionalOriginsComponent;
let fixture: ComponentFixture<AdditionalOriginsComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [AdditionalOriginsComponent],
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(AdditionalOriginsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,56 @@
import { Component, EventEmitter, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { FormControl } from '@angular/forms';
import { Observable, Subscription } from 'rxjs';
@Component({
selector: 'cnsl-additional-origins',
templateUrl: './additional-origins.component.html',
styleUrls: ['./additional-origins.component.scss'],
})
export class AdditionalOriginsComponent implements OnInit, OnDestroy {
@Input() title: string = '';
@Input() canWrite: boolean = false;
@Input() public urisList: string[] = [];
@Input() public redirectControl: FormControl = new FormControl({ value: '', disabled: true });
@Input() public changedUris: EventEmitter<string[]> = new EventEmitter();
@Input() public getValues: Observable<void> = new Observable();
public placeholder: string = '<scheme> "://" <hostname> [ ":" <port> ]';
@ViewChild('originInput') input!: any;
private sub: Subscription = new Subscription();
constructor() { }
ngOnInit(): void {
if (this.canWrite) {
this.redirectControl.enable();
}
this.sub = this.getValues.subscribe(() => {
this.add(this.input.nativeElement);
});
}
ngOnDestroy(): void {
this.sub.unsubscribe();
}
public add(input: any): void {
if (this.redirectControl.valid) {
if (input.value !== '' && input.value !== ' ' && input.value !== '/') {
this.urisList.push(input.value);
}
if (input) {
input.value = '';
}
}
}
public remove(redirect: any): void {
const index = this.urisList.indexOf(redirect);
if (index >= 0) {
this.urisList.splice(index, 1);
}
}
}

View File

@@ -118,7 +118,6 @@
{{'APP.OIDC.REDIRECTDESCRIPTIONWEB' | translate}}
</cnsl-info-section>
<div style="margin: .5rem" class="divider"></div>
<cnsl-redirect-uris *ngIf="appType?.value !== undefined" class="redirect-section" [canWrite]="canWrite"
[devMode]="devMode?.value" [getValues]="requestRedirectValuesSubject$"
(changedUris)="redirectUrisList = $event" [urisList]="redirectUrisList"
@@ -132,6 +131,27 @@
title="{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}"
[isNative]="appType?.value == OIDCAppType.OIDC_APP_TYPE_NATIVE">
</cnsl-redirect-uris>
<div style="margin: .5rem" class="divider"></div>
<div class="additional-origins">
<p class="title">{{'APP.ADDITIONALORIGINS' | translate}}
<button mat-icon-button (click)="showAdditionalOrigins = !showAdditionalOrigins"
matTooltip="{{(showAdditionalOrigins ? 'ACTIONS.HIDE' : 'ACTIONS.SHOW') | translate}}">
<mat-icon *ngIf="!showAdditionalOrigins">expand_more</mat-icon>
<mat-icon *ngIf="showAdditionalOrigins">expand_less</mat-icon>
</button>
</p>
<ng-container *ngIf="showAdditionalOrigins">
<p class="desc">{{'APP.ADDITIONALORIGINSDESC' | translate}}</p>
<cnsl-additional-origins *ngIf="appType?.value !== undefined" class="input" [canWrite]="canWrite"
[getValues]="requestRedirectValuesSubject$" (changedUris)="additionalOriginsList = $event"
[urisList]="additionalOriginsList" title="{{ 'APP.ORIGINS' | translate }}">
</cnsl-additional-origins>
</ng-container>
</div>
<div style="margin: .5rem" class="divider"></div>
</div>
<app-auth-method-radio *ngIf="authMethods && initialAuthMethod && (app?.oidcConfig || app?.apiConfig)"

View File

@@ -155,6 +155,26 @@
margin: 0 .5rem;
}
.additional-origins {
display: block;
width: 100%;
margin: 0 .5rem;
.title {
margin: 0;
}
.desc {
color: var(--grey);
font-size: 14px;
margin-top: 0;
}
.input {
width: 100%;
}
}
.formfield {
flex: 1 1 30%;
margin: 0 .5rem;

View File

@@ -61,6 +61,7 @@ export class AppDetailComponent implements OnInit, OnDestroy {
public errorMessage: string = '';
public removable: boolean = true;
public addOnBlur: boolean = true;
public showAdditionalOrigins: boolean = false;
public readonly separatorKeysCodes: number[] = [ENTER, COMMA, SPACE];
public authMethods: RadioItemAuthType[] = [];
@@ -102,6 +103,7 @@ export class AppDetailComponent implements OnInit, OnDestroy {
public redirectUrisList: string[] = [];
public postLogoutRedirectUrisList: string[] = [];
public additionalOriginsList: string[] = [];
public isZitadel: boolean = false;
public docs!: GetOIDCInformationResponse.AsObject;
@@ -252,6 +254,10 @@ export class AppDetailComponent implements OnInit, OnDestroy {
if (this.app.oidcConfig?.postLogoutRedirectUrisList) {
this.postLogoutRedirectUrisList = this.app.oidcConfig.postLogoutRedirectUrisList;
}
if (this.app.oidcConfig?.additionalOriginsList) {
this.additionalOriginsList = this.app.oidcConfig.additionalOriginsList;
}
if (this.app.oidcConfig?.clockSkew) {
const inSecs = this.app.oidcConfig?.clockSkew.seconds +
this.app.oidcConfig?.clockSkew.nanos / 100000;
@@ -445,6 +451,7 @@ export class AppDetailComponent implements OnInit, OnDestroy {
this.app.oidcConfig.authMethodType = this.authMethodType?.value;
this.app.oidcConfig.redirectUrisList = this.redirectUrisList;
this.app.oidcConfig.postLogoutRedirectUrisList = this.postLogoutRedirectUrisList;
this.app.oidcConfig.additionalOriginsList = this.additionalOriginsList;
this.app.oidcConfig.devMode = this.devMode?.value;
this.app.oidcConfig.accessTokenType = this.accessTokenType?.value;
this.app.oidcConfig.accessTokenRoleAssertion = this.accessTokenRoleAssertion?.value;

View File

@@ -1,3 +1,4 @@
import { A11yModule } from '@angular/cdk/a11y';
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
@@ -22,25 +23,28 @@ import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { AppRadioModule } from 'src/app/modules/app-radio/app-radio.module';
import { CardModule } from 'src/app/modules/card/card.module';
import { ChangesModule } from 'src/app/modules/changes/changes.module';
import { ClientKeysModule } from 'src/app/modules/client-keys/client-keys.module';
import { InfoSectionModule } from 'src/app/modules/info-section/info-section.module';
import { InputModule } from 'src/app/modules/input/input.module';
import { LinksModule } from 'src/app/modules/links/links.module';
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
import { OriginPipeModule } from 'src/app/pipes/origin-pipe/origin-pipe.module';
import { RedirectPipeModule } from 'src/app/pipes/redirect-pipe/redirect-pipe.module';
import { AdditionalOriginsComponent } from './additional-origins/additional-origins.component';
import { AppCreateComponent } from './app-create/app-create.component';
import { AppDetailComponent } from './app-detail/app-detail.component';
import { AppSecretDialogComponent } from './app-secret-dialog/app-secret-dialog.component';
import { AppsRoutingModule } from './apps-routing.module';
import { A11yModule } from '@angular/cdk/a11y';
import { RedirectUrisComponent } from './redirect-uris/redirect-uris.component';
import { LinksModule } from 'src/app/modules/links/links.module';
import { RedirectPipeModule } from 'src/app/pipes/redirect-pipe/redirect-pipe.module';
import { ClientKeysModule } from 'src/app/modules/client-keys/client-keys.module';
@NgModule({
declarations: [
AppCreateComponent,
AppDetailComponent,
AppSecretDialogComponent,
RedirectUrisComponent,
AdditionalOriginsComponent,
],
imports: [
CommonModule,
@@ -51,6 +55,7 @@ import { ClientKeysModule } from 'src/app/modules/client-keys/client-keys.module
AppsRoutingModule,
FormsModule,
TranslateModule,
OriginPipeModule,
ReactiveFormsModule,
HasRoleModule,
MatMenuModule,

View File

@@ -0,0 +1,18 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { OriginPipe } from './origin.pipe';
@NgModule({
declarations: [
OriginPipe,
],
imports: [
CommonModule,
],
exports: [
OriginPipe,
],
})
export class OriginPipeModule { }

View File

@@ -0,0 +1,10 @@
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'origin',
})
export class OriginPipe implements PipeTransform {
public transform(value: string): boolean {
return new RegExp(/^((https?:\/\/).*?([\w\d-]*\.[\w\d]+))($|\/.*$)/gm).test(value);
}
}

View File

@@ -104,6 +104,8 @@
}
},
"ACTIONS": {
"SHOW":"Aufklappen",
"HIDE":"Zuklappen",
"SAVE": "Speichern",
"SAVENOW": "Speichern",
"NEW": "Neu",
@@ -1056,6 +1058,10 @@
"AUTHMETHOD": "Authentifizierungsmethode",
"AUTHMETHODSECTION": "Authentifizierungsmethode",
"GRANT": "Berechtigungstypen",
"ADDITIONALORIGINS":"Zusätzliche Origins",
"ADDITIONALORIGINSDESC":"Wenn sie zusätzliche Origins definieren wollen, die nicht den Redirect URIs gleichzusätzen sind, können Sie dies hier tun.",
"ORIGINS":"Origins",
"NOTANORIGIN":"Der Angegebene Wert ist kein Origin.",
"OIDC": {
"INFO": {
"ISSUER": "Issuer",

View File

@@ -104,6 +104,8 @@
}
},
"ACTIONS": {
"SHOW":"Show",
"HIDE":"Hide",
"SAVE": "Save",
"SAVENOW": "Save now",
"NEW": "New",
@@ -1057,6 +1059,10 @@
"AUTHMETHOD": "Authentication Method",
"AUTHMETHODSECTION": "Authentication Method",
"GRANT": "Grant Types",
"ADDITIONALORIGINS":"Additional Origins",
"ADDITIONALORIGINSDESC":"If you want to add additional Origins to your app which is not used as a redirect you can do that here.",
"ORIGINS":"Origins",
"NOTANORIGIN":"The entered value is not an origin",
"OIDC": {
"INFO": {
"ISSUER": "Issuer",