Skip to content

Commit

Permalink
chore: merge main into next-rc (#6068)
Browse files Browse the repository at this point in the history
### Definition of Ready

- [ ] I am happy with the code
- [ ] Short description of the feature/issue is added in the pr
description
- [ ] PR is linked to the corresponding user story
- [ ] Acceptance criteria are met
- [ ] All open todos and follow ups are defined in a new ticket and
justified
- [ ] Deviations from the acceptance criteria and design are agreed with
the PO and documented.
- [ ] No debug or dead code
- [ ] My code has no repetitions
- [ ] Critical parts are tested automatically
- [ ] Where possible E2E tests are implemented
- [ ] Documentation/examples are up-to-date
- [ ] All non-functional requirements are met
- [ ] Functionality of the acceptance criteria is checked manually on
the dev system.
  • Loading branch information
livio-a committed Jun 22, 2023
2 parents 093d01a + 1b5d6ce commit 11d5e6f
Show file tree
Hide file tree
Showing 127 changed files with 9,018 additions and 423 deletions.
6 changes: 6 additions & 0 deletions cmd/start/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import (
auth_es "github.com/zitadel/zitadel/internal/auth/repository/eventsourcing"
"github.com/zitadel/zitadel/internal/authz"
authz_repo "github.com/zitadel/zitadel/internal/authz/repository"
authz_es "github.com/zitadel/zitadel/internal/authz/repository/eventsourcing/eventstore"
"github.com/zitadel/zitadel/internal/command"
"github.com/zitadel/zitadel/internal/crypto"
cryptoDB "github.com/zitadel/zitadel/internal/crypto/database"
Expand Down Expand Up @@ -145,6 +146,11 @@ func startZitadel(config *Config, masterKey string, server chan<- *Server) error
keys.SAML,
config.InternalAuthZ.RolePermissionMappings,
sessionTokenVerifier,
func(q *query.Queries) domain.PermissionCheck {
return func(ctx context.Context, permission, orgID, resourceID string) (err error) {
return internal_authz.CheckPermission(ctx, &authz_es.UserMembershipRepo{Queries: q}, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
}
},
)
if err != nil {
return fmt.Errorf("cannot start queries: %w", err)
Expand Down
11 changes: 6 additions & 5 deletions console/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { KeyboardShortcutsService } from './services/keyboard-shortcuts/keyboard
import { ManagementService } from './services/mgmt.service';
import { ThemeService } from './services/theme.service';
import { UpdateService } from './services/update.service';
import { fallbackLanguage, supportedLanguages, supportedLanguagesRegexp } from './utils/language';

@Component({
selector: 'cnsl-root',
Expand Down Expand Up @@ -267,15 +268,15 @@ export class AppComponent implements OnDestroy {
}

private setLanguage(): void {
this.translate.addLangs(['de', 'en', 'es', 'fr', 'it', 'ja', 'pl', 'zh']);
this.translate.setDefaultLang('en');
this.translate.addLangs(supportedLanguages);
this.translate.setDefaultLang(fallbackLanguage);

this.authService.user.subscribe((userprofile) => {
if (userprofile) {
const cropped = navigator.language.split('-')[0] ?? 'en';
const fallbackLang = cropped.match(/de|en|es|fr|it|ja|pl|zh/) ? cropped : 'en';
const cropped = navigator.language.split('-')[0] ?? fallbackLanguage;
const fallbackLang = cropped.match(supportedLanguagesRegexp) ? cropped : fallbackLanguage;

const lang = userprofile?.human?.profile?.preferredLanguage.match(/de|en|es|fr|it|ja|pl|zh/)
const lang = userprofile?.human?.profile?.preferredLanguage.match(supportedLanguagesRegexp)
? userprofile.human.profile?.preferredLanguage
: fallbackLang;
this.translate.use(lang);
Expand Down
3 changes: 3 additions & 0 deletions console/src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { CommonModule, registerLocaleData } from '@angular/common';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import localeBg from '@angular/common/locales/bg';
import localeDe from '@angular/common/locales/de';
import localeEn from '@angular/common/locales/en';
import localeEs from '@angular/common/locales/es';
Expand Down Expand Up @@ -80,6 +81,8 @@ registerLocaleData(localePl);
i18nIsoCountries.registerLocale(require('i18n-iso-countries/langs/pl.json'));
registerLocaleData(localeZh);
i18nIsoCountries.registerLocale(require('i18n-iso-countries/langs/zh.json'));
registerLocaleData(localeBg);
i18nIsoCountries.registerLocale(require('i18n-iso-countries/langs/bg.json'));

export class WebpackTranslateLoader implements TranslateLoader {
getTranslation(lang: string): Observable<any> {
Expand Down
19 changes: 18 additions & 1 deletion console/src/app/directives/back/back.directive.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,33 @@
import { Directive, ElementRef, HostListener, Renderer2 } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { take } from 'rxjs';
import { NavigationService } from 'src/app/services/navigation.service';

@Directive({
selector: '[cnslBack]',
})
export class BackDirective {
new: Boolean = false;
@HostListener('click')
onClick(): void {
this.navigation.back();
// Go back again to avoid create dialog starts again
if (this.new) {
this.navigation.back();
}
}

constructor(private navigation: NavigationService, private elRef: ElementRef, private renderer2: Renderer2) {
constructor(
private navigation: NavigationService,
private elRef: ElementRef,
private renderer2: Renderer2,
private route: ActivatedRoute,
) {
// Check if a new element was created using a create dialog
this.route.queryParams.pipe(take(1)).subscribe((params) => {
this.new = params['new'];
});

if (navigation.isBackPossible) {
// this.renderer2.removeStyle(this.elRef.nativeElement, 'visibility');
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
import { ManagementService } from 'src/app/services/mgmt.service';
import { ToastService } from 'src/app/services/toast.service';

import { supportedLanguages } from 'src/app/utils/language';
import { InfoSectionType } from '../../info-section/info-section.component';
import { WarnDialogComponent } from '../../warn-dialog/warn-dialog.component';
import { PolicyComponentServiceType } from '../policy-component-types.enum';
Expand Down Expand Up @@ -109,7 +110,7 @@ export class LoginTextsComponent implements OnInit, OnDestroy {
@Input() public serviceType: PolicyComponentServiceType = PolicyComponentServiceType.MGMT;

public KeyNamesArray: string[] = KeyNamesArray;
public LOCALES: string[] = ['de', 'en', 'es', 'fr', 'it', 'ja', 'pl', 'zh'];
public LOCALES: string[] = supportedLanguages;

private sub: Subscription = new Subscription();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
import { ManagementService } from 'src/app/services/mgmt.service';
import { ToastService } from 'src/app/services/toast.service';

import { supportedLanguages } from 'src/app/utils/language';
import { InfoSectionType } from '../../info-section/info-section.component';
import { WarnDialogComponent } from '../../warn-dialog/warn-dialog.component';
import { PolicyComponentServiceType } from '../policy-component-types.enum';
Expand Down Expand Up @@ -441,7 +442,7 @@ export class MessageTextsComponent implements OnInit, OnDestroy {
};

public locale: string = 'en';
public LOCALES: string[] = ['de', 'en', 'es', 'fr', 'it', 'ja', 'pl', 'zh'];
public LOCALES: string[] = supportedLanguages;
private sub: Subscription = new Subscription();
public canWrite$: Observable<boolean> = this.authService.isAllowed([
this.serviceType === PolicyComponentServiceType.ADMIN
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ export class ActionTableComponent implements OnInit {
const dialogRef = this.dialog.open(AddActionDialogComponent, {
data: {},
width: '500px',
disableClose: true,
});

dialogRef.afterClosed().subscribe((req: CreateActionRequest) => {
Expand All @@ -120,6 +121,7 @@ export class ActionTableComponent implements OnInit {
action: action,
},
width: '500px',
disableClose: true,
});

dialogRef.afterClosed().subscribe((req: UpdateActionRequest) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,29 @@
<span *ngIf="id" class="action-dialog-title" mat-dialog-title>{{ 'FLOWS.DIALOG.UPDATE.TITLE' | translate }}</span>

<div mat-dialog-content>
<cnsl-form-field class="form-field">
<cnsl-label>{{ 'FLOWS.NAME' | translate }}</cnsl-label>
<input cnslInput [(ngModel)]="name" />
</cnsl-form-field>
<form [formGroup]="form">
<cnsl-form-field class="form-field">
<cnsl-label>{{ 'FLOWS.NAME' | translate }}</cnsl-label>
<input cnslInput formControlName="name" />
</cnsl-form-field>

<ngx-codemirror
*ngIf="opened$ | async"
[(ngModel)]="script"
[options]="{
lineNumbers: true,
theme: 'material',
mode: 'javascript'
}"
></ngx-codemirror>
<ngx-codemirror
*ngIf="opened$ | async"
formControlName="script"
[options]="{
lineNumbers: true,
theme: 'material',
mode: 'javascript'
}"
></ngx-codemirror>

<cnsl-form-field class="form-field">
<cnsl-label>{{ 'FLOWS.TIMEOUTINSEC' | translate }}</cnsl-label>
<input type="number" cnslInput [(ngModel)]="durationInSec" />
</cnsl-form-field>
<cnsl-form-field class="form-field">
<cnsl-label>{{ 'FLOWS.TIMEOUTINSEC' | translate }}</cnsl-label>
<input type="number" cnslInput formControlName="durationInSec" />
</cnsl-form-field>

<mat-checkbox [(ngModel)]="allowedToFail">{{ 'FLOWS.ALLOWEDTOFAIL' | translate }}</mat-checkbox>
<mat-checkbox formControlName="allowedToFail">{{ 'FLOWS.ALLOWEDTOFAIL' | translate }}</mat-checkbox>
</form>
</div>
<div mat-dialog-actions class="action">
<button *ngIf="id" mat-stroked-button color="warn" (click)="deleteAndCloseDialog()">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Component, Inject } from '@angular/core';
import { Component, Inject, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import {
MatLegacyDialog as MatDialog,
MatLegacyDialogRef as MatDialogRef,
MAT_LEGACY_DIALOG_DATA as MAT_DIALOG_DATA,
} from '@angular/material/legacy-dialog';

import { Duration } from 'google-protobuf/google/protobuf/duration_pb';
import { mapTo } from 'rxjs';
import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component';
Expand All @@ -17,35 +19,76 @@ import { ToastService } from 'src/app/services/toast.service';
templateUrl: './add-action-dialog.component.html',
styleUrls: ['./add-action-dialog.component.scss'],
})
export class AddActionDialogComponent {
public name: string = '';
public script: string = '';
public durationInSec: number = 10;
public allowedToFail: boolean = false;

export class AddActionDialogComponent implements OnInit {
public id: string = '';

public opened$ = this.dialogRef.afterOpened().pipe(mapTo(true));

public form: FormGroup = new FormGroup({
name: new FormControl<string>('', []),
script: new FormControl<string>('', []),
durationInSec: new FormControl<number>(10, []),
allowedToFail: new FormControl<boolean>(false, []),
});
constructor(
private toast: ToastService,
private mgmtService: ManagementService,
private dialog: MatDialog,
private unsavedChangesDialog: MatDialog,
public dialogRef: MatDialogRef<AddActionDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: any,
) {
if (data && data.action) {
const action: Action.AsObject = data.action;
this.name = action.name;
this.script = action.script;
if (action.timeout?.seconds) {
this.durationInSec = action.timeout?.seconds;
}
this.allowedToFail = action.allowedToFail;
this.form.setValue({
name: action.name,
script: action.script,
durationInSec: action.timeout?.seconds ?? 10,
allowedToFail: action.allowedToFail,
});
this.id = action.id;
}
}

ngOnInit(): void {
// prevent unsaved changes get lost if backdrop is clicked
this.dialogRef.backdropClick().subscribe(() => {
if (this.form.dirty) {
this.showUnsavedDialog();
} else {
this.dialogRef.close(false);
}
});

// prevent unsaved changes get lost if escape key is pressed
this.dialogRef.keydownEvents().subscribe((event) => {
if (event.key === 'Escape') {
if (this.form.dirty) {
this.showUnsavedDialog();
} else {
this.dialogRef.close(false);
}
}
});
}

private showUnsavedDialog(): void {
const unsavedChangesDialogRef = this.unsavedChangesDialog.open(WarnDialogComponent, {
data: {
confirmKey: 'ACTIONS.UNSAVED.DIALOG.DISCARD',
cancelKey: 'ACTIONS.UNSAVED.DIALOG.CANCEL',
titleKey: 'ACTIONS.UNSAVEDCHANGES',
descriptionKey: 'ACTIONS.UNSAVED.DIALOG.DESCRIPTION',
},
width: '400px',
});

unsavedChangesDialogRef.afterClosed().subscribe((resp) => {
if (resp) {
this.dialogRef.close(false);
}
});
}

public closeDialog(): void {
this.dialogRef.close(false);
}
Expand All @@ -54,27 +97,27 @@ export class AddActionDialogComponent {
if (this.id) {
const req = new UpdateActionRequest();
req.setId(this.id);
req.setName(this.name);
req.setScript(this.script);
req.setName(this.form.value.name);
req.setScript(this.form.value.script);

const duration = new Duration();
duration.setNanos(0);
duration.setSeconds(this.durationInSec);
duration.setSeconds(this.form.value.durationInSec);

req.setAllowedToFail(this.allowedToFail);
req.setAllowedToFail(this.form.value.allowedToFail);

req.setTimeout(duration);
this.dialogRef.close(req);
} else {
const req = new CreateActionRequest();
req.setName(this.name);
req.setScript(this.script);
req.setName(this.form.value.name);
req.setScript(this.form.value.script);

const duration = new Duration();
duration.setNanos(0);
duration.setSeconds(this.durationInSec);
duration.setSeconds(this.form.value.durationInSec);

req.setAllowedToFail(this.allowedToFail);
req.setAllowedToFail(this.form.value.allowedToFail);

req.setTimeout(duration);
this.dialogRef.close(req);
Expand Down
3 changes: 2 additions & 1 deletion console/src/app/pages/org-create/org-create.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { AdminService } from 'src/app/services/admin.service';
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
import { ManagementService } from 'src/app/services/mgmt.service';
import { ToastService } from 'src/app/services/toast.service';
import { supportedLanguages } from 'src/app/utils/language';

@Component({
selector: 'cnsl-org-create',
Expand All @@ -45,7 +46,7 @@ export class OrgCreateComponent {
public pwdForm?: UntypedFormGroup;

public genders: Gender[] = [Gender.GENDER_FEMALE, Gender.GENDER_MALE, Gender.GENDER_UNSPECIFIED];
public languages: string[] = ['de', 'en', 'es', 'fr', 'it', 'ja', 'pl', 'zh'];
public languages: string[] = supportedLanguages;

public policy?: PasswordComplexityPolicy.AsObject;
public usePassword: boolean = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ export class AppCreateComponent implements OnInit, OnDestroy {
if (resp.clientId || resp.clientSecret) {
this.showSavedDialog(resp);
} else {
this.router.navigate(['projects', this.projectId, 'apps', resp.appId]);
this.router.navigate(['projects', this.projectId, 'apps', resp.appId], { queryParams: { new: true } });
}
})
.catch((error) => {
Expand All @@ -396,7 +396,7 @@ export class AppCreateComponent implements OnInit, OnDestroy {
if (resp.clientId || resp.clientSecret) {
this.showSavedDialog(resp);
} else {
this.router.navigate(['projects', this.projectId, 'apps', resp.appId]);
this.router.navigate(['projects', this.projectId, 'apps', resp.appId], { queryParams: { new: true } });
}
})
.catch((error) => {
Expand All @@ -410,7 +410,7 @@ export class AppCreateComponent implements OnInit, OnDestroy {
.addSAMLApp(this.samlAppRequest)
.then((resp) => {
this.loading = false;
this.router.navigate(['projects', this.projectId, 'apps', resp.appId]);
this.router.navigate(['projects', this.projectId, 'apps', resp.appId], { queryParams: { new: true } });
})
.catch((error) => {
this.loading = false;
Expand All @@ -436,7 +436,7 @@ export class AppCreateComponent implements OnInit, OnDestroy {
});

dialogRef.afterClosed().subscribe(() => {
this.router.navigate(['projects', this.projectId, 'apps', added.appId]);
this.router.navigate(['projects', this.projectId, 'apps', added.appId], { queryParams: { new: true } });
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export class ProjectRoleCreateComponent implements OnInit, OnDestroy {
.bulkAddProjectRoles(this.projectId, rolesToAdd)
.then(() => {
this.toast.showInfo('PROJECT.TOAST.ROLESCREATED', true);
this.router.navigate(['projects', this.projectId], { queryParams: { id: 'roles' } });
this.router.navigate(['projects', this.projectId], { queryParams: { id: 'roles', new: true } });
})
.catch((error) => {
this.toast.showError(error);
Expand Down

0 comments on commit 11d5e6f

Please sign in to comment.