From b8798230b06ff8c286425d7b4bb45c8522180245 Mon Sep 17 00:00:00 2001 From: Max Peintner Date: Tue, 7 Jul 2020 11:50:42 +0200 Subject: [PATCH] fix(console): ui/ux improvements, delete user phone, pinned cards, user grant role load fix (#357) * project grant member edit * project grant member dialog, import cleanup * readd project roles * user login-methods cleanup * fix sw config, user grant context * delete user grants, context for creation, search * contributor box shadow * password to detail view * user detail notification * ui ux improvements * pinned section * project pinnable grid, rem columns, move buttons * user detail mfa, move user comonents, user grant * del phone * user detail service * delete phone for auth, mgmt user --- console/src/app/app.component.html | 21 +- console/src/app/app.component.scss | 21 +- .../user-grants/user-grants.component.html | 27 +- .../user-grants/user-grants.component.ts | 5 +- .../granted-project-detail.component.html | 6 +- .../granted-project-grid.component.html | 79 +-- .../granted-project-grid.component.scss | 28 +- .../granted-project-grid.component.ts | 73 ++- .../granted-project-list.component.html | 14 +- .../granted-project-list.component.ts | 5 +- .../granted-projects.component.ts | 25 +- .../granted-projects.module.ts | 2 - .../orgs/org-create/org-create.component.html | 4 +- .../orgs/org-detail/org-detail.component.html | 17 +- .../orgs/org-detail/org-detail.component.ts | 2 + .../owned-project-detail.component.html | 47 +- .../owned-project-detail.component.scss | 8 + .../owned-project-grid.component.html | 67 +-- .../owned-project-grid.component.scss | 23 +- .../owned-project-grid.component.ts | 73 ++- .../owned-project-list.component.ts | 3 + .../owned-projects.component.ts | 25 +- .../owned-projects/owned-projects.module.ts | 2 - .../project-grants.component.html | 6 - .../project-grants.component.ts | 6 +- .../auth-user-detail.component.html | 10 +- .../auth-user-detail.component.ts | 36 +- .../auth-user-mfa.component.html | 6 +- .../auth-user-mfa.component.scss | 0 .../auth-user-mfa.component.spec.ts | 0 .../auth-user-mfa/auth-user-mfa.component.ts | 0 .../code-dialog/code-dialog.component.html | 0 .../code-dialog/code-dialog.component.scss | 0 .../code-dialog/code-dialog.component.spec.ts | 0 .../code-dialog/code-dialog.component.ts | 0 .../dialog-otp/dialog-otp.component.html | 0 .../dialog-otp/dialog-otp.component.scss | 0 .../dialog-otp/dialog-otp.component.ts | 0 .../code-dialog/code-dialog.module.ts | 34 -- .../password/password.component.spec.ts | 3 +- .../pages/user-detail/user-detail.module.ts | 10 +- .../user-detail/user-detail.component.html | 34 +- .../user-detail/user-detail.component.scss | 8 + .../user-detail/user-detail.component.ts | 47 ++ .../user-mfa/user-mfa.component.html | 3 +- .../app/proto/generated/auth_grpc_web_pb.d.ts | 25 + .../app/proto/generated/auth_grpc_web_pb.js | 160 ++++++ console/src/app/proto/generated/auth_pb.d.ts | 62 +++ console/src/app/proto/generated/auth_pb.js | 467 ++++++++++++++++++ .../generated/management_grpc_web_pb.d.ts | 12 + .../proto/generated/management_grpc_web_pb.js | 80 +++ console/src/app/services/auth-user.service.ts | 8 + console/src/app/services/mgmt-user.service.ts | 10 + console/src/app/services/storage.service.ts | 4 +- console/src/assets/i18n/de.json | 23 +- console/src/assets/i18n/en.json | 29 +- console/src/styles/table.scss | 2 +- 57 files changed, 1299 insertions(+), 363 deletions(-) rename console/src/app/pages/user-detail/{ => auth-user-detail}/auth-user-mfa/auth-user-mfa.component.html (70%) rename console/src/app/pages/user-detail/{ => auth-user-detail}/auth-user-mfa/auth-user-mfa.component.scss (100%) rename console/src/app/pages/user-detail/{ => auth-user-detail}/auth-user-mfa/auth-user-mfa.component.spec.ts (100%) rename console/src/app/pages/user-detail/{ => auth-user-detail}/auth-user-mfa/auth-user-mfa.component.ts (100%) rename console/src/app/pages/user-detail/{ => auth-user-detail}/code-dialog/code-dialog.component.html (100%) rename console/src/app/pages/user-detail/{ => auth-user-detail}/code-dialog/code-dialog.component.scss (100%) rename console/src/app/pages/user-detail/{ => auth-user-detail}/code-dialog/code-dialog.component.spec.ts (100%) rename console/src/app/pages/user-detail/{ => auth-user-detail}/code-dialog/code-dialog.component.ts (100%) rename console/src/app/pages/user-detail/{ => auth-user-detail}/dialog-otp/dialog-otp.component.html (100%) rename console/src/app/pages/user-detail/{ => auth-user-detail}/dialog-otp/dialog-otp.component.scss (100%) rename console/src/app/pages/user-detail/{ => auth-user-detail}/dialog-otp/dialog-otp.component.ts (100%) delete mode 100644 console/src/app/pages/user-detail/code-dialog/code-dialog.module.ts diff --git a/console/src/app/app.component.html b/console/src/app/app.component.html index f9d20ed499..428cff6f7a 100644 --- a/console/src/app/app.component.html +++ b/console/src/app/app.component.html @@ -59,7 +59,9 @@ {{ 'MENU.PERSONAL_INFO' | translate }} -
+
+
+
@@ -71,12 +73,17 @@ {{org?.name ? org.name : 'MENU.ORGANIZATION' | translate}} -
+
+
+ {{'MENU.PROJECTSSECTION' | translate}} +
+
- {{ 'MENU.PROJECT' | translate }} + {{org?.name ? org.name : 'MENU.ORGANIZATION' | translate}} + {{ 'MENU.PROJECT' | translate }} {{ 'MENU.GRANTEDPROJECT' | translate }} -
+
+
+ + {{ 'MENU.USERSECTION' | translate }} +
+ +
diff --git a/console/src/app/app.component.scss b/console/src/app/app.component.scss index 506bd33b08..dc1fcff92e 100644 --- a/console/src/app/app.component.scss +++ b/console/src/app/app.component.scss @@ -194,8 +194,23 @@ } .divider { - display: block; - background-color: #ffffff10; - height: 1px; + display: flex; + align-items: center; + width: 100%; margin: .5rem 0; + + span { + border: 1px solid #ffffff10; + padding: 2px 1rem; + border-radius: .5rem; + color: #8795a1; + font-size: 12px; + } + .line { + display: block; + background-color: #ffffff10; + height: 1px; + margin: .5rem 0; + flex: 1; + } } \ No newline at end of file diff --git a/console/src/app/modules/user-grants/user-grants.component.html b/console/src/app/modules/user-grants/user-grants.component.html index f3aa5212f0..3838270c31 100644 --- a/console/src/app/modules/user-grants/user-grants.component.html +++ b/console/src/app/modules/user-grants/user-grants.component.html @@ -77,25 +77,22 @@ {{ 'PROJECT.GRANT.ROLENAMESLIST' | translate }} - - - + + {{role}} - - - {{ 'PROJECT.GRANT.TITLE' | translate }} - - - {{ role.displayName }} {{role.key}} - - - - + + {{ 'PROJECT.GRANT.TITLE' | translate }} + + + {{role.key}} + + + diff --git a/console/src/app/modules/user-grants/user-grants.component.ts b/console/src/app/modules/user-grants/user-grants.component.ts index a46a202478..d620009d04 100644 --- a/console/src/app/modules/user-grants/user-grants.component.ts +++ b/console/src/app/modules/user-grants/user-grants.component.ts @@ -37,6 +37,7 @@ export class UserGrantsComponent implements OnInit, AfterViewInit { public roleOptions: ProjectRoleView.AsObject[] = []; public routerLink: any = ['']; + public loadedProjectId: string = ''; constructor( private userService: MgmtUserService, private projectService: ProjectService, @@ -121,16 +122,14 @@ export class UserGrantsComponent implements OnInit, AfterViewInit { public getRoleOptions(projectId: string): void { this.projectService.SearchProjectRoles(projectId, 100, 0).then(resp => { + this.loadedProjectId = projectId; this.roleOptions = resp.toObject().resultList; - console.log(this.roleOptions); }); } updateRoles(grant: UserGrant.AsObject, selectionChange: MatSelectChange): void { - console.log(grant, selectionChange.value); this.userService.UpdateUserGrant(grant.id, grant.userId, selectionChange.value) .then((newmember: UserGrant) => { - console.log(newmember.toObject()); this.toast.showInfo('Grant updated!'); }).catch(error => { this.toast.showError(error.message); diff --git a/console/src/app/pages/granted-projects/granted-project-detail/granted-project-detail.component.html b/console/src/app/pages/granted-projects/granted-project-detail/granted-project-detail.component.html index ff813d2b05..dcbe2f8065 100644 --- a/console/src/app/pages/granted-projects/granted-project-detail/granted-project-detail.component.html +++ b/console/src/app/pages/granted-projects/granted-project-detail/granted-project-detail.component.html @@ -1,7 +1,7 @@
- + arrow_back

{{ 'PROJECT.PAGES.TITLE' | translate }} {{project?.projectName}}

@@ -24,10 +24,6 @@
-
- {{'PROJECT.TYPE.TITLE' | translate}}: - {{'PROJECT.TYPE.'+ ProjectType.PROJECTTYPE_GRANTED | translate}} -
{{'PROJECT.STATE.TITLE' | translate}}: -
- -
-
-
- - check_circle + +

{{'PROJECT.PAGES.PINNED' | translate}}

+ +
- last modified on + {{'PROJECT.PAGES.LASTMODIFIED' | translate}} {{ item.changeDate | timestampToDate | date: 'EEE dd. MMM, HH:mm' }} {{ item.projectName }} - {{item.grantedOrgName}} - - created on - {{ - item.creationDate | timestampToDate | date: 'EEE dd. MMM, HH:mm' - }} + {{item.resourceOwnerName}} + {{'PROJECT.PAGES.CREATEDON' | translate}} + {{ item.creationDate | timestampToDate | date: 'EEE dd. MMM, HH:mm' }}
- - - - - - - -
-

{{'PROJECT.PAGES.NOITEMS' | translate}}

+ +
+
+

{{'PROJECT.PAGES.ALL' | translate}}

+ +
+
+ {{'PROJECT.PAGES.LASTMODIFIED' | translate}} + {{ + item.changeDate | timestampToDate | date: 'EEE dd. MMM, HH:mm' + }} + {{ item.projectName }} + {{item.resourceOwnerName}} + {{'PROJECT.PAGES.CREATEDON' | translate}} + {{ item.creationDate | timestampToDate | date: 'EEE dd. MMM, HH:mm' }} + +
+
+
+ +
+

+ {{'PROJECT.PAGES.NOITEMS' | translate}}

\ No newline at end of file diff --git a/console/src/app/pages/granted-projects/granted-project-grid/granted-project-grid.component.scss b/console/src/app/pages/granted-projects/granted-project-grid/granted-project-grid.component.scss index 7fce400eec..f0e971d09a 100644 --- a/console/src/app/pages/granted-projects/granted-project-grid/granted-project-grid.component.scss +++ b/console/src/app/pages/granted-projects/granted-project-grid/granted-project-grid.component.scss @@ -52,18 +52,6 @@ color: #8795a1; } - .selection-icon { - opacity: 0; - position: absolute; - top: -12px; - left: -12px; - user-select: none; - - &:hover { - color: white; - } - } - img { height: 50px; width: 50px; @@ -136,16 +124,26 @@ } .edit-button { + opacity: 0; + user-select: none; position: absolute; bottom: 0; right: 0; margin: 0; margin-bottom: 0.25rem; + color: #8795a1; + + &:hover { + color: white; + } + + &.selected { + opacity: 1; + } } - &:hover { - .selection-icon { + .edit-button { opacity: 1; } @@ -163,7 +161,7 @@ } } - .selection-icon { + .edit-button { opacity: 1; } diff --git a/console/src/app/pages/granted-projects/granted-project-grid/granted-project-grid.component.ts b/console/src/app/pages/granted-projects/granted-project-grid/granted-project-grid.component.ts index 9674bbf4e7..0aa1437bfd 100644 --- a/console/src/app/pages/granted-projects/granted-project-grid/granted-project-grid.component.ts +++ b/console/src/app/pages/granted-projects/granted-project-grid/granted-project-grid.component.ts @@ -1,10 +1,8 @@ import { animate, animateChild, query, stagger, style, transition, trigger } from '@angular/animations'; import { SelectionModel } from '@angular/cdk/collections'; -import { Component, EventEmitter, Input, Output } from '@angular/core'; -import { Router } from '@angular/router'; -import { ProjectGrantView, ProjectState, ProjectType, ProjectView } from 'src/app/proto/generated/management_pb'; -import { ProjectService } from 'src/app/services/project.service'; -import { ToastService } from 'src/app/services/toast.service'; +import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; +import { ProjectGrantView, ProjectState, ProjectType } from 'src/app/proto/generated/management_pb'; +import { AuthService } from 'src/app/services/auth.service'; @Component({ selector: 'app-granted-project-grid', @@ -30,30 +28,73 @@ import { ToastService } from 'src/app/services/toast.service'; ]), ], }) -export class GrantedProjectGridComponent { +export class GrantedProjectGridComponent implements OnChanges { @Input() items: Array = []; + public notPinned: Array = []; @Output() newClicked: EventEmitter = new EventEmitter(); @Output() changedView: EventEmitter = new EventEmitter(); @Input() loading: boolean = false; - - public selection: SelectionModel = new SelectionModel(true, []); - public selectedIndex: number = -1; + public selection: SelectionModel = new SelectionModel(true, []); public showNewProject: boolean = false; public ProjectState: any = ProjectState; public ProjectType: any = ProjectType; - constructor(private router: Router, private projectService: ProjectService, private toast: ToastService) { } + constructor(private authService: AuthService) { + this.selection.changed.subscribe(selection => { + this.setPrefixedItem('pinned-granted-projects', JSON.stringify( + this.selection.selected.map(item => item.projectId), + )).then(() => { + const filtered = this.notPinned.filter(item => item === selection.added.find(i => i === item)); + filtered.forEach((f, i) => { + this.notPinned.splice(i, 1); + }); - public selectItem(item: ProjectGrantView.AsObject, event?: any): void { - if (event && !event.target.classList.contains('mat-icon')) { - this.router.navigate(['granted-projects', item.projectId, 'grant', `${item.id}`]); - } else if (!event) { - this.router.navigate(['granted-projects', item.projectId, 'grant', `${item.id}`]); - } + this.notPinned.push(...selection.removed); + }); + }); } public addItem(): void { 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 reorganizeItems(): void { + this.getPrefixedItem('pinned-granted-projects').then(storageEntry => { + if (storageEntry) { + const array: string[] = JSON.parse(storageEntry); + const toSelect: ProjectGrantView.AsObject[] = this.items.filter((item, index) => { + if (array.includes(item.projectId)) { + // this.notPinned.splice(index, 1); + return true; + } + }); + this.selection.select(...toSelect); + + const toNotPinned: ProjectGrantView.AsObject[] = this.items.filter((item, index) => { + if (!array.includes(item.projectId)) { + return true; + } + }); + this.notPinned = toNotPinned; + } + }); + } + + private async getPrefixedItem(key: string): Promise { + const prefix = (await this.authService.GetActiveOrg()).id; + return localStorage.getItem(`${prefix}:${key}`); + } + + private async setPrefixedItem(key: string, value: any): Promise { + const prefix = (await this.authService.GetActiveOrg()).id; + return localStorage.setItem(`${prefix}:${key}`, value); + } } diff --git a/console/src/app/pages/granted-projects/granted-project-list/granted-project-list.component.html b/console/src/app/pages/granted-projects/granted-project-list/granted-project-list.component.html index eb043daae5..ddc4c6a986 100644 --- a/console/src/app/pages/granted-projects/granted-project-list/granted-project-list.component.html +++ b/console/src/app/pages/granted-projects/granted-project-list/granted-project-list.component.html @@ -53,19 +53,13 @@ {{ 'PROJECT.NAME' | translate }} - {{project.name}} + {{project.projectName}} - - {{ 'PROJECT.TABLE.ORGNAME' | translate }} + + {{ 'PROJECT.TABLE.RESOURCEOWNER' | translate }} - {{project.orgName}} - - - - {{ 'PROJECT.TABLE.ORGDOMAIN' | translate }} - - {{project?.orgDomain}} + {{project.resourceOwnerName}} diff --git a/console/src/app/pages/granted-projects/granted-project-list/granted-project-list.component.ts b/console/src/app/pages/granted-projects/granted-project-list/granted-project-list.component.ts index 6dd12c675b..39f12c7d5b 100644 --- a/console/src/app/pages/granted-projects/granted-project-list/granted-project-list.component.ts +++ b/console/src/app/pages/granted-projects/granted-project-list/granted-project-list.component.ts @@ -40,7 +40,7 @@ export class GrantedProjectListComponent implements OnInit, OnDestroy { new MatTableDataSource(); public grantedProjectList: ProjectGrantView.AsObject[] = []; - public displayedColumns: string[] = ['select', 'name', 'orgName', 'orgDomain', 'state', 'creationDate', 'changeDate']; + public displayedColumns: string[] = ['select', 'name', 'resourceOwnerName', 'state', 'creationDate', 'changeDate']; public selection: SelectionModel = new SelectionModel(true, []); private loadingSubject: BehaviorSubject = new BehaviorSubject(false); @@ -88,6 +88,9 @@ export class GrantedProjectListComponent implements OnInit, OnDestroy { this.projectService.SearchGrantedProjects(limit, offset).then(res => { this.grantedProjectList = res.toObject().resultList; this.totalResult = res.toObject().totalResult; + if (this.totalResult > 5) { + this.grid = false; + } this.dataSource.data = this.grantedProjectList; this.loadingSubject.next(false); }).catch(error => { diff --git a/console/src/app/pages/granted-projects/granted-projects.component.ts b/console/src/app/pages/granted-projects/granted-projects.component.ts index 544cc493dc..040108b4a6 100644 --- a/console/src/app/pages/granted-projects/granted-projects.component.ts +++ b/console/src/app/pages/granted-projects/granted-projects.component.ts @@ -1,29 +1,10 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { Subscription } from 'rxjs'; +import { Component } from '@angular/core'; @Component({ selector: 'app-granted-projects', templateUrl: './granted-projects.component.html', styleUrls: ['./granted-projects.component.scss'], }) -export class GrantedProjectsComponent implements OnInit, OnDestroy { - // public projectId: string = ''; - // public grantId: string = ''; - private sub: Subscription = new Subscription(); - constructor(private route: ActivatedRoute, - ) { - // this.route.params.subscribe((params) => { - // this.projectId = params.projectId; - // this.grantId = params.grantId; - // }); - } - - ngOnInit(): void { - } - - - public ngOnDestroy(): void { - // this.sub.unsubscribe(); - } +export class GrantedProjectsComponent { + constructor() { } } diff --git a/console/src/app/pages/granted-projects/granted-projects.module.ts b/console/src/app/pages/granted-projects/granted-projects.module.ts index 1d1b62285a..8429ea4706 100644 --- a/console/src/app/pages/granted-projects/granted-projects.module.ts +++ b/console/src/app/pages/granted-projects/granted-projects.module.ts @@ -7,7 +7,6 @@ import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; -import { MatMenuModule } from '@angular/material/menu'; import { MatPaginatorModule } from '@angular/material/paginator'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; @@ -51,7 +50,6 @@ import { GrantedProjectsComponent } from './granted-projects.component'; HasRoleModule, MatTableModule, MatPaginatorModule, - MatMenuModule, MatFormFieldModule, MatInputModule, ChangesModule, diff --git a/console/src/app/pages/orgs/org-create/org-create.component.html b/console/src/app/pages/orgs/org-create/org-create.component.html index 60f7c00aa7..2b1d72a1dc 100644 --- a/console/src/app/pages/orgs/org-create/org-create.component.html +++ b/console/src/app/pages/orgs/org-create/org-create.component.html @@ -23,7 +23,7 @@
-
+ diff --git a/console/src/app/pages/orgs/org-detail/org-detail.component.html b/console/src/app/pages/orgs/org-detail/org-detail.component.html index 788916c2d0..70cfef1d4e 100644 --- a/console/src/app/pages/orgs/org-detail/org-detail.component.html +++ b/console/src/app/pages/orgs/org-detail/org-detail.component.html @@ -8,11 +8,8 @@
{{domain.domain}} - + -
@@ -27,11 +24,6 @@ - - -
@@ -43,12 +35,11 @@
- Domains: - {{domain.domain}} + {{'ORG.PAGES.PRIMARYDOMAIN' | translate}} + {{primaryDomain}}
- State: + {{'ORG.PAGES.STATE' | translate}} {{'ORG.STATE.'+org.state | translate}}
diff --git a/console/src/app/pages/orgs/org-detail/org-detail.component.ts b/console/src/app/pages/orgs/org-detail/org-detail.component.ts index ff83986f15..4e7edaaa2a 100644 --- a/console/src/app/pages/orgs/org-detail/org-detail.component.ts +++ b/console/src/app/pages/orgs/org-detail/org-detail.component.ts @@ -28,6 +28,7 @@ export class OrgDetailComponent implements OnInit, OnDestroy { private subscription: Subscription = new Subscription(); public domains: OrgDomainView.AsObject[] = []; + public primaryDomain: string = ''; public newDomain: string = ''; constructor( @@ -53,6 +54,7 @@ export class OrgDetailComponent implements OnInit, OnDestroy { this.orgService.SearchMyOrgDomains(0, 100).then(result => { this.domains = result.toObject().resultList; + this.primaryDomain = this.domains.find(domain => domain.primary)?.domain ?? ''; }); } diff --git a/console/src/app/pages/owned-projects/owned-project-detail/owned-project-detail.component.html b/console/src/app/pages/owned-projects/owned-project-detail/owned-project-detail.component.html index e8b257015b..50bf13e34e 100644 --- a/console/src/app/pages/owned-projects/owned-project-detail/owned-project-detail.component.html +++ b/console/src/app/pages/owned-projects/owned-project-detail/owned-project-detail.component.html @@ -13,31 +13,34 @@ + + + + +
- - - Project Name - - - - - - +
+ + + {{'PROJECT.NAME' | translate}} + + + + + +

{{ 'PROJECT.PAGES.DESCRIPTION' | translate }}

-

This belongs to Zitadel project. If you change something, - Zitadel - may not behave as intended!

+

{{'PROJECT.PAGES.ZITADELPROJECT' | translate}}

-
-
- {{'PROJECT.TYPE.TITLE' | translate}}: - {{'PROJECT.TYPE.'+ ProjectType.PROJECTTYPE_OWNED | translate}} -
{{'PROJECT.STATE.TITLE' | translate}}: -
- - - - -
@@ -18,19 +6,19 @@
-
- - check_circle + +

{{'PROJECT.PAGES.PINNED' | translate}}

+ +
- last modified on + {{'PROJECT.PAGES.LASTMODIFIED' | translate}} {{ item.changeDate | timestampToDate | date: 'EEE dd. MMM, HH:mm' }} {{ item.name }} - - created on + {{'PROJECT.PAGES.CREATEDON' | translate}} {{ item.creationDate | timestampToDate | date: 'EEE dd. MMM, HH:mm' }} @@ -38,20 +26,37 @@
- +
- - - - - - +
+
+

{{'PROJECT.PAGES.ALL' | translate}}

+ +
+
+ {{'PROJECT.PAGES.LASTMODIFIED' | translate}} + {{ + item.changeDate | timestampToDate | date: 'EEE dd. MMM, HH:mm' + }} + {{ item.name }} + + {{'PROJECT.PAGES.CREATEDON' | translate}} + {{ + item.creationDate | timestampToDate | date: 'EEE dd. MMM, HH:mm' + }} + +
+
+
+

{{'PROJECT.PAGES.NOITEMS' | translate}}

diff --git a/console/src/app/pages/owned-projects/owned-project-grid/owned-project-grid.component.scss b/console/src/app/pages/owned-projects/owned-project-grid/owned-project-grid.component.scss index 82714b1ae3..93d55018c5 100644 --- a/console/src/app/pages/owned-projects/owned-project-grid/owned-project-grid.component.scss +++ b/console/src/app/pages/owned-projects/owned-project-grid/owned-project-grid.component.scss @@ -52,14 +52,6 @@ color: #8795a1; } - .selection-icon { - opacity: 0; - position: absolute; - top: -12px; - left: -12px; - user-select: none; - } - img { height: 50px; width: 50px; @@ -132,16 +124,27 @@ } .edit-button { + opacity: 0; + user-select: none; position: absolute; bottom: 0; right: 0; margin: 0; margin-bottom: 0.25rem; + color: #8795a1; + + &:hover { + color: white; + } + + &.selected { + opacity: 1; + } } &:hover { - .selection-icon { + .edit-button { opacity: 1; } @@ -159,7 +162,7 @@ } } - .selection-icon { + .edit-button { opacity: 1; } diff --git a/console/src/app/pages/owned-projects/owned-project-grid/owned-project-grid.component.ts b/console/src/app/pages/owned-projects/owned-project-grid/owned-project-grid.component.ts index aaa221c0d1..d5457ec3e3 100644 --- a/console/src/app/pages/owned-projects/owned-project-grid/owned-project-grid.component.ts +++ b/console/src/app/pages/owned-projects/owned-project-grid/owned-project-grid.component.ts @@ -1,10 +1,9 @@ import { animate, animateChild, query, stagger, style, transition, trigger } from '@angular/animations'; import { SelectionModel } from '@angular/cdk/collections'; -import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; import { Router } from '@angular/router'; import { ProjectState, ProjectType, ProjectView } from 'src/app/proto/generated/management_pb'; -import { ProjectService } from 'src/app/services/project.service'; -import { ToastService } from 'src/app/services/toast.service'; +import { AuthService } from 'src/app/services/auth.service'; @Component({ selector: 'app-owned-project-grid', @@ -30,8 +29,10 @@ import { ToastService } from 'src/app/services/toast.service'; ]), ], }) -export class OwnedProjectGridComponent { +export class OwnedProjectGridComponent implements OnChanges { @Input() items: Array = []; + public notPinned: Array = []; + @Output() newClicked: EventEmitter = new EventEmitter(); @Output() changedView: EventEmitter = new EventEmitter(); @Input() loading: boolean = false; @@ -43,7 +44,20 @@ export class OwnedProjectGridComponent { public ProjectState: any = ProjectState; public ProjectType: any = ProjectType; - constructor(private router: Router, private projectService: ProjectService, private toast: ToastService) { } + constructor(private router: Router, private authService: AuthService) { + this.selection.changed.subscribe(selection => { + this.setPrefixedItem('pinned-projects', JSON.stringify( + this.selection.selected.map(item => item.projectId), + )).then(() => { + const filtered = this.notPinned.filter(item => item === selection.added.find(i => i === item)); + filtered.forEach((f, i) => { + this.notPinned.splice(i, 1); + }); + + this.notPinned.push(...selection.removed); + }); + }); + } public selectItem(item: ProjectView.AsObject, event?: any): void { if (event && !event.target.classList.contains('mat-icon')) { @@ -57,23 +71,42 @@ export class OwnedProjectGridComponent { this.newClicked.emit(true); } - public reactivateProjects(selected: ProjectView.AsObject[]): void { - Promise.all([selected.map(proj => { - return this.projectService.ReactivateProject(proj.projectId); - })]).then(() => { - this.toast.showInfo('Successful reactivated all projects'); - }).catch(error => { - this.toast.showError(error.message); + public ngOnChanges(changes: SimpleChanges): void { + if (changes.items.currentValue && changes.items.currentValue.length > 0) { + this.notPinned = Object.assign([], this.items); + this.reorganizeItems(); + } + } + + public reorganizeItems(): void { + this.getPrefixedItem('pinned-projects').then(storageEntry => { + if (storageEntry) { + const array: string[] = JSON.parse(storageEntry); + const toSelect: ProjectView.AsObject[] = this.items.filter((item, index) => { + if (array.includes(item.projectId)) { + // this.notPinned.splice(index, 1); + return true; + } + }); + this.selection.select(...toSelect); + + const toNotPinned: ProjectView.AsObject[] = this.items.filter((item, index) => { + if (!array.includes(item.projectId)) { + return true; + } + }); + this.notPinned = toNotPinned; + } }); } - public deactivateProjects(selected: ProjectView.AsObject[]): void { - Promise.all([selected.map(proj => { - return this.projectService.DeactivateProject(proj.projectId); - })]).then(() => { - this.toast.showInfo('Successful deactivated all projects'); - }).catch(error => { - this.toast.showError(error.message); - }); + private async getPrefixedItem(key: string): Promise { + const prefix = (await this.authService.GetActiveOrg()).id; + return localStorage.getItem(`${prefix}:${key}`); + } + + private async setPrefixedItem(key: string, value: any): Promise { + const prefix = (await this.authService.GetActiveOrg()).id; + return localStorage.setItem(`${prefix}:${key}`, value); } } diff --git a/console/src/app/pages/owned-projects/owned-project-list/owned-project-list.component.ts b/console/src/app/pages/owned-projects/owned-project-list/owned-project-list.component.ts index 6cbe4217b4..525acd3be9 100644 --- a/console/src/app/pages/owned-projects/owned-project-list/owned-project-list.component.ts +++ b/console/src/app/pages/owned-projects/owned-project-list/owned-project-list.component.ts @@ -88,6 +88,9 @@ export class OwnedProjectListComponent implements OnInit, OnDestroy { this.projectService.SearchProjects(limit, offset).then(res => { this.ownedProjectList = res.toObject().resultList; this.totalResult = res.toObject().totalResult; + if (this.totalResult > 5) { + this.grid = false; + } this.dataSource.data = this.ownedProjectList; this.loadingSubject.next(false); }).catch(error => { diff --git a/console/src/app/pages/owned-projects/owned-projects.component.ts b/console/src/app/pages/owned-projects/owned-projects.component.ts index 27ce717483..e17472f071 100644 --- a/console/src/app/pages/owned-projects/owned-projects.component.ts +++ b/console/src/app/pages/owned-projects/owned-projects.component.ts @@ -1,29 +1,10 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { Subscription } from 'rxjs'; +import { Component } from '@angular/core'; @Component({ selector: 'app-owned-projects', templateUrl: './owned-projects.component.html', styleUrls: ['./owned-projects.component.scss'], }) -export class OwnedProjectsComponent implements OnInit, OnDestroy { - // public projectId: string = ''; - // public grantId: string = ''; - private sub: Subscription = new Subscription(); - constructor(private route: ActivatedRoute, - ) { - // this.route.params.subscribe((params) => { - // this.projectId = params.projectId; - // this.grantId = params.grantId; - // }); - } - - ngOnInit(): void { - } - - - public ngOnDestroy(): void { - // this.sub.unsubscribe(); - } +export class OwnedProjectsComponent { + constructor() { } } diff --git a/console/src/app/pages/owned-projects/owned-projects.module.ts b/console/src/app/pages/owned-projects/owned-projects.module.ts index 1e7d69a1e6..57dbd29290 100644 --- a/console/src/app/pages/owned-projects/owned-projects.module.ts +++ b/console/src/app/pages/owned-projects/owned-projects.module.ts @@ -8,7 +8,6 @@ import { MatChipsModule } from '@angular/material/chips'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; -import { MatMenuModule } from '@angular/material/menu'; import { MatPaginatorModule } from '@angular/material/paginator'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; @@ -64,7 +63,6 @@ import { ProjectGrantsComponent } from './project-grants/project-grants.componen MatInputModule, ChangesModule, UserListModule, - MatMenuModule, MatChipsModule, MatIconModule, MatButtonModule, diff --git a/console/src/app/pages/owned-projects/project-grants/project-grants.component.html b/console/src/app/pages/owned-projects/project-grants/project-grants.component.html index c153d5f4a9..196e3704d6 100644 --- a/console/src/app/pages/owned-projects/project-grants/project-grants.component.html +++ b/console/src/app/pages/owned-projects/project-grants/project-grants.component.html @@ -50,12 +50,6 @@ {{grant.grantedOrgName}} - - {{ 'PROJECT.GRANT.GRANTEDORGDOMAIN' | translate }} - - {{grant.grantedOrgDomain}} - - {{ 'PROJECT.GRANT.CREATIONDATE' | translate }} diff --git a/console/src/app/pages/owned-projects/project-grants/project-grants.component.ts b/console/src/app/pages/owned-projects/project-grants/project-grants.component.ts index abd7436514..2ccc993f34 100644 --- a/console/src/app/pages/owned-projects/project-grants/project-grants.component.ts +++ b/console/src/app/pages/owned-projects/project-grants/project-grants.component.ts @@ -1,13 +1,11 @@ import { animate, state, style, transition, trigger } from '@angular/animations'; import { SelectionModel } from '@angular/cdk/collections'; import { AfterViewInit, Component, Input, OnInit, ViewChild } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; import { MatPaginator } from '@angular/material/paginator'; import { MatTable } from '@angular/material/table'; import { tap } from 'rxjs/operators'; import { ProjectGrant, ProjectMemberView } from 'src/app/proto/generated/management_pb'; import { ProjectService } from 'src/app/services/project.service'; -import { ToastService } from 'src/app/services/toast.service'; import { ProjectGrantsDataSource } from './project-grants-datasource'; @@ -34,9 +32,9 @@ export class ProjectGrantsComponent implements OnInit, AfterViewInit { public selectedGrantMembers: ProjectMemberView.AsObject[] = []; /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ - public displayedColumns: string[] = ['select', 'grantedOrgName', 'grantedOrgDomain', 'creationDate', 'changeDate', 'roleNamesList']; + public displayedColumns: string[] = ['select', 'grantedOrgName', 'creationDate', 'changeDate', 'roleNamesList']; - constructor(private projectService: ProjectService, private toast: ToastService, private dialog: MatDialog) { } + constructor(private projectService: ProjectService) { } public ngOnInit(): void { this.dataSource = new ProjectGrantsDataSource(this.projectService); diff --git a/console/src/app/pages/user-detail/auth-user-detail/auth-user-detail.component.html b/console/src/app/pages/user-detail/auth-user-detail/auth-user-detail.component.html index e2fd6e596a..2ac83262bd 100644 --- a/console/src/app/pages/user-detail/auth-user-detail/auth-user-detail.component.html +++ b/console/src/app/pages/user-detail/auth-user-detail/auth-user-detail.component.html @@ -117,6 +117,9 @@ + @@ -129,10 +132,9 @@
-
- Login Names: - {{login}} +
+ Preferred Loginname: + {{user.preferredLoginName}}
diff --git a/console/src/app/pages/user-detail/auth-user-detail/auth-user-detail.component.ts b/console/src/app/pages/user-detail/auth-user-detail/auth-user-detail.component.ts index 418b68ee26..624bbcbfd2 100644 --- a/console/src/app/pages/user-detail/auth-user-detail/auth-user-detail.component.ts +++ b/console/src/app/pages/user-detail/auth-user-detail/auth-user-detail.component.ts @@ -1,35 +1,13 @@ import { Component, OnDestroy } from '@angular/core'; -import { AbstractControl, FormBuilder } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { TranslateService } from '@ngx-translate/core'; import { Subscription } from 'rxjs'; import { ChangeType } from 'src/app/modules/changes/changes.component'; import { Gender, UserAddress, UserEmail, UserPhone, UserProfile, UserView } from 'src/app/proto/generated/auth_pb'; import { AuthUserService } from 'src/app/services/auth-user.service'; -import { OrgService } from 'src/app/services/org.service'; import { ToastService } from 'src/app/services/toast.service'; -import { CodeDialogComponent } from '../code-dialog/code-dialog.component'; - -function passwordConfirmValidator(c: AbstractControl): any { - if (!c.parent || !c) { - return; - } - const pwd = c.parent.get('newPassword'); - const cpwd = c.parent.get('confirmPassword'); - - if (!pwd || !cpwd) { - return; - } - if (pwd.value !== cpwd.value) { - return { - invalid: true, - notequal: { - valid: false, - }, - }; - } -} +import { CodeDialogComponent } from './code-dialog/code-dialog.component'; @Component({ selector: 'app-auth-user-detail', @@ -58,9 +36,7 @@ export class AuthUserDetailComponent implements OnDestroy { public translate: TranslateService, private toast: ToastService, private userService: AuthUserService, - private fb: FormBuilder, private dialog: MatDialog, - private orgService: OrgService, ) { this.loading = true; this.getData().then(() => { @@ -151,6 +127,16 @@ export class AuthUserDetailComponent implements OnDestroy { }); } + public deletePhone(): void { + this.userService.RemoveMyUserPhone().then(() => { + this.toast.showInfo('Phone removed with success!'); + this.user.phone = ''; + this.phoneEditState = false; + }).catch(data => { + this.toast.showError(data.message); + }); + } + public savePhone(): void { this.phoneEditState = false; this.userService diff --git a/console/src/app/pages/user-detail/auth-user-mfa/auth-user-mfa.component.html b/console/src/app/pages/user-detail/auth-user-detail/auth-user-mfa/auth-user-mfa.component.html similarity index 70% rename from console/src/app/pages/user-detail/auth-user-mfa/auth-user-mfa.component.html rename to console/src/app/pages/user-detail/auth-user-detail/auth-user-mfa/auth-user-mfa.component.html index c9c2197ee2..9cfc6af175 100644 --- a/console/src/app/pages/user-detail/auth-user-mfa/auth-user-mfa.component.html +++ b/console/src/app/pages/user-detail/auth-user-detail/auth-user-mfa/auth-user-mfa.component.html @@ -2,7 +2,11 @@
{{'USER.MFA.TYPE.'+ mfa.type | translate}} - {{'USER.MFA.STATE.'+ mfa.state | translate}} + + + + +

{{ 'USER.PROFILE.DESCRIPTION' | translate }}

@@ -13,6 +24,19 @@ {{ 'USER.PAGES.NOUSER' | translate }} + + + + @@ -108,6 +132,9 @@ + @@ -126,10 +153,9 @@
-
- Login Names: - {{login}} +
+ Preferred Loginname: + {{user.preferredLoginName}}
diff --git a/console/src/app/pages/user-detail/user-detail/user-detail.component.scss b/console/src/app/pages/user-detail/user-detail/user-detail.component.scss index 647662d210..2e08e8f382 100644 --- a/console/src/app/pages/user-detail/user-detail/user-detail.component.scss +++ b/console/src/app/pages/user-detail/user-detail/user-detail.component.scss @@ -21,6 +21,14 @@ font-size: .9rem; color: #8795a1; } + + .fill-space { + flex: 1; + } + + .state-button { + border-radius: .5rem; + } } .card-actions { diff --git a/console/src/app/pages/user-detail/user-detail/user-detail.component.ts b/console/src/app/pages/user-detail/user-detail/user-detail.component.ts index 7440b9f41c..75800fd970 100644 --- a/console/src/app/pages/user-detail/user-detail/user-detail.component.ts +++ b/console/src/app/pages/user-detail/user-detail/user-detail.component.ts @@ -36,6 +36,8 @@ export class UserDetailComponent implements OnInit, OnDestroy { public loading: boolean = false; public UserState: any = UserState; + public copied: string = ''; + constructor( public translate: TranslateService, private route: ActivatedRoute, @@ -60,6 +62,22 @@ export class UserDetailComponent implements OnInit, OnDestroy { this.subscription.unsubscribe(); } + public changeState(newState: UserState): void { + if (newState === UserState.USERSTATE_ACTIVE) { + this.mgmtUserService.ReactivateUser(this.user.id).then(() => { + this.toast.showInfo('reactivated User'); + }).catch(error => { + this.toast.showError(error.message); + }); + } else if (newState === UserState.USERSTATE_INACTIVE) { + this.mgmtUserService.DeactivateUser(this.user.id).then(() => { + this.toast.showInfo('deactivated User'); + }).catch(error => { + this.toast.showError(error.message); + }); + } + } + public saveProfile(profileData: UserProfile.AsObject): void { this.user.firstName = profileData.firstName; this.user.lastName = profileData.lastName; @@ -100,6 +118,16 @@ export class UserDetailComponent implements OnInit, OnDestroy { }); } + public deletePhone(): void { + this.mgmtUserService.RemoveUserPhone(this.user.id).then(() => { + this.toast.showInfo('Phone removed with success!'); + this.user.phone = ''; + this.phoneEditState = false; + }).catch(data => { + this.toast.showError(data.message); + }); + } + public saveEmail(): void { this.emailEditState = false; this.mgmtUserService @@ -117,6 +145,7 @@ export class UserDetailComponent implements OnInit, OnDestroy { .SaveUserPhone(this.user.id, this.user.phone).then((data: UserPhone) => { this.toast.showInfo('Saved Phone'); this.user.phone = data.toObject().phone; + this.phoneEditState = false; }).catch(data => { this.toast.showError(data.message); }); @@ -143,4 +172,22 @@ export class UserDetailComponent implements OnInit, OnDestroy { this.toast.showError(data.message); }); } + + public copytoclipboard(value: string): void { + const selBox = document.createElement('textarea'); + selBox.style.position = 'fixed'; + selBox.style.left = '0'; + selBox.style.top = '0'; + selBox.style.opacity = '0'; + selBox.value = value; + document.body.appendChild(selBox); + selBox.focus(); + selBox.select(); + document.execCommand('copy'); + document.body.removeChild(selBox); + this.copied = value; + setTimeout(() => { + this.copied = ''; + }, 3000); + } } diff --git a/console/src/app/pages/user-detail/user-mfa/user-mfa.component.html b/console/src/app/pages/user-detail/user-mfa/user-mfa.component.html index bb6d1c4b63..6c1e36a33f 100644 --- a/console/src/app/pages/user-detail/user-mfa/user-mfa.component.html +++ b/console/src/app/pages/user-detail/user-mfa/user-mfa.component.html @@ -1,4 +1,5 @@ - +
{{'USER.MFA.TYPE.'+ mfa.type | translate}} diff --git a/console/src/app/proto/generated/auth_grpc_web_pb.d.ts b/console/src/app/proto/generated/auth_grpc_web_pb.d.ts index 7a0ad28fc2..92fe709f34 100644 --- a/console/src/app/proto/generated/auth_grpc_web_pb.d.ts +++ b/console/src/app/proto/generated/auth_grpc_web_pb.d.ts @@ -17,6 +17,7 @@ import { MyProjectOrgSearchRequest, MyProjectOrgSearchResponse, PasswordChange, + PasswordComplexityPolicy, UpdateUserAddressRequest, UpdateUserEmailRequest, UpdateUserPhoneRequest, @@ -133,6 +134,13 @@ export class AuthServiceClient { response: UserPhone) => void ): grpcWeb.ClientReadableStream; + removeMyUserPhone( + request: google_protobuf_empty_pb.Empty, + metadata: grpcWeb.Metadata | undefined, + callback: (err: grpcWeb.Error, + response: google_protobuf_empty_pb.Empty) => void + ): grpcWeb.ClientReadableStream; + verifyMyUserPhone( request: VerifyUserPhoneRequest, metadata: grpcWeb.Metadata | undefined, @@ -182,6 +190,13 @@ export class AuthServiceClient { response: google_protobuf_empty_pb.Empty) => void ): grpcWeb.ClientReadableStream; + getMyPasswordComplexityPolicy( + request: google_protobuf_empty_pb.Empty, + metadata: grpcWeb.Metadata | undefined, + callback: (err: grpcWeb.Error, + response: PasswordComplexityPolicy) => void + ): grpcWeb.ClientReadableStream; + addMfaOTP( request: google_protobuf_empty_pb.Empty, metadata: grpcWeb.Metadata | undefined, @@ -303,6 +318,11 @@ export class AuthServicePromiseClient { metadata?: grpcWeb.Metadata ): Promise; + removeMyUserPhone( + request: google_protobuf_empty_pb.Empty, + metadata?: grpcWeb.Metadata + ): Promise; + verifyMyUserPhone( request: VerifyUserPhoneRequest, metadata?: grpcWeb.Metadata @@ -338,6 +358,11 @@ export class AuthServicePromiseClient { metadata?: grpcWeb.Metadata ): Promise; + getMyPasswordComplexityPolicy( + request: google_protobuf_empty_pb.Empty, + metadata?: grpcWeb.Metadata + ): Promise; + addMfaOTP( request: google_protobuf_empty_pb.Empty, metadata?: grpcWeb.Metadata diff --git a/console/src/app/proto/generated/auth_grpc_web_pb.js b/console/src/app/proto/generated/auth_grpc_web_pb.js index e7bfea4589..6dc4c0236a 100644 --- a/console/src/app/proto/generated/auth_grpc_web_pb.js +++ b/console/src/app/proto/generated/auth_grpc_web_pb.js @@ -1124,6 +1124,86 @@ proto.caos.zitadel.auth.api.v1.AuthServicePromiseClient.prototype.changeMyUserPh }; +/** + * @const + * @type {!grpc.web.MethodDescriptor< + * !proto.google.protobuf.Empty, + * !proto.google.protobuf.Empty>} + */ +const methodDescriptor_AuthService_RemoveMyUserPhone = new grpc.web.MethodDescriptor( + '/caos.zitadel.auth.api.v1.AuthService/RemoveMyUserPhone', + grpc.web.MethodType.UNARY, + google_protobuf_empty_pb.Empty, + google_protobuf_empty_pb.Empty, + /** + * @param {!proto.google.protobuf.Empty} request + * @return {!Uint8Array} + */ + function(request) { + return request.serializeBinary(); + }, + google_protobuf_empty_pb.Empty.deserializeBinary +); + + +/** + * @const + * @type {!grpc.web.AbstractClientBase.MethodInfo< + * !proto.google.protobuf.Empty, + * !proto.google.protobuf.Empty>} + */ +const methodInfo_AuthService_RemoveMyUserPhone = new grpc.web.AbstractClientBase.MethodInfo( + google_protobuf_empty_pb.Empty, + /** + * @param {!proto.google.protobuf.Empty} request + * @return {!Uint8Array} + */ + function(request) { + return request.serializeBinary(); + }, + google_protobuf_empty_pb.Empty.deserializeBinary +); + + +/** + * @param {!proto.google.protobuf.Empty} request The + * request proto + * @param {?Object} metadata User defined + * call metadata + * @param {function(?grpc.web.Error, ?proto.google.protobuf.Empty)} + * callback The callback function(error, response) + * @return {!grpc.web.ClientReadableStream|undefined} + * The XHR Node Readable Stream + */ +proto.caos.zitadel.auth.api.v1.AuthServiceClient.prototype.removeMyUserPhone = + function(request, metadata, callback) { + return this.client_.rpcCall(this.hostname_ + + '/caos.zitadel.auth.api.v1.AuthService/RemoveMyUserPhone', + request, + metadata || {}, + methodDescriptor_AuthService_RemoveMyUserPhone, + callback); +}; + + +/** + * @param {!proto.google.protobuf.Empty} request The + * request proto + * @param {?Object} metadata User defined + * call metadata + * @return {!Promise} + * A native promise that resolves to the response + */ +proto.caos.zitadel.auth.api.v1.AuthServicePromiseClient.prototype.removeMyUserPhone = + function(request, metadata) { + return this.client_.unaryCall(this.hostname_ + + '/caos.zitadel.auth.api.v1.AuthService/RemoveMyUserPhone', + request, + metadata || {}, + methodDescriptor_AuthService_RemoveMyUserPhone); +}; + + /** * @const * @type {!grpc.web.MethodDescriptor< @@ -1684,6 +1764,86 @@ proto.caos.zitadel.auth.api.v1.AuthServicePromiseClient.prototype.changeMyPasswo }; +/** + * @const + * @type {!grpc.web.MethodDescriptor< + * !proto.google.protobuf.Empty, + * !proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy>} + */ +const methodDescriptor_AuthService_GetMyPasswordComplexityPolicy = new grpc.web.MethodDescriptor( + '/caos.zitadel.auth.api.v1.AuthService/GetMyPasswordComplexityPolicy', + grpc.web.MethodType.UNARY, + google_protobuf_empty_pb.Empty, + proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy, + /** + * @param {!proto.google.protobuf.Empty} request + * @return {!Uint8Array} + */ + function(request) { + return request.serializeBinary(); + }, + proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.deserializeBinary +); + + +/** + * @const + * @type {!grpc.web.AbstractClientBase.MethodInfo< + * !proto.google.protobuf.Empty, + * !proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy>} + */ +const methodInfo_AuthService_GetMyPasswordComplexityPolicy = new grpc.web.AbstractClientBase.MethodInfo( + proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy, + /** + * @param {!proto.google.protobuf.Empty} request + * @return {!Uint8Array} + */ + function(request) { + return request.serializeBinary(); + }, + proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.deserializeBinary +); + + +/** + * @param {!proto.google.protobuf.Empty} request The + * request proto + * @param {?Object} metadata User defined + * call metadata + * @param {function(?grpc.web.Error, ?proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy)} + * callback The callback function(error, response) + * @return {!grpc.web.ClientReadableStream|undefined} + * The XHR Node Readable Stream + */ +proto.caos.zitadel.auth.api.v1.AuthServiceClient.prototype.getMyPasswordComplexityPolicy = + function(request, metadata, callback) { + return this.client_.rpcCall(this.hostname_ + + '/caos.zitadel.auth.api.v1.AuthService/GetMyPasswordComplexityPolicy', + request, + metadata || {}, + methodDescriptor_AuthService_GetMyPasswordComplexityPolicy, + callback); +}; + + +/** + * @param {!proto.google.protobuf.Empty} request The + * request proto + * @param {?Object} metadata User defined + * call metadata + * @return {!Promise} + * A native promise that resolves to the response + */ +proto.caos.zitadel.auth.api.v1.AuthServicePromiseClient.prototype.getMyPasswordComplexityPolicy = + function(request, metadata) { + return this.client_.unaryCall(this.hostname_ + + '/caos.zitadel.auth.api.v1.AuthService/GetMyPasswordComplexityPolicy', + request, + metadata || {}, + methodDescriptor_AuthService_GetMyPasswordComplexityPolicy); +}; + + /** * @const * @type {!grpc.web.MethodDescriptor< diff --git a/console/src/app/proto/generated/auth_pb.d.ts b/console/src/app/proto/generated/auth_pb.d.ts index 366ca37d23..e8fcf60161 100644 --- a/console/src/app/proto/generated/auth_pb.d.ts +++ b/console/src/app/proto/generated/auth_pb.d.ts @@ -1302,6 +1302,68 @@ export namespace Change { } } +export class PasswordComplexityPolicy extends jspb.Message { + getId(): string; + setId(value: string): void; + + getDescription(): string; + setDescription(value: string): void; + + getCreationDate(): google_protobuf_timestamp_pb.Timestamp | undefined; + setCreationDate(value?: google_protobuf_timestamp_pb.Timestamp): void; + hasCreationDate(): boolean; + clearCreationDate(): void; + + getChangeDate(): google_protobuf_timestamp_pb.Timestamp | undefined; + setChangeDate(value?: google_protobuf_timestamp_pb.Timestamp): void; + hasChangeDate(): boolean; + clearChangeDate(): void; + + getMinLength(): number; + setMinLength(value: number): void; + + getHasLowercase(): boolean; + setHasLowercase(value: boolean): void; + + getHasUppercase(): boolean; + setHasUppercase(value: boolean): void; + + getHasNumber(): boolean; + setHasNumber(value: boolean): void; + + getHasSymbol(): boolean; + setHasSymbol(value: boolean): void; + + getSequence(): number; + setSequence(value: number): void; + + getIsDefault(): boolean; + setIsDefault(value: boolean): void; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): PasswordComplexityPolicy.AsObject; + static toObject(includeInstance: boolean, msg: PasswordComplexityPolicy): PasswordComplexityPolicy.AsObject; + static serializeBinaryToWriter(message: PasswordComplexityPolicy, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): PasswordComplexityPolicy; + static deserializeBinaryFromReader(message: PasswordComplexityPolicy, reader: jspb.BinaryReader): PasswordComplexityPolicy; +} + +export namespace PasswordComplexityPolicy { + export type AsObject = { + id: string, + description: string, + creationDate?: google_protobuf_timestamp_pb.Timestamp.AsObject, + changeDate?: google_protobuf_timestamp_pb.Timestamp.AsObject, + minLength: number, + hasLowercase: boolean, + hasUppercase: boolean, + hasNumber: boolean, + hasSymbol: boolean, + sequence: number, + isDefault: boolean, + } +} + export enum UserSessionState { USERSESSIONSTATE_UNSPECIFIED = 0, USERSESSIONSTATE_ACTIVE = 1, diff --git a/console/src/app/proto/generated/auth_pb.js b/console/src/app/proto/generated/auth_pb.js index ccde4d885e..298299a182 100644 --- a/console/src/app/proto/generated/auth_pb.js +++ b/console/src/app/proto/generated/auth_pb.js @@ -43,6 +43,7 @@ goog.exportSymbol('proto.caos.zitadel.auth.api.v1.OIDCClientAuth', null, global) goog.exportSymbol('proto.caos.zitadel.auth.api.v1.OIDCResponseType', null, global); goog.exportSymbol('proto.caos.zitadel.auth.api.v1.Org', null, global); goog.exportSymbol('proto.caos.zitadel.auth.api.v1.PasswordChange', null, global); +goog.exportSymbol('proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy', null, global); goog.exportSymbol('proto.caos.zitadel.auth.api.v1.PasswordID', null, global); goog.exportSymbol('proto.caos.zitadel.auth.api.v1.PasswordRequest', null, global); goog.exportSymbol('proto.caos.zitadel.auth.api.v1.SearchMethod', null, global); @@ -870,6 +871,27 @@ if (goog.DEBUG && !COMPILED) { */ proto.caos.zitadel.auth.api.v1.Change.displayName = 'proto.caos.zitadel.auth.api.v1.Change'; } +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.displayName = 'proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy'; +} /** * List of repeated fields within this message type. @@ -10049,6 +10071,451 @@ proto.caos.zitadel.auth.api.v1.Change.prototype.hasData = function() { }; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto suitable for use in Soy templates. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. + * @param {boolean=} opt_includeInstance Whether to include the JSPB instance + * for transitional soy proto support: http://goto/soy-param-migration + * @return {!Object} + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.toObject = function(opt_includeInstance) { + return proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Whether to include the JSPB + * instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.toObject = function(includeInstance, msg) { + var f, obj = { + id: jspb.Message.getFieldWithDefault(msg, 1, ""), + description: jspb.Message.getFieldWithDefault(msg, 2, ""), + creationDate: (f = msg.getCreationDate()) && google_protobuf_timestamp_pb.Timestamp.toObject(includeInstance, f), + changeDate: (f = msg.getChangeDate()) && google_protobuf_timestamp_pb.Timestamp.toObject(includeInstance, f), + minLength: jspb.Message.getFieldWithDefault(msg, 5, 0), + hasLowercase: jspb.Message.getFieldWithDefault(msg, 6, false), + hasUppercase: jspb.Message.getFieldWithDefault(msg, 7, false), + hasNumber: jspb.Message.getFieldWithDefault(msg, 8, false), + hasSymbol: jspb.Message.getFieldWithDefault(msg, 9, false), + sequence: jspb.Message.getFieldWithDefault(msg, 10, 0), + isDefault: jspb.Message.getFieldWithDefault(msg, 11, false) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy} + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy; + return proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy} + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setId(value); + break; + case 2: + var value = /** @type {string} */ (reader.readString()); + msg.setDescription(value); + break; + case 3: + var value = new google_protobuf_timestamp_pb.Timestamp; + reader.readMessage(value,google_protobuf_timestamp_pb.Timestamp.deserializeBinaryFromReader); + msg.setCreationDate(value); + break; + case 4: + var value = new google_protobuf_timestamp_pb.Timestamp; + reader.readMessage(value,google_protobuf_timestamp_pb.Timestamp.deserializeBinaryFromReader); + msg.setChangeDate(value); + break; + case 5: + var value = /** @type {number} */ (reader.readUint64()); + msg.setMinLength(value); + break; + case 6: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setHasLowercase(value); + break; + case 7: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setHasUppercase(value); + break; + case 8: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setHasNumber(value); + break; + case 9: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setHasSymbol(value); + break; + case 10: + var value = /** @type {number} */ (reader.readUint64()); + msg.setSequence(value); + break; + case 11: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setIsDefault(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getId(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getDescription(); + if (f.length > 0) { + writer.writeString( + 2, + f + ); + } + f = message.getCreationDate(); + if (f != null) { + writer.writeMessage( + 3, + f, + google_protobuf_timestamp_pb.Timestamp.serializeBinaryToWriter + ); + } + f = message.getChangeDate(); + if (f != null) { + writer.writeMessage( + 4, + f, + google_protobuf_timestamp_pb.Timestamp.serializeBinaryToWriter + ); + } + f = message.getMinLength(); + if (f !== 0) { + writer.writeUint64( + 5, + f + ); + } + f = message.getHasLowercase(); + if (f) { + writer.writeBool( + 6, + f + ); + } + f = message.getHasUppercase(); + if (f) { + writer.writeBool( + 7, + f + ); + } + f = message.getHasNumber(); + if (f) { + writer.writeBool( + 8, + f + ); + } + f = message.getHasSymbol(); + if (f) { + writer.writeBool( + 9, + f + ); + } + f = message.getSequence(); + if (f !== 0) { + writer.writeUint64( + 10, + f + ); + } + f = message.getIsDefault(); + if (f) { + writer.writeBool( + 11, + f + ); + } +}; + + +/** + * optional string id = 1; + * @return {string} + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.getId = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** @param {string} value */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.setId = function(value) { + jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * optional string description = 2; + * @return {string} + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.getDescription = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); +}; + + +/** @param {string} value */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.setDescription = function(value) { + jspb.Message.setProto3StringField(this, 2, value); +}; + + +/** + * optional google.protobuf.Timestamp creation_date = 3; + * @return {?proto.google.protobuf.Timestamp} + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.getCreationDate = function() { + return /** @type{?proto.google.protobuf.Timestamp} */ ( + jspb.Message.getWrapperField(this, google_protobuf_timestamp_pb.Timestamp, 3)); +}; + + +/** @param {?proto.google.protobuf.Timestamp|undefined} value */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.setCreationDate = function(value) { + jspb.Message.setWrapperField(this, 3, value); +}; + + +/** + * Clears the message field making it undefined. + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.clearCreationDate = function() { + this.setCreationDate(undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.hasCreationDate = function() { + return jspb.Message.getField(this, 3) != null; +}; + + +/** + * optional google.protobuf.Timestamp change_date = 4; + * @return {?proto.google.protobuf.Timestamp} + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.getChangeDate = function() { + return /** @type{?proto.google.protobuf.Timestamp} */ ( + jspb.Message.getWrapperField(this, google_protobuf_timestamp_pb.Timestamp, 4)); +}; + + +/** @param {?proto.google.protobuf.Timestamp|undefined} value */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.setChangeDate = function(value) { + jspb.Message.setWrapperField(this, 4, value); +}; + + +/** + * Clears the message field making it undefined. + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.clearChangeDate = function() { + this.setChangeDate(undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.hasChangeDate = function() { + return jspb.Message.getField(this, 4) != null; +}; + + +/** + * optional uint64 min_length = 5; + * @return {number} + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.getMinLength = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0)); +}; + + +/** @param {number} value */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.setMinLength = function(value) { + jspb.Message.setProto3IntField(this, 5, value); +}; + + +/** + * optional bool has_lowercase = 6; + * Note that Boolean fields may be set to 0/1 when serialized from a Java server. + * You should avoid comparisons like {@code val === true/false} in those cases. + * @return {boolean} + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.getHasLowercase = function() { + return /** @type {boolean} */ (jspb.Message.getFieldWithDefault(this, 6, false)); +}; + + +/** @param {boolean} value */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.setHasLowercase = function(value) { + jspb.Message.setProto3BooleanField(this, 6, value); +}; + + +/** + * optional bool has_uppercase = 7; + * Note that Boolean fields may be set to 0/1 when serialized from a Java server. + * You should avoid comparisons like {@code val === true/false} in those cases. + * @return {boolean} + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.getHasUppercase = function() { + return /** @type {boolean} */ (jspb.Message.getFieldWithDefault(this, 7, false)); +}; + + +/** @param {boolean} value */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.setHasUppercase = function(value) { + jspb.Message.setProto3BooleanField(this, 7, value); +}; + + +/** + * optional bool has_number = 8; + * Note that Boolean fields may be set to 0/1 when serialized from a Java server. + * You should avoid comparisons like {@code val === true/false} in those cases. + * @return {boolean} + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.getHasNumber = function() { + return /** @type {boolean} */ (jspb.Message.getFieldWithDefault(this, 8, false)); +}; + + +/** @param {boolean} value */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.setHasNumber = function(value) { + jspb.Message.setProto3BooleanField(this, 8, value); +}; + + +/** + * optional bool has_symbol = 9; + * Note that Boolean fields may be set to 0/1 when serialized from a Java server. + * You should avoid comparisons like {@code val === true/false} in those cases. + * @return {boolean} + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.getHasSymbol = function() { + return /** @type {boolean} */ (jspb.Message.getFieldWithDefault(this, 9, false)); +}; + + +/** @param {boolean} value */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.setHasSymbol = function(value) { + jspb.Message.setProto3BooleanField(this, 9, value); +}; + + +/** + * optional uint64 sequence = 10; + * @return {number} + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.getSequence = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 10, 0)); +}; + + +/** @param {number} value */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.setSequence = function(value) { + jspb.Message.setProto3IntField(this, 10, value); +}; + + +/** + * optional bool is_default = 11; + * Note that Boolean fields may be set to 0/1 when serialized from a Java server. + * You should avoid comparisons like {@code val === true/false} in those cases. + * @return {boolean} + */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.getIsDefault = function() { + return /** @type {boolean} */ (jspb.Message.getFieldWithDefault(this, 11, false)); +}; + + +/** @param {boolean} value */ +proto.caos.zitadel.auth.api.v1.PasswordComplexityPolicy.prototype.setIsDefault = function(value) { + jspb.Message.setProto3BooleanField(this, 11, value); +}; + + /** * @enum {number} */ diff --git a/console/src/app/proto/generated/management_grpc_web_pb.d.ts b/console/src/app/proto/generated/management_grpc_web_pb.d.ts index 7c2e02dbfa..007e83a888 100644 --- a/console/src/app/proto/generated/management_grpc_web_pb.d.ts +++ b/console/src/app/proto/generated/management_grpc_web_pb.d.ts @@ -309,6 +309,13 @@ export class ManagementServiceClient { response: UserPhone) => void ): grpcWeb.ClientReadableStream; + removeUserPhone( + request: UserID, + metadata: grpcWeb.Metadata | undefined, + callback: (err: grpcWeb.Error, + response: google_protobuf_empty_pb.Empty) => void + ): grpcWeb.ClientReadableStream; + resendPhoneVerificationCode( request: UserID, metadata: grpcWeb.Metadata | undefined, @@ -1085,6 +1092,11 @@ export class ManagementServicePromiseClient { metadata?: grpcWeb.Metadata ): Promise; + removeUserPhone( + request: UserID, + metadata?: grpcWeb.Metadata + ): Promise; + resendPhoneVerificationCode( request: UserID, metadata?: grpcWeb.Metadata diff --git a/console/src/app/proto/generated/management_grpc_web_pb.js b/console/src/app/proto/generated/management_grpc_web_pb.js index 2e205309b5..7cec293a74 100644 --- a/console/src/app/proto/generated/management_grpc_web_pb.js +++ b/console/src/app/proto/generated/management_grpc_web_pb.js @@ -2086,6 +2086,86 @@ proto.caos.zitadel.management.api.v1.ManagementServicePromiseClient.prototype.ch }; +/** + * @const + * @type {!grpc.web.MethodDescriptor< + * !proto.caos.zitadel.management.api.v1.UserID, + * !proto.google.protobuf.Empty>} + */ +const methodDescriptor_ManagementService_RemoveUserPhone = new grpc.web.MethodDescriptor( + '/caos.zitadel.management.api.v1.ManagementService/RemoveUserPhone', + grpc.web.MethodType.UNARY, + proto.caos.zitadel.management.api.v1.UserID, + google_protobuf_empty_pb.Empty, + /** + * @param {!proto.caos.zitadel.management.api.v1.UserID} request + * @return {!Uint8Array} + */ + function(request) { + return request.serializeBinary(); + }, + google_protobuf_empty_pb.Empty.deserializeBinary +); + + +/** + * @const + * @type {!grpc.web.AbstractClientBase.MethodInfo< + * !proto.caos.zitadel.management.api.v1.UserID, + * !proto.google.protobuf.Empty>} + */ +const methodInfo_ManagementService_RemoveUserPhone = new grpc.web.AbstractClientBase.MethodInfo( + google_protobuf_empty_pb.Empty, + /** + * @param {!proto.caos.zitadel.management.api.v1.UserID} request + * @return {!Uint8Array} + */ + function(request) { + return request.serializeBinary(); + }, + google_protobuf_empty_pb.Empty.deserializeBinary +); + + +/** + * @param {!proto.caos.zitadel.management.api.v1.UserID} request The + * request proto + * @param {?Object} metadata User defined + * call metadata + * @param {function(?grpc.web.Error, ?proto.google.protobuf.Empty)} + * callback The callback function(error, response) + * @return {!grpc.web.ClientReadableStream|undefined} + * The XHR Node Readable Stream + */ +proto.caos.zitadel.management.api.v1.ManagementServiceClient.prototype.removeUserPhone = + function(request, metadata, callback) { + return this.client_.rpcCall(this.hostname_ + + '/caos.zitadel.management.api.v1.ManagementService/RemoveUserPhone', + request, + metadata || {}, + methodDescriptor_ManagementService_RemoveUserPhone, + callback); +}; + + +/** + * @param {!proto.caos.zitadel.management.api.v1.UserID} request The + * request proto + * @param {?Object} metadata User defined + * call metadata + * @return {!Promise} + * A native promise that resolves to the response + */ +proto.caos.zitadel.management.api.v1.ManagementServicePromiseClient.prototype.removeUserPhone = + function(request, metadata) { + return this.client_.unaryCall(this.hostname_ + + '/caos.zitadel.management.api.v1.ManagementService/RemoveUserPhone', + request, + metadata || {}, + methodDescriptor_ManagementService_RemoveUserPhone); +}; + + /** * @const * @type {!grpc.web.MethodDescriptor< diff --git a/console/src/app/services/auth-user.service.ts b/console/src/app/services/auth-user.service.ts index 3a8b89afe6..cf09379c49 100644 --- a/console/src/app/services/auth-user.service.ts +++ b/console/src/app/services/auth-user.service.ts @@ -156,6 +156,14 @@ export class AuthUserService { ); } + public async RemoveMyUserPhone(): Promise { + return await this.request( + c => c.removeMyUserPhone, + new Empty(), + f => f, + ); + } + private async getMyzitadelPermissions(): Promise { return await this.request( c => c.getMyZitadelPermissions, diff --git a/console/src/app/services/mgmt-user.service.ts b/console/src/app/services/mgmt-user.service.ts index fc121d6c77..bca942d102 100644 --- a/console/src/app/services/mgmt-user.service.ts +++ b/console/src/app/services/mgmt-user.service.ts @@ -197,6 +197,16 @@ export class MgmtUserService { ); } + public async RemoveUserPhone(id: string): Promise { + const req = new UserID(); + req.setId(id); + return await this.request( + c => c.removeUserPhone, + req, + f => f, + ); + } + public async DeactivateUser(id: string): Promise { const req = new UserID(); req.setId(id); diff --git a/console/src/app/services/storage.service.ts b/console/src/app/services/storage.service.ts index 83022238c9..af207f76e0 100644 --- a/console/src/app/services/storage.service.ts +++ b/console/src/app/services/storage.service.ts @@ -1,8 +1,6 @@ import { Injectable } from '@angular/core'; import { OAuthStorage } from 'angular-oauth2-oidc'; -import { GrpcService } from './grpc.service'; - @Injectable({ providedIn: 'root', @@ -11,7 +9,7 @@ import { GrpcService } from './grpc.service'; export class StorageService implements OAuthStorage { private storage: Storage = window.sessionStorage; - constructor(private grpcService: GrpcService) { } + constructor() { } public setItem(key: string, value: TValue): void { this.storage.setItem(this.getPrefixedKey(key), JSON.stringify(value)); diff --git a/console/src/assets/i18n/de.json b/console/src/assets/i18n/de.json index ce74e738e9..076c63a469 100644 --- a/console/src/assets/i18n/de.json +++ b/console/src/assets/i18n/de.json @@ -20,12 +20,14 @@ }, "MENU": { "PERSONAL_INFO": "Persönliche Informationen", - "IAM":"IAM", + "IAM":"Administration", "ORGANIZATION": "Organisation", + "PROJECTSSECTION":"Projekte", "PROJECT": "Projekte", "GRANTEDPROJECT":"Berechtigte Projekte", + "USERSECTION":"Benutzer", "USER": "Benutzer", - "LOGOUT": "abmelden", + "LOGOUT": "alle Benutzer abmelden", "NEWORG":"Neue Organisation", "IAMADMIN":"Sie sind ein IAM Administrator. Sie haben erweiterte Berechtigungen!", "SHOWORGS":"Alle organisationen anzeigen" @@ -64,7 +66,9 @@ "LOGINNAMESDESC":"Mit diesen Namen können Sie sich anmelden", "COPY":"In die Zwischenablage kopieren", "COPIED":"In die Zwischenablage kopiert!", - "NOUSER":"Kein User" + "NOUSER":"Kein User", + "REACTIVATE":"Reaktivieren", + "DEACTIVATE":"Deaktivieren" }, "MFA": { "TITLE": "Multifaktor-Authentifizierung", @@ -220,7 +224,9 @@ "ORGDOMAIN_VERIFICATION_SKIP":"Sie können die Überprüfung vorerst überspringen und Ihre Organisation weiter erstellen. Um Ihre Organisation jedoch verwenden zu können, muss dieser Schritt abgeschlossen sein!", "ORGDETAILUSER_TITLE":"Organisationsbesitzer hinzufügen", "DOWNLOAD_FILE":"File download", - "SELECTORGTOOLTIP":"Wähle diese Organisation" + "SELECTORGTOOLTIP":"Wähle diese Organisation", + "PRIMARYDOMAIN":"Primäre Domain", + "STATE":"Status" }, "DOMAINS": { "TITLE":"Domains", @@ -330,7 +336,11 @@ "TYPE":{ "OWNED":"Eigene Projekte", "GRANTED":"Berechtigte Projekte" - } + }, + "PINNED":"Angepinnt", + "ALL": "Alle", + "CREATEDON":"erstellt am", + "LASTMODIFIED":"zuletzt verändert am" }, "STATE": { "TITLE":"Status", @@ -420,7 +430,8 @@ "STATE":"Status", "TYPE":"Typ", "CREATIONDATE":"Erstelldatum", - "CHANGEDATE":"Letzte Änderung" + "CHANGEDATE":"Letzte Änderung", + "RESOURCEOWNER":"Besitzer" } }, "APP": { diff --git a/console/src/assets/i18n/en.json b/console/src/assets/i18n/en.json index 196fa4bcf6..71fa521a6d 100644 --- a/console/src/assets/i18n/en.json +++ b/console/src/assets/i18n/en.json @@ -20,12 +20,14 @@ }, "MENU": { "PERSONAL_INFO": "Personal Information", - "IAM":"IAM", + "IAM":"Administration", "ORGANIZATION": "Organization", + "PROJECTSSECTION":"Projects", "PROJECT": "Projects", "GRANTEDPROJECT":"Granted Projects", + "USERSECTION":"Benutzer", "USER": "Users", - "LOGOUT": "Log out", + "LOGOUT": "Logout all users", "NEWORG":"New Organization", "IAMADMIN":"You are an IAM Administrator. Note that you have enhanced permissions!", "SHOWORGS":"Show all organizations" @@ -64,7 +66,9 @@ "LOGINNAMESDESC":"You can log into zitadel with these names", "COPY":"Copy to clipboard", "COPIED":"Copied to clipboard!", - "NOUSER":"No User" + "NOUSER":"No User", + "REACTIVATE":"Reactivate", + "DEACTIVATE":"Deactivate" }, "MFA": { "TITLE": "Multifactor Authentication", @@ -221,16 +225,18 @@ "ORGDOMAIN_VERIFICATION_SKIP":"You can skip verification for now and continue to create your organization, but in order to use your organization this step has to be completed!", "ORGDETAILUSER_TITLE":"Configure Organization Owner", "DOWNLOAD_FILE":"Download file", - "SELECTORGTOOLTIP":"Select this organization" + "SELECTORGTOOLTIP":"Select this organization", + "PRIMARYDOMAIN":"Primary Domain", + "STATE":"State" }, "DOMAINS": { "TITLE":"Domains", "DESCRIPTION":"Configure your domains on which your users will be registered." }, "STATE": { - "0": "nicht definiert", - "1": "aktiv", - "2": "inaktiv" + "0": "not defined", + "1": "active", + "2": "deactivated" }, "MEMBER": { "TITLE":"Organization Managers", @@ -331,7 +337,11 @@ "TYPE":{ "OWNED":"Owned Projects", "GRANTED":"Granted Projects" - } + }, + "PINNED":"Pinned", + "ALL": "All", + "CREATEDON":"created on", + "LASTMODIFIED":"last modified on" }, "STATE": { "TITLE":"State", @@ -421,7 +431,8 @@ "STATE":"Status", "TYPE":"Type", "CREATIONDATE":"Created At", - "CHANGEDATE":"Last Modified" + "CHANGEDATE":"Last Modified", + "RESOURCEOWNER":"Owner" } }, "APP": { diff --git a/console/src/styles/table.scss b/console/src/styles/table.scss index cf7b012f5a..86de6b75dd 100644 --- a/console/src/styles/table.scss +++ b/console/src/styles/table.scss @@ -22,7 +22,7 @@ color: mat-color($foreground, text); white-space: nowrap; background-color: #8795a1; - padding: .5rem 1rem; + padding: 3px 1rem; } td {