mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-07 23:17:41 +00:00
fix(console): add missing login interface texts, update dependencies, cleanup storage (#2430)
* name * core cli * material cdk * chore(deps): bump libphonenumber-js from 1.9.23 to 1.9.34 in /console (#2386) Bumps [libphonenumber-js](https://gitlab.com/catamphetamine/libphonenumber-js) from 1.9.23 to 1.9.34. - [Release notes](https://gitlab.com/catamphetamine/libphonenumber-js/tags) - [Changelog](https://gitlab.com/catamphetamine/libphonenumber-js/blob/master/CHANGELOG.md) - [Commits](https://gitlab.com/catamphetamine/libphonenumber-js/compare/v1.9.23...v1.9.34) --- updated-dependencies: - dependency-name: libphonenumber-js dependency-type: direct:production update-type: version-update:semver-patch ... 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-core from 3.7.1 to 3.9.0 in /console (#2373) Bumps [jasmine-core](https://github.com/jasmine/jasmine) from 3.7.1 to 3.9.0. - [Release notes](https://github.com/jasmine/jasmine/releases) - [Changelog](https://github.com/jasmine/jasmine/blob/main/RELEASE.md) - [Commits](https://github.com/jasmine/jasmine/compare/v3.7.1...v3.9.0) --- updated-dependencies: - dependency-name: jasmine-core dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump rxjs from 6.6.7 to 7.3.0 in /console (#2366) Bumps [rxjs](https://github.com/reactivex/rxjs) from 6.6.7 to 7.3.0. - [Release notes](https://github.com/reactivex/rxjs/releases) - [Changelog](https://github.com/ReactiveX/rxjs/blob/master/CHANGELOG.md) - [Commits](https://github.com/reactivex/rxjs/compare/6.6.7...7.3.0) --- updated-dependencies: - dependency-name: rxjs dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * add missing login texts, fix application table * storage cleanup * storage location local * org session storage, remember in local Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
parent
440030b20b
commit
7579bf56f6
748
console/package-lock.json
generated
748
console/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -10,18 +10,18 @@
|
|||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "~12.2.4",
|
"@angular/animations": "~12.2.7",
|
||||||
"@angular/cdk": "~12.2.4",
|
"@angular/cdk": "~12.2.7",
|
||||||
"@angular/common": "~12.2.4",
|
"@angular/common": "~12.2.7",
|
||||||
"@angular/compiler": "~12.2.4",
|
"@angular/compiler": "~12.2.7",
|
||||||
"@angular/core": "~12.2.4",
|
"@angular/core": "~12.2.7",
|
||||||
"@angular/forms": "~12.2.4",
|
"@angular/forms": "~12.2.7",
|
||||||
"@angular/material": "^12.2.4",
|
"@angular/material": "^12.2.7",
|
||||||
"@angular/material-moment-adapter": "^12.2.4",
|
"@angular/material-moment-adapter": "^12.2.7",
|
||||||
"@angular/platform-browser": "~12.2.4",
|
"@angular/platform-browser": "~12.2.7",
|
||||||
"@angular/platform-browser-dynamic": "~12.2.4",
|
"@angular/platform-browser-dynamic": "~12.2.7",
|
||||||
"@angular/router": "~12.2.4",
|
"@angular/router": "~12.2.7",
|
||||||
"@angular/service-worker": "~12.2.4",
|
"@angular/service-worker": "~12.2.7",
|
||||||
"@grpc/grpc-js": "^1.3.2",
|
"@grpc/grpc-js": "^1.3.2",
|
||||||
"@ngx-translate/core": "^13.0.0",
|
"@ngx-translate/core": "^13.0.0",
|
||||||
"@ngx-translate/http-loader": "^6.0.0",
|
"@ngx-translate/http-loader": "^6.0.0",
|
||||||
@ -35,12 +35,12 @@
|
|||||||
"google-proto-files": "^2.4.0",
|
"google-proto-files": "^2.4.0",
|
||||||
"google-protobuf": "^3.17.2",
|
"google-protobuf": "^3.17.2",
|
||||||
"grpc-web": "^1.2.1",
|
"grpc-web": "^1.2.1",
|
||||||
"libphonenumber-js": "^1.9.23",
|
"libphonenumber-js": "^1.9.34",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"ngx-color": "^7.2.0",
|
"ngx-color": "^7.2.0",
|
||||||
"ngx-image-cropper": "^3.3.5",
|
"ngx-image-cropper": "^3.3.5",
|
||||||
"ngx-quicklink": "^0.2.6",
|
"ngx-quicklink": "^0.2.6",
|
||||||
"rxjs": "~6.6.7",
|
"rxjs": "~7.3.0",
|
||||||
"tinycolor2": "^1.4.2",
|
"tinycolor2": "^1.4.2",
|
||||||
"ts-protoc-gen": "^0.14.0",
|
"ts-protoc-gen": "^0.14.0",
|
||||||
"tslib": "^2.2.0",
|
"tslib": "^2.2.0",
|
||||||
@ -48,15 +48,15 @@
|
|||||||
"zone.js": "~0.11.4"
|
"zone.js": "~0.11.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "~12.2.4",
|
"@angular-devkit/build-angular": "~12.2.7",
|
||||||
"@angular/cli": "~12.2.4",
|
"@angular/cli": "~12.2.7",
|
||||||
"@angular/compiler-cli": "~12.2.4",
|
"@angular/compiler-cli": "~12.2.7",
|
||||||
"@angular/language-service": "~12.2.4",
|
"@angular/language-service": "~12.2.7",
|
||||||
"@types/jasmine": "~3.8.2",
|
"@types/jasmine": "~3.8.2",
|
||||||
"@types/jasminewd2": "~2.0.10",
|
"@types/jasminewd2": "~2.0.10",
|
||||||
"@types/node": "^16.7.6",
|
"@types/node": "^16.7.6",
|
||||||
"codelyzer": "^6.0.0",
|
"codelyzer": "^6.0.0",
|
||||||
"jasmine-core": "~3.7.1",
|
"jasmine-core": "~3.9.0",
|
||||||
"jasmine-spec-reporter": "~7.0.0",
|
"jasmine-spec-reporter": "~7.0.0",
|
||||||
"karma": "~6.3.2",
|
"karma": "~6.3.2",
|
||||||
"karma-chrome-launcher": "~3.1.0",
|
"karma-chrome-launcher": "~3.1.0",
|
||||||
@ -72,4 +72,4 @@
|
|||||||
"tslint": "~6.1.3",
|
"tslint": "~6.1.3",
|
||||||
"typescript": "^4.2.4"
|
"typescript": "^4.2.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -13,7 +13,7 @@ import { GetFeaturesResponse } from 'src/app/proto/generated/zitadel/management_
|
|||||||
import { Org } from 'src/app/proto/generated/zitadel/org_pb';
|
import { Org } from 'src/app/proto/generated/zitadel/org_pb';
|
||||||
import { AdminService } from 'src/app/services/admin.service';
|
import { AdminService } from 'src/app/services/admin.service';
|
||||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||||
import { StorageService } from 'src/app/services/storage.service';
|
import { StorageKey, StorageLocation, StorageService } from 'src/app/services/storage.service';
|
||||||
import { StripeCustomer, SubscriptionService } from 'src/app/services/subscription.service';
|
import { StripeCustomer, SubscriptionService } from 'src/app/services/subscription.service';
|
||||||
import { ToastService } from 'src/app/services/toast.service';
|
import { ToastService } from 'src/app/services/toast.service';
|
||||||
|
|
||||||
@ -49,13 +49,14 @@ export class FeaturesComponent implements OnDestroy {
|
|||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private toast: ToastService,
|
private toast: ToastService,
|
||||||
private sessionStorage: StorageService,
|
private storage: StorageService,
|
||||||
private injector: Injector,
|
private injector: Injector,
|
||||||
private adminService: AdminService,
|
private adminService: AdminService,
|
||||||
private subService: SubscriptionService,
|
private subService: SubscriptionService,
|
||||||
private dialog: MatDialog,
|
private dialog: MatDialog,
|
||||||
) {
|
) {
|
||||||
const temporg = this.sessionStorage.getItem('organization') as Org.AsObject;
|
const temporg: Org.AsObject | null = this.storage.getItem(StorageKey.organization, StorageLocation.session);
|
||||||
|
|
||||||
if (temporg) {
|
if (temporg) {
|
||||||
this.org = temporg;
|
this.org = temporg;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ import { SetCustomLoginTextsRequest } from 'src/app/proto/generated/zitadel/mana
|
|||||||
import {
|
import {
|
||||||
EmailVerificationDoneScreenText,
|
EmailVerificationDoneScreenText,
|
||||||
EmailVerificationScreenText,
|
EmailVerificationScreenText,
|
||||||
|
ExternalRegistrationUserOverviewScreenText,
|
||||||
ExternalUserNotFoundScreenText,
|
ExternalUserNotFoundScreenText,
|
||||||
FooterText,
|
FooterText,
|
||||||
InitializeUserDoneScreenText,
|
InitializeUserDoneScreenText,
|
||||||
@ -61,6 +62,11 @@ export function mapRequestValues(map: Partial<Map>, req: Req): Req {
|
|||||||
r2.setDescription(map.externalUserNotFoundText?.description ?? '');
|
r2.setDescription(map.externalUserNotFoundText?.description ?? '');
|
||||||
r2.setLinkButtonText(map.externalUserNotFoundText?.linkButtonText ?? '');
|
r2.setLinkButtonText(map.externalUserNotFoundText?.linkButtonText ?? '');
|
||||||
r2.setTitle(map.externalUserNotFoundText?.title ?? '');
|
r2.setTitle(map.externalUserNotFoundText?.title ?? '');
|
||||||
|
r2.setTosAndPrivacyLabel(map.externalUserNotFoundText?.tosAndPrivacyLabel ?? '');
|
||||||
|
r2.setTosConfirm(map.externalUserNotFoundText?.tosConfirm ?? '');
|
||||||
|
r2.setTosConfirmAnd(map.externalUserNotFoundText?.tosConfirmAnd ?? '');
|
||||||
|
r2.setTosLinkText(map.externalUserNotFoundText?.tosLinkText ?? '');
|
||||||
|
r2.setPrivacyLinkText(map.externalUserNotFoundText?.privacyLinkText ?? '');
|
||||||
req.setExternalUserNotFoundText(r2);
|
req.setExternalUserNotFoundText(r2);
|
||||||
|
|
||||||
const r3 = new FooterText();
|
const r3 = new FooterText();
|
||||||
@ -329,6 +335,7 @@ export function mapRequestValues(map: Partial<Map>, req: Req): Req {
|
|||||||
r31.setDescription(map.passwordlessRegistrationDoneText?.description ?? '');
|
r31.setDescription(map.passwordlessRegistrationDoneText?.description ?? '');
|
||||||
r31.setNextButtonText(map.passwordlessRegistrationDoneText?.nextButtonText ?? '');
|
r31.setNextButtonText(map.passwordlessRegistrationDoneText?.nextButtonText ?? '');
|
||||||
r31.setTitle(map.passwordlessRegistrationDoneText?.title ?? '');
|
r31.setTitle(map.passwordlessRegistrationDoneText?.title ?? '');
|
||||||
|
r31.setNextButtonText(map.passwordlessRegistrationDoneText?.cancelButtonText ?? '');
|
||||||
req.setPasswordlessRegistrationDoneText(r31);
|
req.setPasswordlessRegistrationDoneText(r31);
|
||||||
|
|
||||||
const r32 = new PasswordlessRegistrationScreenText();
|
const r32 = new PasswordlessRegistrationScreenText();
|
||||||
@ -350,5 +357,24 @@ export function mapRequestValues(map: Partial<Map>, req: Req): Req {
|
|||||||
r33.setValidateTokenButtonText(map.passwordlessText?.validateTokenButtonText ?? '');
|
r33.setValidateTokenButtonText(map.passwordlessText?.validateTokenButtonText ?? '');
|
||||||
req.setPasswordlessText(r33);
|
req.setPasswordlessText(r33);
|
||||||
|
|
||||||
|
const r34 = new ExternalRegistrationUserOverviewScreenText();
|
||||||
|
r34.setBackButtonText(map.externalRegistrationUserOverviewText?.backButtonText ?? '');
|
||||||
|
r34.setDescription(map.externalRegistrationUserOverviewText?.description ?? '');
|
||||||
|
r34.setEmailLabel(map.externalRegistrationUserOverviewText?.emailLabel ?? '');
|
||||||
|
r34.setFirstnameLabel(map.externalRegistrationUserOverviewText?.firstnameLabel ?? '');
|
||||||
|
r34.setLanguageLabel(map.externalRegistrationUserOverviewText?.languageLabel ?? '');
|
||||||
|
r34.setLastnameLabel(map.externalRegistrationUserOverviewText?.lastnameLabel ?? '');
|
||||||
|
r34.setNextButtonText(map.externalRegistrationUserOverviewText?.nextButtonText ?? '');
|
||||||
|
r34.setNicknameLabel(map.externalRegistrationUserOverviewText?.nicknameLabel ?? '');
|
||||||
|
r34.setPhoneLabel(map.externalRegistrationUserOverviewText?.phoneLabel ?? '');
|
||||||
|
r34.setPrivacyLinkText(map.externalRegistrationUserOverviewText?.privacyLinkText ?? '');
|
||||||
|
r34.setTitle(map.externalRegistrationUserOverviewText?.title ?? '');
|
||||||
|
r34.setTosAndPrivacyLabel(map.externalRegistrationUserOverviewText?.tosAndPrivacyLabel ?? '');
|
||||||
|
r34.setTosConfirm(map.externalRegistrationUserOverviewText?.tosConfirm ?? '');
|
||||||
|
r34.setTosConfirmAnd(map.externalRegistrationUserOverviewText?.tosConfirmAnd ?? '');
|
||||||
|
r34.setTosLinkText(map.externalRegistrationUserOverviewText?.tosLinkText ?? '');
|
||||||
|
r34.setUsernameLabel(map.externalRegistrationUserOverviewText?.usernameLabel ?? '');
|
||||||
|
req.setExternalRegistrationUserOverviewText(r34);
|
||||||
|
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,7 @@ const KeyNamesArray = [
|
|||||||
'passwordlessRegistrationDoneText',
|
'passwordlessRegistrationDoneText',
|
||||||
'passwordlessRegistrationText',
|
'passwordlessRegistrationText',
|
||||||
'passwordlessText',
|
'passwordlessText',
|
||||||
|
'externalRegistrationUserOverviewText'
|
||||||
];
|
];
|
||||||
// tslint:enable
|
// tslint:enable
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import { Org } from 'src/app/proto/generated/zitadel/org_pb';
|
|||||||
import { OrgIAMPolicy } from 'src/app/proto/generated/zitadel/policy_pb';
|
import { OrgIAMPolicy } from 'src/app/proto/generated/zitadel/policy_pb';
|
||||||
import { AdminService } from 'src/app/services/admin.service';
|
import { AdminService } from 'src/app/services/admin.service';
|
||||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||||
import { StorageService } from 'src/app/services/storage.service';
|
import { StorageKey, StorageLocation, StorageService } from 'src/app/services/storage.service';
|
||||||
import { ToastService } from 'src/app/services/toast.service';
|
import { ToastService } from 'src/app/services/toast.service';
|
||||||
|
|
||||||
import { GridPolicy, IAM_POLICY } from '../../policy-grid/policies';
|
import { GridPolicy, IAM_POLICY } from '../../policy-grid/policies';
|
||||||
@ -34,11 +34,11 @@ export class OrgIamPolicyComponent implements OnDestroy {
|
|||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private toast: ToastService,
|
private toast: ToastService,
|
||||||
private sessionStorage: StorageService,
|
private storage: StorageService,
|
||||||
private injector: Injector,
|
private injector: Injector,
|
||||||
private adminService: AdminService,
|
private adminService: AdminService,
|
||||||
) {
|
) {
|
||||||
const temporg = this.sessionStorage.getItem('organization') as Org.AsObject;
|
const temporg = this.storage.getItem(StorageKey.organization, StorageLocation.session) as Org.AsObject;
|
||||||
if (temporg) {
|
if (temporg) {
|
||||||
this.org = temporg;
|
this.org = temporg;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ import { AdminService } from 'src/app/services/admin.service';
|
|||||||
import { AssetEndpoint, AssetService, AssetType } from 'src/app/services/asset.service';
|
import { AssetEndpoint, AssetService, AssetType } from 'src/app/services/asset.service';
|
||||||
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||||
import { StorageService } from 'src/app/services/storage.service';
|
import { StorageKey, StorageLocation, StorageService } from 'src/app/services/storage.service';
|
||||||
import { ThemeService } from 'src/app/services/theme.service';
|
import { ThemeService } from 'src/app/services/theme.service';
|
||||||
import { ToastService } from 'src/app/services/toast.service';
|
import { ToastService } from 'src/app/services/toast.service';
|
||||||
|
|
||||||
@ -48,7 +48,6 @@ export enum ColorType {
|
|||||||
BACKGROUNDLIGHT,
|
BACKGROUNDLIGHT,
|
||||||
}
|
}
|
||||||
|
|
||||||
const ORG_STORAGE_KEY = 'organization';
|
|
||||||
const MAX_ALLOWED_SIZE = 0.5 * 1024 * 1024;
|
const MAX_ALLOWED_SIZE = 0.5 * 1024 * 1024;
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -96,10 +95,10 @@ export class PrivateLabelingPolicyComponent implements OnDestroy {
|
|||||||
private injector: Injector,
|
private injector: Injector,
|
||||||
private assetService: AssetService,
|
private assetService: AssetService,
|
||||||
private sanitizer: DomSanitizer,
|
private sanitizer: DomSanitizer,
|
||||||
private storageService: StorageService,
|
private storage: StorageService,
|
||||||
private themeService: ThemeService,
|
private themeService: ThemeService,
|
||||||
) {
|
) {
|
||||||
const org: Org.AsObject | null = (this.storageService.getItem(ORG_STORAGE_KEY));
|
const org: Org.AsObject | null = (this.storage.getItem(StorageKey.organization, StorageLocation.session));
|
||||||
|
|
||||||
if (org) {
|
if (org) {
|
||||||
this.org = org;
|
this.org = org;
|
||||||
|
@ -4,7 +4,7 @@ import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from
|
|||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { Org } from 'src/app/proto/generated/zitadel/org_pb';
|
import { Org } from 'src/app/proto/generated/zitadel/org_pb';
|
||||||
import { GrantedProject, ProjectGrantState } from 'src/app/proto/generated/zitadel/project_pb';
|
import { GrantedProject, ProjectGrantState } from 'src/app/proto/generated/zitadel/project_pb';
|
||||||
import { StorageKey, StorageService } from 'src/app/services/storage.service';
|
import { StorageKey, StorageLocation, StorageService } from 'src/app/services/storage.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-granted-project-grid',
|
selector: 'app-granted-project-grid',
|
||||||
@ -81,12 +81,12 @@ export class GrantedProjectGridComponent implements OnChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async getPrefixedItem(key: string): Promise<string | null> {
|
private async getPrefixedItem(key: string): Promise<string | null> {
|
||||||
const org = this.storage.getItem<Org.AsObject>(StorageKey.organization) as Org.AsObject;
|
const org = this.storage.getItem<Org.AsObject>(StorageKey.organization, StorageLocation.session) as Org.AsObject;
|
||||||
return localStorage.getItem(`${org.id}:${key}`);
|
return localStorage.getItem(`${org.id}:${key}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async setPrefixedItem(key: string, value: any): Promise<void> {
|
private async setPrefixedItem(key: string, value: any): Promise<void> {
|
||||||
const org = this.storage.getItem<Org.AsObject>(StorageKey.organization) as Org.AsObject;
|
const org = this.storage.getItem<Org.AsObject>(StorageKey.organization, StorageLocation.session) as Org.AsObject;
|
||||||
return localStorage.setItem(`${org.id}:${key}`, value);
|
return localStorage.setItem(`${org.id}:${key}`, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<div class="table-wrapper">
|
<div class="table-wrapper">
|
||||||
<table [dataSource]="dataSource" mat-table class="table" matSort aria-label="Elements">
|
<table [dataSource]="dataSource" mat-table class="table" aria-label="Elements">
|
||||||
<ng-container matColumnDef="select">
|
<ng-container matColumnDef="select">
|
||||||
<th class="selection" mat-header-cell *matHeaderCellDef>
|
<th class="selection" mat-header-cell *matHeaderCellDef>
|
||||||
<mat-checkbox color="primary" (change)="$event ? masterToggle() : null"
|
<mat-checkbox color="primary" (change)="$event ? masterToggle() : null"
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { SelectionModel } from '@angular/cdk/collections';
|
import { SelectionModel } from '@angular/cdk/collections';
|
||||||
import { AfterViewInit, Component, Input, OnInit, ViewChild } from '@angular/core';
|
import { AfterViewInit, Component, Input, OnInit, ViewChild } from '@angular/core';
|
||||||
import { MatSort } from '@angular/material/sort';
|
|
||||||
import { MatTable } from '@angular/material/table';
|
import { MatTable } from '@angular/material/table';
|
||||||
import { merge, of } from 'rxjs';
|
import { merge } from 'rxjs';
|
||||||
import { tap } from 'rxjs/operators';
|
import { tap } from 'rxjs/operators';
|
||||||
import { PaginatorComponent } from 'src/app/modules/paginator/paginator.component';
|
import { PaginatorComponent } from 'src/app/modules/paginator/paginator.component';
|
||||||
import { App } from 'src/app/proto/generated/zitadel/app_pb';
|
import { App } from 'src/app/proto/generated/zitadel/app_pb';
|
||||||
@ -11,57 +10,56 @@ import { ManagementService } from 'src/app/services/mgmt.service';
|
|||||||
import { ProjectApplicationsDataSource } from './applications-datasource';
|
import { ProjectApplicationsDataSource } from './applications-datasource';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-applications',
|
selector: 'app-applications',
|
||||||
templateUrl: './applications.component.html',
|
templateUrl: './applications.component.html',
|
||||||
styleUrls: ['./applications.component.scss'],
|
styleUrls: ['./applications.component.scss'],
|
||||||
})
|
})
|
||||||
export class ApplicationsComponent implements AfterViewInit, OnInit {
|
export class ApplicationsComponent implements AfterViewInit, OnInit {
|
||||||
@Input() public projectId: string = '';
|
@Input() public projectId: string = '';
|
||||||
@Input() public disabled: boolean = false;
|
@Input() public disabled: boolean = false;
|
||||||
@ViewChild(PaginatorComponent) public paginator!: PaginatorComponent;
|
@ViewChild(PaginatorComponent) public paginator!: PaginatorComponent;
|
||||||
@ViewChild(MatSort) public sort!: MatSort;
|
@ViewChild(MatTable) public table!: MatTable<App.AsObject>;
|
||||||
@ViewChild(MatTable) public table!: MatTable<App.AsObject>;
|
public dataSource!: ProjectApplicationsDataSource;
|
||||||
public dataSource!: ProjectApplicationsDataSource;
|
public selection: SelectionModel<App.AsObject> = new SelectionModel<App.AsObject>(true, []);
|
||||||
public selection: SelectionModel<App.AsObject> = new SelectionModel<App.AsObject>(true, []);
|
|
||||||
|
|
||||||
public displayedColumns: string[] = ['select', 'name', 'type'];
|
public displayedColumns: string[] = ['select', 'name', 'type'];
|
||||||
|
|
||||||
constructor(private mgmtService: ManagementService) { }
|
constructor(private mgmtService: ManagementService) { }
|
||||||
|
|
||||||
public ngOnInit(): void {
|
public ngOnInit(): void {
|
||||||
this.dataSource = new ProjectApplicationsDataSource(this.mgmtService);
|
this.dataSource = new ProjectApplicationsDataSource(this.mgmtService);
|
||||||
this.dataSource.loadApps(this.projectId, 0, 25);
|
this.dataSource.loadApps(this.projectId, 0, 25);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngAfterViewInit(): void {
|
public ngAfterViewInit(): void {
|
||||||
merge(this.sort ? this.sort?.sortChange : of(null), this.paginator.page)
|
merge(this.paginator.page)
|
||||||
.pipe(
|
.pipe(
|
||||||
tap(() => this.loadRolesPage()),
|
tap(() => this.loadRolesPage()),
|
||||||
)
|
)
|
||||||
.subscribe();
|
.subscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadRolesPage(): void {
|
private loadRolesPage(): void {
|
||||||
this.dataSource.loadApps(
|
this.dataSource.loadApps(
|
||||||
this.projectId,
|
this.projectId,
|
||||||
this.paginator.pageIndex,
|
this.paginator.pageIndex,
|
||||||
this.paginator.pageSize,
|
this.paginator.pageSize,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public isAllSelected(): boolean {
|
public isAllSelected(): boolean {
|
||||||
const numSelected = this.selection.selected.length;
|
const numSelected = this.selection.selected.length;
|
||||||
const numRows = this.dataSource.appsSubject.value.length;
|
const numRows = this.dataSource.appsSubject.value.length;
|
||||||
return numSelected === numRows;
|
return numSelected === numRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
public masterToggle(): void {
|
public masterToggle(): void {
|
||||||
this.isAllSelected() ?
|
this.isAllSelected() ?
|
||||||
this.selection.clear() :
|
this.selection.clear() :
|
||||||
this.dataSource.appsSubject.value.forEach((row: App.AsObject) => this.selection.select(row));
|
this.dataSource.appsSubject.value.forEach((row: App.AsObject) => this.selection.select(row));
|
||||||
}
|
}
|
||||||
|
|
||||||
public refreshPage(): void {
|
public refreshPage(): void {
|
||||||
this.dataSource.loadApps(this.projectId, this.paginator.pageIndex, this.paginator.pageSize);
|
this.dataSource.loadApps(this.projectId, this.paginator.pageIndex, this.paginator.pageSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,162 +7,162 @@ import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.com
|
|||||||
import { Org } from 'src/app/proto/generated/zitadel/org_pb';
|
import { Org } from 'src/app/proto/generated/zitadel/org_pb';
|
||||||
import { Project, ProjectState } from 'src/app/proto/generated/zitadel/project_pb';
|
import { Project, ProjectState } from 'src/app/proto/generated/zitadel/project_pb';
|
||||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||||
import { StorageKey, StorageService } from 'src/app/services/storage.service';
|
import { StorageKey, StorageLocation, StorageService } from 'src/app/services/storage.service';
|
||||||
import { ToastService } from 'src/app/services/toast.service';
|
import { ToastService } from 'src/app/services/toast.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-owned-project-grid',
|
selector: 'app-owned-project-grid',
|
||||||
templateUrl: './owned-project-grid.component.html',
|
templateUrl: './owned-project-grid.component.html',
|
||||||
styleUrls: ['./owned-project-grid.component.scss'],
|
styleUrls: ['./owned-project-grid.component.scss'],
|
||||||
animations: [
|
animations: [
|
||||||
trigger('cardAnimation', [
|
trigger('cardAnimation', [
|
||||||
transition('* => *', [
|
transition('* => *', [
|
||||||
query('@animate', stagger('100ms', animateChild()), { optional: true }),
|
query('@animate', stagger('100ms', animateChild()), { optional: true }),
|
||||||
]),
|
]),
|
||||||
]),
|
]),
|
||||||
trigger('animate', [
|
trigger('animate', [
|
||||||
transition(':enter', [
|
transition(':enter', [
|
||||||
animate('.2s ease-in', keyframes([
|
animate('.2s ease-in', keyframes([
|
||||||
style({ opacity: 0, transform: 'translateY(-50%)', offset: 0 }),
|
style({ opacity: 0, transform: 'translateY(-50%)', offset: 0 }),
|
||||||
style({ opacity: .5, transform: 'translateY(-10px) scale(1.1)', offset: 0.3 }),
|
style({ opacity: .5, transform: 'translateY(-10px) scale(1.1)', offset: 0.3 }),
|
||||||
style({ opacity: 1, transform: 'translateY(0)', offset: 1 }),
|
style({ opacity: 1, transform: 'translateY(0)', offset: 1 }),
|
||||||
])),
|
])),
|
||||||
]),
|
]),
|
||||||
transition(':leave', [
|
transition(':leave', [
|
||||||
animate('.2s ease-out', keyframes([
|
animate('.2s ease-out', keyframes([
|
||||||
style({ opacity: 1, transform: 'scale(1.1)', offset: 0 }),
|
style({ opacity: 1, transform: 'scale(1.1)', offset: 0 }),
|
||||||
style({ opacity: .5, transform: 'scale(.5)', offset: 0.3 }),
|
style({ opacity: .5, transform: 'scale(.5)', offset: 0.3 }),
|
||||||
style({ opacity: 0, transform: 'scale(0)', offset: 1 }),
|
style({ opacity: 0, transform: 'scale(0)', offset: 1 }),
|
||||||
])),
|
])),
|
||||||
]),
|
]),
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class OwnedProjectGridComponent implements OnChanges {
|
export class OwnedProjectGridComponent implements OnChanges {
|
||||||
@Input() items: Array<Project.AsObject> = [];
|
@Input() items: Array<Project.AsObject> = [];
|
||||||
public notPinned: Array<Project.AsObject> = [];
|
public notPinned: Array<Project.AsObject> = [];
|
||||||
|
|
||||||
@Output() newClicked: EventEmitter<boolean> = new EventEmitter();
|
@Output() newClicked: EventEmitter<boolean> = new EventEmitter();
|
||||||
@Output() changedView: EventEmitter<boolean> = new EventEmitter();
|
@Output() changedView: EventEmitter<boolean> = new EventEmitter();
|
||||||
@Input() loading: boolean = false;
|
@Input() loading: boolean = false;
|
||||||
|
|
||||||
public selection: SelectionModel<Project.AsObject> = new SelectionModel<Project.AsObject>(true, []);
|
public selection: SelectionModel<Project.AsObject> = new SelectionModel<Project.AsObject>(true, []);
|
||||||
|
|
||||||
public showNewProject: boolean = false;
|
public showNewProject: boolean = false;
|
||||||
public ProjectState: any = ProjectState;
|
public ProjectState: any = ProjectState;
|
||||||
@Input() public zitadelProjectId: string = '';
|
@Input() public zitadelProjectId: string = '';
|
||||||
constructor(
|
constructor(
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private dialog: MatDialog,
|
private dialog: MatDialog,
|
||||||
private storage: StorageService,
|
private storage: StorageService,
|
||||||
private mgmtService: ManagementService,
|
private mgmtService: ManagementService,
|
||||||
private toast: ToastService,
|
private toast: ToastService,
|
||||||
) {
|
) {
|
||||||
this.selection.changed.subscribe(selection => {
|
this.selection.changed.subscribe(selection => {
|
||||||
this.setPrefixedItem('pinned-projects', JSON.stringify(
|
this.setPrefixedItem('pinned-projects', JSON.stringify(
|
||||||
this.selection.selected.map(item => item.id),
|
this.selection.selected.map(item => item.id),
|
||||||
)).then(() => {
|
)).then(() => {
|
||||||
selection.added.forEach(item => {
|
selection.added.forEach(item => {
|
||||||
const index = this.notPinned.findIndex(i => i.id === item.id);
|
const index = this.notPinned.findIndex(i => i.id === item.id);
|
||||||
this.notPinned.splice(index, 1);
|
this.notPinned.splice(index, 1);
|
||||||
});
|
|
||||||
this.notPinned.push(...selection.removed);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
this.notPinned.push(...selection.removed);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public selectItem(item: Project.AsObject, event?: any): void {
|
public selectItem(item: Project.AsObject, event?: any): void {
|
||||||
if (event && !event.target.classList.contains('mat-icon')) {
|
if (event && !event.target.classList.contains('mat-icon')) {
|
||||||
this.router.navigate(['/projects', item.id]);
|
this.router.navigate(['/projects', item.id]);
|
||||||
} else if (!event) {
|
} else if (!event) {
|
||||||
this.router.navigate(['/projects', item.id]);
|
this.router.navigate(['/projects', item.id]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public addItem(): void {
|
public addItem(): void {
|
||||||
this.newClicked.emit(true);
|
this.newClicked.emit(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnChanges(changes: SimpleChanges): void {
|
||||||
|
if (changes.items.currentValue && changes.items.currentValue.length > 0) {
|
||||||
|
this.notPinned = Object.assign([], this.items);
|
||||||
|
this.reorganizeItems();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public ngOnChanges(changes: SimpleChanges): void {
|
public reorganizeItems(): void {
|
||||||
if (changes.items.currentValue && changes.items.currentValue.length > 0) {
|
this.getPrefixedItem('pinned-projects').then(storageEntry => {
|
||||||
this.notPinned = Object.assign([], this.items);
|
if (storageEntry) {
|
||||||
this.reorganizeItems();
|
const array: string[] = JSON.parse(storageEntry);
|
||||||
}
|
const toSelect: Project.AsObject[] = this.items.filter((item, index) => {
|
||||||
}
|
if (array.includes(item.id)) {
|
||||||
|
return true;
|
||||||
public reorganizeItems(): void {
|
}
|
||||||
this.getPrefixedItem('pinned-projects').then(storageEntry => {
|
|
||||||
if (storageEntry) {
|
|
||||||
const array: string[] = JSON.parse(storageEntry);
|
|
||||||
const toSelect: Project.AsObject[] = this.items.filter((item, index) => {
|
|
||||||
if (array.includes(item.id)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.selection.select(...toSelect);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
this.selection.select(...toSelect);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private async getPrefixedItem(key: string): Promise<string | null> {
|
private async getPrefixedItem(key: string): Promise<string | null> {
|
||||||
const org = this.storage.getItem<Org.AsObject>(StorageKey.organization) as Org.AsObject;
|
const org = this.storage.getItem<Org.AsObject>(StorageKey.organization, StorageLocation.session) as Org.AsObject;
|
||||||
return localStorage.getItem(`${org.id}:${key}`);
|
return localStorage.getItem(`${org.id}:${key}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async setPrefixedItem(key: string, value: any): Promise<void> {
|
private async setPrefixedItem(key: string, value: any): Promise<void> {
|
||||||
const org = this.storage.getItem<Org.AsObject>(StorageKey.organization) as Org.AsObject;
|
const org = this.storage.getItem<Org.AsObject>(StorageKey.organization, StorageLocation.session) as Org.AsObject;
|
||||||
return localStorage.setItem(`${org.id}:${key}`, value);
|
return localStorage.setItem(`${org.id}:${key}`, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public navigateToProject(id: string, event: any): void {
|
public navigateToProject(id: string, event: any): void {
|
||||||
if (event && event.srcElement && event.srcElement.localName !== 'button') {
|
if (event && event.srcElement && event.srcElement.localName !== 'button') {
|
||||||
this.router.navigate(['/projects', id]);
|
this.router.navigate(['/projects', id]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public closeGridView(): void {
|
public closeGridView(): void {
|
||||||
this.changedView.emit(true);
|
this.changedView.emit(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public toggle(item: Project.AsObject, event: any): void {
|
public toggle(item: Project.AsObject, event: any): void {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
this.selection.toggle(item);
|
this.selection.toggle(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public deleteProject(event: any, item: Project.AsObject): void {
|
public deleteProject(event: any, item: Project.AsObject): void {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
const dialogRef = this.dialog.open(WarnDialogComponent, {
|
const dialogRef = this.dialog.open(WarnDialogComponent, {
|
||||||
data: {
|
data: {
|
||||||
confirmKey: 'ACTIONS.DELETE',
|
confirmKey: 'ACTIONS.DELETE',
|
||||||
cancelKey: 'ACTIONS.CANCEL',
|
cancelKey: 'ACTIONS.CANCEL',
|
||||||
titleKey: 'PROJECT.PAGES.DIALOG.DELETE.TITLE',
|
titleKey: 'PROJECT.PAGES.DIALOG.DELETE.TITLE',
|
||||||
descriptionKey: 'PROJECT.PAGES.DIALOG.DELETE.DESCRIPTION',
|
descriptionKey: 'PROJECT.PAGES.DIALOG.DELETE.DESCRIPTION',
|
||||||
},
|
},
|
||||||
width: '400px',
|
width: '400px',
|
||||||
|
});
|
||||||
|
|
||||||
|
dialogRef.afterClosed().subscribe(resp => {
|
||||||
|
if (resp && item.id !== this.zitadelProjectId) {
|
||||||
|
this.mgmtService.removeProject(item.id).then(() => {
|
||||||
|
this.toast.showInfo('PROJECT.TOAST.DELETED', true);
|
||||||
|
const index = this.items.findIndex(iter => iter.id === item.id);
|
||||||
|
if (index > -1) {
|
||||||
|
this.items.splice(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const indexSelection = this.selection.selected.findIndex(iter => iter.id === item.id);
|
||||||
|
if (indexSelection > -1) {
|
||||||
|
this.selection.selected.splice(indexSelection, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const indexPinned = this.notPinned.findIndex(iter => iter.id === item.id);
|
||||||
|
if (indexPinned > -1) {
|
||||||
|
this.notPinned.splice(indexPinned, 1);
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
this.toast.showError(error);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
dialogRef.afterClosed().subscribe(resp => {
|
});
|
||||||
if (resp && item.id !== this.zitadelProjectId) {
|
}
|
||||||
this.mgmtService.removeProject(item.id).then(() => {
|
|
||||||
this.toast.showInfo('PROJECT.TOAST.DELETED', true);
|
|
||||||
const index = this.items.findIndex(iter => iter.id === item.id);
|
|
||||||
if (index > -1) {
|
|
||||||
this.items.splice(index, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const indexSelection = this.selection.selected.findIndex(iter => iter.id === item.id);
|
|
||||||
if (indexSelection > -1) {
|
|
||||||
this.selection.selected.splice(indexSelection, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const indexPinned = this.notPinned.findIndex(iter => iter.id === item.id);
|
|
||||||
if (indexPinned > -1) {
|
|
||||||
this.notPinned.splice(indexPinned, 1);
|
|
||||||
}
|
|
||||||
}).catch(error => {
|
|
||||||
this.toast.showError(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,6 @@ export class OwnedProjectListComponent implements OnInit, OnDestroy {
|
|||||||
if (resp.details?.viewTimestamp) {
|
if (resp.details?.viewTimestamp) {
|
||||||
this.viewTimestamp = resp.details?.viewTimestamp;
|
this.viewTimestamp = resp.details?.viewTimestamp;
|
||||||
}
|
}
|
||||||
console.log(resp.resultList);
|
|
||||||
this.dataSource.data = this.ownedProjectList;
|
this.dataSource.data = this.ownedProjectList;
|
||||||
this.loadingSubject.next(false);
|
this.loadingSubject.next(false);
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
|
@ -9,7 +9,7 @@ import { GrantedProject, Project, Role } from 'src/app/proto/generated/zitadel/p
|
|||||||
import { User } from 'src/app/proto/generated/zitadel/user_pb';
|
import { User } from 'src/app/proto/generated/zitadel/user_pb';
|
||||||
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||||
import { StorageKey, StorageService } from 'src/app/services/storage.service';
|
import { StorageKey, StorageLocation, StorageService } from 'src/app/services/storage.service';
|
||||||
import { ToastService } from 'src/app/services/toast.service';
|
import { ToastService } from 'src/app/services/toast.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -94,7 +94,7 @@ export class UserGrantCreateComponent implements OnDestroy {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const temporg = this.storage.getItem<Org.AsObject>(StorageKey.organization);
|
const temporg = this.storage.getItem<Org.AsObject>(StorageKey.organization, StorageLocation.session);
|
||||||
if (temporg) {
|
if (temporg) {
|
||||||
this.org = temporg;
|
this.org = temporg;
|
||||||
}
|
}
|
||||||
|
@ -187,6 +187,7 @@ export class GrpcAuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public setActiveOrg(org: Org.AsObject): void {
|
public setActiveOrg(org: Org.AsObject): void {
|
||||||
|
// Set organization in localstorage to get the last used organization in a new tab
|
||||||
this.storage.setItem(StorageKey.organization, org, StorageLocation.local);
|
this.storage.setItem(StorageKey.organization, org, StorageLocation.local);
|
||||||
this.storage.setItem(StorageKey.organization, org, StorageLocation.session);
|
this.storage.setItem(StorageKey.organization, org, StorageLocation.session);
|
||||||
this._activeOrgChanged.next(org);
|
this._activeOrgChanged.next(org);
|
||||||
|
@ -3,10 +3,9 @@ import { OAuthModuleConfig } from 'angular-oauth2-oidc';
|
|||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
import { Org } from '../../proto/generated/zitadel/org_pb';
|
import { Org } from '../../proto/generated/zitadel/org_pb';
|
||||||
import { StorageService } from '../storage.service';
|
import { StorageKey, StorageLocation, StorageService } from '../storage.service';
|
||||||
|
|
||||||
const orgKey = 'x-zitadel-orgid';
|
const orgKey = 'x-zitadel-orgid';
|
||||||
const ORG_STORAGE_KEY = 'organization';
|
|
||||||
export abstract class HttpOrgInterceptor implements HttpInterceptor {
|
export abstract class HttpOrgInterceptor implements HttpInterceptor {
|
||||||
private org!: Org.AsObject;
|
private org!: Org.AsObject;
|
||||||
|
|
||||||
@ -18,7 +17,7 @@ export abstract class HttpOrgInterceptor implements HttpInterceptor {
|
|||||||
private storageService: StorageService,
|
private storageService: StorageService,
|
||||||
protected oauthModuleConfig: OAuthModuleConfig,
|
protected oauthModuleConfig: OAuthModuleConfig,
|
||||||
) {
|
) {
|
||||||
const org: Org.AsObject | null = (this.storageService.getItem(ORG_STORAGE_KEY));
|
const org: Org.AsObject | null = (this.storageService.getItem(StorageKey.organization, StorageLocation.session));
|
||||||
|
|
||||||
if (org) {
|
if (org) {
|
||||||
this.org = org;
|
this.org = org;
|
||||||
|
@ -2,31 +2,30 @@ import { Injectable } from '@angular/core';
|
|||||||
import { Request, UnaryInterceptor, UnaryResponse } from 'grpc-web';
|
import { Request, UnaryInterceptor, UnaryResponse } from 'grpc-web';
|
||||||
import { Org } from 'src/app/proto/generated/zitadel/org_pb';
|
import { Org } from 'src/app/proto/generated/zitadel/org_pb';
|
||||||
|
|
||||||
import { StorageService } from '../storage.service';
|
import { StorageKey, StorageLocation, StorageService } from '../storage.service';
|
||||||
|
|
||||||
|
|
||||||
const ORG_HEADER_KEY = 'x-zitadel-orgid';
|
const ORG_HEADER_KEY = 'x-zitadel-orgid';
|
||||||
const ORG_STORAGE_KEY = 'organization';
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class OrgInterceptor<TReq = unknown, TResp = unknown> implements UnaryInterceptor<TReq, TResp> {
|
export class OrgInterceptor<TReq = unknown, TResp = unknown> implements UnaryInterceptor<TReq, TResp> {
|
||||||
constructor(private readonly storageService: StorageService) { }
|
constructor(private readonly storageService: StorageService) { }
|
||||||
|
|
||||||
public intercept(request: Request<TReq, TResp>, invoker: any): Promise<UnaryResponse<TReq, TResp>> {
|
public intercept(request: Request<TReq, TResp>, invoker: any): Promise<UnaryResponse<TReq, TResp>> {
|
||||||
const metadata = request.getMetadata();
|
const metadata = request.getMetadata();
|
||||||
|
|
||||||
const org: Org.AsObject | null = (this.storageService.getItem(ORG_STORAGE_KEY));
|
const org: Org.AsObject | null = (this.storageService.getItem(StorageKey.organization, StorageLocation.session));
|
||||||
|
|
||||||
if (org) {
|
if (org) {
|
||||||
metadata[ORG_HEADER_KEY] = `${org.id}`;
|
metadata[ORG_HEADER_KEY] = `${org.id}`;
|
||||||
}
|
|
||||||
|
|
||||||
return invoker(request).then((response: any) => {
|
|
||||||
return response;
|
|
||||||
}).catch((error: any) => {
|
|
||||||
if (error.code === 7 && error.message.startsWith('Organisation doesn\'t exist')) {
|
|
||||||
this.storageService.removeItem(ORG_STORAGE_KEY);
|
|
||||||
}
|
|
||||||
return Promise.reject(error);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return invoker(request).then((response: any) => {
|
||||||
|
return response;
|
||||||
|
}).catch((error: any) => {
|
||||||
|
if (error.code === 7 && error.message.startsWith('Organisation doesn\'t exist')) {
|
||||||
|
this.storageService.removeItem(StorageKey.organization, StorageLocation.session);
|
||||||
|
}
|
||||||
|
return Promise.reject(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,48 +4,48 @@ import { OAuthStorage } from 'angular-oauth2-oidc';
|
|||||||
const STORAGE_PREFIX = 'zitadel';
|
const STORAGE_PREFIX = 'zitadel';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class StorageService implements OAuthStorage {
|
export class StorageService implements OAuthStorage {
|
||||||
private sessionStorage: Storage = window.sessionStorage;
|
private sessionStorage: Storage = window.sessionStorage;
|
||||||
private localStorage: Storage = window.localStorage;
|
private localStorage: Storage = window.localStorage;
|
||||||
|
|
||||||
constructor() { }
|
constructor() { }
|
||||||
|
|
||||||
public setItem<TValue = string>(key: string, value: TValue, location: StorageLocation = StorageLocation.session): void {
|
public setItem<TValue = string>(key: string, value: TValue, location: StorageLocation = StorageLocation.session): void {
|
||||||
this.getStorage(location).setItem(this.getPrefixedKey(key), JSON.stringify(value));
|
this.getStorage(location).setItem(this.getPrefixedKey(key), JSON.stringify(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public getItem<TResult = string>(key: string, location: StorageLocation = StorageLocation.session): TResult | null {
|
||||||
|
const result = this.getStorage(location).getItem(this.getPrefixedKey(key));
|
||||||
|
if (result) {
|
||||||
|
return JSON.parse(result);
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public getItem<TResult = string>(key: string, location: StorageLocation = StorageLocation.session): TResult | null {
|
public removeItem(key: string, location: StorageLocation = StorageLocation.session): void {
|
||||||
const result = this.getStorage(location).getItem(this.getPrefixedKey(key));
|
this.getStorage(location).removeItem(this.getPrefixedKey(key));
|
||||||
if (result) {
|
}
|
||||||
return JSON.parse(result);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public removeItem(key: string, location: StorageLocation = StorageLocation.session): void {
|
public getPrefixedKey(key: string): string {
|
||||||
this.getStorage(location).removeItem(this.getPrefixedKey(key));
|
return `${STORAGE_PREFIX}:${key}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getPrefixedKey(key: string): string {
|
private getStorage(location: StorageLocation): Storage {
|
||||||
return `${STORAGE_PREFIX}:${key}`;
|
return location === StorageLocation.session
|
||||||
}
|
? this.sessionStorage
|
||||||
|
: this.localStorage;
|
||||||
private getStorage(location: StorageLocation): Storage {
|
}
|
||||||
return location === StorageLocation.session
|
|
||||||
? this.sessionStorage
|
|
||||||
: this.localStorage;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class StorageConfig {
|
export class StorageConfig {
|
||||||
clientId: string = '';
|
clientId: string = '';
|
||||||
storage: Storage = window.sessionStorage;
|
storage: Storage = window.sessionStorage;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum StorageKey {
|
export enum StorageKey {
|
||||||
organization = 'organization',
|
organization = 'organization',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum StorageLocation {
|
export enum StorageLocation {
|
||||||
|
@ -820,7 +820,8 @@
|
|||||||
"passwordlessPromptText":"Passwordless Aufforderung",
|
"passwordlessPromptText":"Passwordless Aufforderung",
|
||||||
"passwordlessRegistrationDoneText":"Passwordless setzen erfolgreich",
|
"passwordlessRegistrationDoneText":"Passwordless setzen erfolgreich",
|
||||||
"passwordlessRegistrationText":"Passwordless Registrierung",
|
"passwordlessRegistrationText":"Passwordless Registrierung",
|
||||||
"passwordlessText":"Passwordless"
|
"passwordlessText":"Passwordless",
|
||||||
|
"externalRegistrationUserOverviewText":"Externe Registrierung Benutzer Übersicht"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"MESSAGE_TEXTS": {
|
"MESSAGE_TEXTS": {
|
||||||
|
@ -822,7 +822,8 @@
|
|||||||
"passwordlessPromptText":"Passwordless Prompt",
|
"passwordlessPromptText":"Passwordless Prompt",
|
||||||
"passwordlessRegistrationDoneText":"Passwordless Registration Done",
|
"passwordlessRegistrationDoneText":"Passwordless Registration Done",
|
||||||
"passwordlessRegistrationText":"Passwordless Registration",
|
"passwordlessRegistrationText":"Passwordless Registration",
|
||||||
"passwordlessText":"Passwordless"
|
"passwordlessText":"Passwordless",
|
||||||
|
"externalRegistrationUserOverviewText":"External Registration User Overview"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"MESSAGE_TEXTS": {
|
"MESSAGE_TEXTS": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user