mirror of
https://github.com/zitadel/zitadel.git
synced 2025-06-01 17:08:21 +00:00
fix(console): initialize org owner with or without password (#471)
* set password validators only if needed * create org initialize without pwd * no caps * self xss message
This commit is contained in:
parent
c051fa8ae1
commit
30282acb42
@ -155,7 +155,7 @@ export class AppComponent implements OnDestroy {
|
||||
update: UpdateService,
|
||||
) {
|
||||
console.log('%cWait!', 'text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; color: #5282c1; font-size: 50px');
|
||||
console.log('%cInserting something here could give attackers access to your caos account.', 'color: red; font-size: 18px');
|
||||
console.log('%cInserting something here could give attackers access to your zitadel account.', 'color: red; font-size: 18px');
|
||||
console.log('%cIf you don\'t know exactly what you\'re doing, close the window and stay on the safe side', 'font-size: 16px');
|
||||
console.log('%cIf you know exactly what you are doing, you should work for us', 'font-size: 16px');
|
||||
this.setLanguage();
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
<ng-container *ngIf="currentCreateStep == 1">
|
||||
<h1>{{'ORG.PAGES.ORGDETAIL_TITLE' | translate}}</h1>
|
||||
<form [formGroup]="orgForm">
|
||||
<form [formGroup]="orgForm" (ngSubmit)="next()">
|
||||
<div class="content">
|
||||
<mat-form-field class="formfield">
|
||||
<mat-label>{{ 'ORG_DETAIL.DETAIL.NAME' | translate }}</mat-label>
|
||||
@ -21,6 +21,11 @@
|
||||
<input matInput formControlName="domain" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<button [disabled]="orgForm.invalid" color="primary" mat-raised-button class="continue-button"
|
||||
cdkFocusInitial type="submit">
|
||||
{{'CONTINUE' | translate}}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<!-- <div *ngIf="name?.touched" @openClose>
|
||||
@ -107,61 +112,66 @@
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<p class="section">{{ 'USER.CREATE.PASSWORDSECTION' | translate }}</p>
|
||||
<mat-checkbox [(ngModel)]="usePassword" [ngModelOptions]="{standalone: true}"
|
||||
(change)="initPwdValidators()">
|
||||
{{'ORG.PAGES.USEPASSWORD' | translate}}</mat-checkbox>
|
||||
|
||||
<mat-form-field class="formfield">
|
||||
<mat-label>{{ 'USER.PASSWORD.NEW' | translate }}</mat-label>
|
||||
<input autocomplete="off" name="firstpassword" matInput formControlName="password"
|
||||
type="password" />
|
||||
<ng-container *ngIf="usePassword">
|
||||
<p class="section">{{ 'USER.CREATE.PASSWORDSECTION' | translate }}</p>
|
||||
|
||||
<mat-error *ngIf="password?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="password?.errors?.symbolValidator">
|
||||
{{ 'USER.VALIDATION.SYMBOLERROR' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="password?.errors?.numberValidator">
|
||||
{{ 'USER.VALIDATION.NUMBERERROR' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="password?.errors?.upperCaseValidator">
|
||||
{{ 'USER.VALIDATION.UPPERCASEMISSING' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="password?.errors?.lowerCaseValidator">
|
||||
{{ 'USER.VALIDATION.LOWERCASEMISSING' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="password?.errors?.minlength">
|
||||
{{ 'USER.VALIDATION.MINLENGTH' | translate:password?.errors?.minlength }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="formfield">
|
||||
<mat-label>{{ 'USER.PASSWORD.CONFIRM' | translate }}</mat-label>
|
||||
<input autocomplete="off" name="confirmPassword" matInput formControlName="confirmPassword"
|
||||
type="password" />
|
||||
<mat-form-field class="formfield" *ngIf="password">
|
||||
<mat-label>{{ 'USER.PASSWORD.NEW' | translate }}</mat-label>
|
||||
<input autocomplete="off" name="firstpassword" matInput formControlName="password"
|
||||
type="password" />
|
||||
|
||||
<mat-error *ngIf="password?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="password?.errors?.symbolValidator">
|
||||
{{ 'USER.VALIDATION.SYMBOLERROR' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="password?.errors?.numberValidator">
|
||||
{{ 'USER.VALIDATION.NUMBERERROR' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="password?.errors?.upperCaseValidator">
|
||||
{{ 'USER.VALIDATION.UPPERCASEMISSING' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="password?.errors?.lowerCaseValidator">
|
||||
{{ 'USER.VALIDATION.LOWERCASEMISSING' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="password?.errors?.minlength">
|
||||
{{ 'USER.VALIDATION.MINLENGTH' | translate:password?.errors?.minlength }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="formfield" *ngIf="confirmPassword">
|
||||
<mat-label>{{ 'USER.PASSWORD.CONFIRM' | translate }}</mat-label>
|
||||
<input autocomplete="off" name="confirmPassword" matInput formControlName="confirmPassword"
|
||||
type="password" />
|
||||
|
||||
|
||||
<mat-error *ngIf="confirmPassword?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.symbolValidator">
|
||||
{{ 'USER.VALIDATION.SYMBOLERROR' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.numberValidator">
|
||||
{{ 'USER.VALIDATION.NUMBERERROR' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.notequal">
|
||||
{{ 'USER.PASSWORD.NOTEQUAL' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.upperCaseValidator">
|
||||
{{ 'USER.VALIDATION.UPPERCASEMISSING' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.lowerCaseValidator">
|
||||
{{ 'USER.VALIDATION.LOWERCASEMISSING' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.minlength">
|
||||
{{ 'USER.VALIDATION.MINLENGTH' | translate:confirmPassword?.errors?.minlength }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-error *ngIf="confirmPassword?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.symbolValidator">
|
||||
{{ 'USER.VALIDATION.SYMBOLERROR' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.numberValidator">
|
||||
{{ 'USER.VALIDATION.NUMBERERROR' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.notequal">
|
||||
{{ 'USER.PASSWORD.NOTEQUAL' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.upperCaseValidator">
|
||||
{{ 'USER.VALIDATION.UPPERCASEMISSING' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.lowerCaseValidator">
|
||||
{{ 'USER.VALIDATION.LOWERCASEMISSING' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.minlength">
|
||||
{{ 'USER.VALIDATION.MINLENGTH' | translate:confirmPassword?.errors?.minlength }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</ng-container>
|
||||
</div>
|
||||
<div class="btn-container">
|
||||
<button color="primary" class="continue-button" [disabled]="orgForm.invalid || userForm.invalid"
|
||||
@ -170,11 +180,4 @@
|
||||
</form>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="currentCreateStep == 1">
|
||||
<button (click)="next()" color="primary" mat-raised-button class="continue-button" cdkFocusInitial
|
||||
type="submit">
|
||||
{{'CONTINUE' | translate}}
|
||||
</button>
|
||||
</ng-container>
|
||||
</div>
|
@ -140,3 +140,7 @@ h1 {
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
mat-checkbox {
|
||||
flex-basis: 100%;
|
||||
margin: .5rem;
|
||||
}
|
@ -7,7 +7,7 @@ import { lowerCaseValidator, numberValidator, symbolValidator, upperCaseValidato
|
||||
import { CreateOrgRequest, CreateUserRequest, Gender, OrgSetUpResponse } from 'src/app/proto/generated/admin_pb';
|
||||
import { PasswordComplexityPolicy } from 'src/app/proto/generated/auth_pb';
|
||||
import { AdminService } from 'src/app/services/admin.service';
|
||||
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';
|
||||
|
||||
function passwordConfirmValidator(c: AbstractControl): any {
|
||||
@ -54,14 +54,14 @@ export class OrgCreateComponent {
|
||||
public languages: string[] = ['de', 'en'];
|
||||
|
||||
public policy!: PasswordComplexityPolicy.AsObject;
|
||||
|
||||
public usePassword: boolean = false;
|
||||
constructor(
|
||||
private router: Router,
|
||||
private toast: ToastService,
|
||||
private adminService: AdminService,
|
||||
private _location: Location,
|
||||
private fb: FormBuilder,
|
||||
private authUserService: AuthUserService,
|
||||
private orgService: OrgService,
|
||||
) {
|
||||
const validators: Validators[] = [];
|
||||
|
||||
@ -69,49 +69,8 @@ export class OrgCreateComponent {
|
||||
name: ['', [Validators.required]],
|
||||
domain: [''],
|
||||
});
|
||||
this.authUserService.GetMyPasswordComplexityPolicy().then(data => {
|
||||
this.policy = data.toObject();
|
||||
if (this.policy.minLength) {
|
||||
validators.push(Validators.minLength(this.policy.minLength));
|
||||
}
|
||||
if (this.policy.hasLowercase) {
|
||||
validators.push(lowerCaseValidator);
|
||||
}
|
||||
if (this.policy.hasUppercase) {
|
||||
validators.push(upperCaseValidator);
|
||||
}
|
||||
if (this.policy.hasNumber) {
|
||||
validators.push(numberValidator);
|
||||
}
|
||||
if (this.policy.hasSymbol) {
|
||||
validators.push(symbolValidator);
|
||||
}
|
||||
|
||||
this.userForm = this.fb.group({
|
||||
userName: ['', [Validators.required]],
|
||||
firstName: ['', [Validators.required]],
|
||||
lastName: ['', [Validators.required]],
|
||||
email: ['', [Validators.required]],
|
||||
gender: [''],
|
||||
nickName: [''],
|
||||
preferredLanguage: [''],
|
||||
password: ['', validators],
|
||||
confirmPassword: ['', [...validators, passwordConfirmValidator]],
|
||||
});
|
||||
}).catch(error => {
|
||||
console.error(error);
|
||||
this.userForm = this.fb.group({
|
||||
userName: ['', [Validators.required]],
|
||||
firstName: ['', [Validators.required]],
|
||||
lastName: ['', [Validators.required]],
|
||||
email: ['', [Validators.required]],
|
||||
gender: [''],
|
||||
nickName: [''],
|
||||
preferredLanguage: [''],
|
||||
password: ['', validators],
|
||||
confirmPassword: ['', [...validators, passwordConfirmValidator]],
|
||||
});
|
||||
});
|
||||
this.initForm();
|
||||
}
|
||||
|
||||
public createSteps: number = 2;
|
||||
@ -150,6 +109,66 @@ export class OrgCreateComponent {
|
||||
this.currentCreateStep--;
|
||||
}
|
||||
|
||||
private initForm(pwdValidators?: Validators[]): void {
|
||||
if (pwdValidators) {
|
||||
console.log('init with pwd');
|
||||
this.userForm = this.fb.group({
|
||||
userName: ['', [Validators.required]],
|
||||
firstName: ['', [Validators.required]],
|
||||
lastName: ['', [Validators.required]],
|
||||
email: ['', [Validators.required]],
|
||||
gender: [''],
|
||||
nickName: [''],
|
||||
preferredLanguage: [''],
|
||||
password: ['', [...pwdValidators]],
|
||||
confirmPassword: ['', [...pwdValidators, passwordConfirmValidator]],
|
||||
});
|
||||
} else {
|
||||
console.log('init without pwd');
|
||||
this.userForm = this.fb.group({
|
||||
userName: ['', [Validators.required]],
|
||||
firstName: ['', [Validators.required]],
|
||||
lastName: ['', [Validators.required]],
|
||||
email: ['', [Validators.required]],
|
||||
gender: [''],
|
||||
nickName: [''],
|
||||
preferredLanguage: [''],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public initPwdValidators(): void {
|
||||
const validators: Validators[] = [Validators.required];
|
||||
|
||||
console.log(this.usePassword);
|
||||
if (this.usePassword) {
|
||||
this.orgService.GetDefaultPasswordComplexityPolicy().then(data => {
|
||||
this.policy = data.toObject();
|
||||
console.log(this.policy);
|
||||
|
||||
if (this.policy.minLength) {
|
||||
validators.push(Validators.minLength(this.policy.minLength));
|
||||
}
|
||||
if (this.policy.hasLowercase) {
|
||||
validators.push(lowerCaseValidator);
|
||||
}
|
||||
if (this.policy.hasUppercase) {
|
||||
validators.push(upperCaseValidator);
|
||||
}
|
||||
if (this.policy.hasNumber) {
|
||||
validators.push(numberValidator);
|
||||
}
|
||||
if (this.policy.hasSymbol) {
|
||||
validators.push(symbolValidator);
|
||||
}
|
||||
|
||||
this.initForm(validators);
|
||||
});
|
||||
} else {
|
||||
this.initForm();
|
||||
}
|
||||
}
|
||||
|
||||
public get name(): AbstractControl | null {
|
||||
return this.orgForm.get('name');
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
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';
|
||||
@ -26,6 +27,7 @@ import { OrgCreateComponent } from './org-create.component';
|
||||
MatSelectModule,
|
||||
PipesModule,
|
||||
TranslateModule,
|
||||
MatCheckboxModule,
|
||||
],
|
||||
})
|
||||
export class OrgCreateModule { }
|
||||
|
@ -58,7 +58,6 @@
|
||||
padding: .5rem 0;
|
||||
|
||||
.left-desc {
|
||||
text-transform: uppercase;
|
||||
color: #8795a1;
|
||||
font-size: .9rem;
|
||||
}
|
||||
|
@ -36,8 +36,7 @@
|
||||
</app-card>
|
||||
|
||||
<ng-template appHasRole [appHasRole]="['user.read', 'user.read:'+user?.id]">
|
||||
<app-card title="{{ 'USER.PROFILE.TITLE' | translate }}"
|
||||
description="{{'USER.PROFILE.DESCRIPTION' | translate}}">
|
||||
<app-card title="{{ 'USER.PROFILE.TITLE' | translate }}">
|
||||
<app-detail-form
|
||||
*ngIf="((authUserService.isAllowed(['user.write:' + user?.id, 'user.write']) | async) || false) as canwrite"
|
||||
[disabled]="canwrite" [genders]="genders" [languages]="languages" [profile]="user"
|
||||
|
@ -43,9 +43,7 @@
|
||||
<td mat-cell *matCellDef="let user">
|
||||
<mat-checkbox color="primary" (click)="$event.stopPropagation()"
|
||||
(change)="$event ? selection.toggle(user) : null" [checked]="selection.isSelected(user)">
|
||||
<app-avatar *ngIf="user && (user.displayName || (user.firstName && user.lastName))"
|
||||
class="avatar"
|
||||
[name]="user.displayName ? user.displayName : (user.firstName + ' '+ user.lastName)"
|
||||
<app-avatar *ngIf="user && user.displayName" class="avatar" [name]="user.displayName"
|
||||
[size]="32">
|
||||
</app-avatar>
|
||||
</mat-checkbox>
|
||||
|
@ -68,6 +68,15 @@ export class OrgService {
|
||||
);
|
||||
}
|
||||
|
||||
public async GetDefaultPasswordComplexityPolicy(): Promise<PasswordComplexityPolicy> {
|
||||
const req: Empty = new Empty();
|
||||
return await this.request(
|
||||
c => c.getDefaultPasswordComplexityPolicy,
|
||||
req,
|
||||
f => f,
|
||||
);
|
||||
}
|
||||
|
||||
public async GetMyOrg(): Promise<Org> {
|
||||
return await this.request(
|
||||
c => c.getMyOrg,
|
||||
|
@ -245,7 +245,8 @@
|
||||
"DOWNLOAD_FILE":"Datei download",
|
||||
"SELECTORGTOOLTIP":"Wähle diese Organisation",
|
||||
"PRIMARYDOMAIN":"Primäre Domain",
|
||||
"STATE":"Status"
|
||||
"STATE":"Status",
|
||||
"USEPASSWORD":"Initiales Password setzen"
|
||||
},
|
||||
"DOMAINS": {
|
||||
"NEW":"Domain hinzufügen",
|
||||
|
@ -245,7 +245,8 @@
|
||||
"DOWNLOAD_FILE":"Download file",
|
||||
"SELECTORGTOOLTIP":"Select this organisation",
|
||||
"PRIMARYDOMAIN":"Primary Domain",
|
||||
"STATE":"State"
|
||||
"STATE":"State",
|
||||
"USEPASSWORD":"Set initial password"
|
||||
},
|
||||
"DOMAINS": {
|
||||
"NEW":"Add Domain",
|
||||
|
Loading…
x
Reference in New Issue
Block a user