feat(console): set email verified on org creation, disable svg upload, password page optimizations (#4149)

* feat: set email verified on org creation

* catch svg files and throw error

* password changes

* passwordpage

* rm log

* it

* fr

* localhost env

* Update fr.json

Co-authored-by: Fabi <[email protected]>
Co-authored-by: Livio Spring <[email protected]>
This commit is contained in:
Max Peintner
2022-08-26 07:34:44 +00:00
committed by GitHub
co-authored by Fabi Livio Spring
parent e39d82c031
commit cbb5e90bac
17 changed files with 201 additions and 127 deletions
@@ -115,14 +115,23 @@
</mat-select>
</cnsl-form-field>
<mat-checkbox
class="checkbox"
[(ngModel)]="usePassword"
[ngModelOptions]="{ standalone: true }"
(change)="initPwdValidators()"
>
{{ 'ORG.PAGES.USEPASSWORD' | translate }}</mat-checkbox
>
<div class="email-is-verified">
<mat-checkbox class="block-checkbox" formControlName="isVerified">
{{ 'USER.LOGINMETHODS.EMAIL.ISVERIFIED' | translate }}
</mat-checkbox>
<mat-checkbox
class="block-checkbox"
[(ngModel)]="usePassword"
[ngModelOptions]="{ standalone: true }"
(change)="initPwdValidators()"
>
{{ 'ORG.PAGES.USEPASSWORD' | translate }}</mat-checkbox
>
<cnsl-info-section class="full-width desc">
<span>{{ 'USER.CREATE.INITMAILDESCRIPTION' | translate }}</span>
</cnsl-info-section>
</div>
<ng-container *ngIf="usePassword && pwdForm">
<p class="section cnsl-secondary-text">{{ 'USER.CREATE.PASSWORDSECTION' | translate }}</p>
@@ -58,6 +58,16 @@ h1 {
flex: 1 0 33%;
margin: 0 0.5rem;
}
.email-is-verified {
flex-basis: 100%;
margin: 1.5rem 0.5rem 0 0.5rem;
.block-checkbox {
display: block;
margin: 0.25rem 0;
}
}
}
.pwd-form {
@@ -109,11 +119,6 @@ h1 {
}
}
.checkbox {
flex-basis: 100%;
margin: 0.5rem;
}
.complexity-view {
width: 100%;
margin: 0 0.5rem;
@@ -10,6 +10,7 @@ import { SetUpOrgRequest } from 'src/app/proto/generated/zitadel/admin_pb';
import { PasswordComplexityPolicy } from 'src/app/proto/generated/zitadel/policy_pb';
import { Gender } from 'src/app/proto/generated/zitadel/user_pb';
import { AdminService } from 'src/app/services/admin.service';
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
import { ManagementService } from 'src/app/services/mgmt.service';
import { ToastService } from 'src/app/services/toast.service';
@@ -69,7 +70,16 @@ export class OrgCreateComponent {
private fb: UntypedFormBuilder,
private mgmtService: ManagementService,
private authService: GrpcAuthService,
private breadcrumbService: BreadcrumbService,
) {
const instanceBread = new Breadcrumb({
type: BreadcrumbType.INSTANCE,
name: 'Instance',
routerLink: ['/instance'],
});
breadcrumbService.setBreadcrumb([instanceBread]);
this.authService
.isAllowed(['iam.write'])
.pipe(take(1))
@@ -96,7 +106,9 @@ export class OrgCreateComponent {
createOrgRequest.setDomain(this.domain?.value);
const humanRequest: SetUpOrgRequest.Human = new SetUpOrgRequest.Human();
humanRequest.setEmail(new SetUpOrgRequest.Human.Email().setEmail(this.email?.value));
humanRequest.setEmail(
new SetUpOrgRequest.Human.Email().setEmail(this.email?.value).setIsEmailVerified(this.isVerified?.value),
);
humanRequest.setUserName(this.userName?.value);
const profile: SetUpOrgRequest.Human.Profile = new SetUpOrgRequest.Human.Profile();
@@ -143,6 +155,7 @@ export class OrgCreateComponent {
firstName: ['', [Validators.required]],
lastName: ['', [Validators.required]],
email: ['', [Validators.required]],
isVerified: [false, []],
gender: [''],
nickName: [''],
preferredLanguage: [''],
@@ -243,6 +256,10 @@ export class OrgCreateComponent {
return this.userForm.get('email');
}
public get isVerified(): AbstractControl | null {
return this.userForm.get('isVerified');
}
public get nickName(): AbstractControl | null {
return this.userForm.get('nickName');
}
@@ -9,6 +9,7 @@ import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { TranslateModule } from '@ngx-translate/core';
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { CreateLayoutModule } from 'src/app/modules/create-layout/create-layout.module';
import { InfoSectionModule } from 'src/app/modules/info-section/info-section.module';
import { InputModule } from 'src/app/modules/input/input.module';
import { PasswordComplexityViewModule } from 'src/app/modules/password-complexity-view/password-complexity-view.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
@@ -23,6 +24,7 @@ import { OrgCreateComponent } from './org-create.component';
CommonModule,
FormsModule,
ReactiveFormsModule,
InfoSectionModule,
InputModule,
MatButtonModule,
MatIconModule,
@@ -1,41 +1,45 @@
<cnsl-detail-layout [hasBackButton]="true" title="{{ 'USER.PASSWORD.TITLE' | translate }}"
description="{{ 'USER.PASSWORD.DESCRIPTION' | translate }}">
<cnsl-detail-layout [hasBackButton]="true" title="{{ 'USER.PASSWORD.TITLE' | translate }}">
<p class="password-info cnsl-secondary-text" sub>{{ 'USER.PASSWORD.DESCRIPTION' | translate }}</p>
<ng-container *ngIf="userId; else authUser">
<div class="validation" *ngIf="this.policy">
<cnsl-password-complexity-view [policy]="this.policy" [password]="password">
</cnsl-password-complexity-view>
</div>
<form
*ngIf="passwordForm"
autocomplete="new-password"
[formGroup]="passwordForm"
(ngSubmit)="setInitialPassword(userId)"
>
<div class="password-content">
<div class="side-by-side">
<cnsl-form-field class="formfield">
<cnsl-label>{{ 'USER.PASSWORD.NEW' | translate }}</cnsl-label>
<input cnslInput autocomplete="off" name="password" formControlName="password" type="password" />
<form *ngIf="passwordForm" autocomplete="new-password" [formGroup]="passwordForm"
(ngSubmit)="setInitialPassword(userId)">
<div class="content center">
<cnsl-form-field class="formfield">
<cnsl-label>{{ 'USER.PASSWORD.NEW' | translate }}</cnsl-label>
<input cnslInput autocomplete="off" name="password" formControlName="password" type="password" />
<span cnslError *ngIf="password?.errors?.required">
{{ 'USER.VALIDATION.REQUIRED' | translate }}
</span>
</cnsl-form-field>
<cnsl-form-field class="formfield">
<cnsl-label>{{ 'USER.PASSWORD.CONFIRM' | translate }}</cnsl-label>
<input cnslInput autocomplete="off" name="passwordRepeat" formControlName="confirmPassword" type="password" />
<span cnslError *ngIf="confirmPassword?.errors?.notequal">
{{ 'USER.PASSWORD.NOTEQUAL' | translate }}
</span>
</cnsl-form-field>
</div>
<span cnslError *ngIf="password?.errors?.required">
{{ 'USER.VALIDATION.REQUIRED' | translate }}
</span>
</cnsl-form-field>
<cnsl-form-field class="formfield">
<cnsl-label>{{ 'USER.PASSWORD.CONFIRM' | translate }}</cnsl-label>
<input cnslInput autocomplete="off" name="passwordRepeat" formControlName="confirmPassword" type="password" />
<span cnslError *ngIf="confirmPassword?.errors?.notequal">
{{ 'USER.PASSWORD.NOTEQUAL' | translate }}
</span>
</cnsl-form-field>
</div>
<div class="btn-container">
<button class="submit-button" [disabled]="passwordForm.invalid" mat-raised-button color="primary">{{
'USER.PASSWORD.SET' | translate }}</button>
<div class="validation" *ngIf="this.policy">
<cnsl-password-complexity-view [policy]="this.policy" [password]="password"> </cnsl-password-complexity-view>
</div>
</div>
<button class="submit-button" [disabled]="passwordForm.invalid" mat-raised-button color="primary">
{{ 'USER.PASSWORD.SET' | translate }}
</button>
</form>
</ng-container>
<ng-template #authUser>
<form *ngIf="passwordForm" [formGroup]="passwordForm" (ngSubmit)="setPassword()">
<div class="content">
<div class="password-content">
<cnsl-form-field class="formfield">
<cnsl-label>{{ 'USER.PASSWORD.OLD' | translate }}</cnsl-label>
<input cnslInput autocomplete="off" name="password" type="password" formControlName="currentPassword" />
@@ -45,29 +49,36 @@
</cnsl-form-field>
<div class="validation between" *ngIf="this.policy">
<cnsl-password-complexity-view [policy]="this.policy" [password]="newPassword">
</cnsl-password-complexity-view>
<cnsl-password-complexity-view [policy]="this.policy" [password]="newPassword"> </cnsl-password-complexity-view>
</div>
<cnsl-form-field class="formfield">
<cnsl-label>{{ 'USER.PASSWORD.NEW' | translate }}</cnsl-label>
<input cnslInput autocomplete="off" name="new password" type="password" formControlName="newPassword" />
<div class="side-by-side">
<cnsl-form-field class="formfield">
<cnsl-label>{{ 'USER.PASSWORD.NEW' | translate }}</cnsl-label>
<input cnslInput autocomplete="off" name="new password" type="password" formControlName="newPassword" />
<span cnslError *ngIf="newPassword?.errors?.required">
{{ 'USER.VALIDATION.REQUIRED' | translate }}
</span>
</cnsl-form-field>
<cnsl-form-field class="formfield">
<cnsl-label>{{ 'USER.PASSWORD.CONFIRM' | translate }}</cnsl-label>
<input cnslInput autocomplete="off" name="password repeating" type="password"
formControlName="confirmPassword" />
<span cnslError *ngIf="confirmPassword?.errors?.notequal">
{{ 'USER.PASSWORD.NOTEQUAL' | translate }}
</span>
</cnsl-form-field>
<span cnslError *ngIf="newPassword?.errors?.required">
{{ 'USER.VALIDATION.REQUIRED' | translate }}
</span>
</cnsl-form-field>
<cnsl-form-field class="formfield">
<cnsl-label>{{ 'USER.PASSWORD.CONFIRM' | translate }}</cnsl-label>
<input
cnslInput
autocomplete="off"
name="password repeating"
type="password"
formControlName="confirmPassword"
/>
<span cnslError *ngIf="confirmPassword?.errors?.notequal">
{{ 'USER.PASSWORD.NOTEQUAL' | translate }}
</span>
</cnsl-form-field>
</div>
</div>
<button class="submit-button" [disabled]="passwordForm.invalid" mat-raised-button color="primary">{{
'USER.PASSWORD.RESET' | translate }}</button>
<button class="submit-button" [disabled]="passwordForm.invalid" mat-raised-button color="primary">
{{ 'USER.PASSWORD.RESET' | translate }}
</button>
</form>
</ng-template>
</cnsl-detail-layout>
</cnsl-detail-layout>
@@ -1,17 +1,34 @@
.content {
.password-info {
margin: -1rem 0 0 0;
font-size: 14px;
}
.password-content {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: 0 -0.5rem;
max-width: 40rem;
.formfield {
margin: 0 0.5rem;
.side-by-side {
display: flex;
flex-wrap: wrap;
flex-direction: row;
margin: 0 -0.5rem;
width: 100%;
max-width: 400px;
@media only screen and (max-width: 500px) {
flex-direction: column;
}
.formfield {
flex: 1;
margin: 0 0.5rem;
}
}
&.center {
align-items: center;
.formfield {
max-width: 400px;
width: 100%;
}
}
@@ -22,7 +39,7 @@
}
.submit-button {
margin-top: 100px;
margin-top: 2rem;
display: block;
padding: 0.5rem 4rem;
}