mirror of
https://github.com/zitadel/zitadel.git
synced 2025-02-28 21:17:23 +00:00
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 <38692350+hifabienne@users.noreply.github.com> Co-authored-by: Livio Spring <livio.a@gmail.com>
This commit is contained in:
parent
e39d82c031
commit
cbb5e90bac
@ -17,6 +17,15 @@ const routes: Routes = [
|
|||||||
path: 'signedout',
|
path: 'signedout',
|
||||||
loadChildren: () => import('./pages/signedout/signedout.module').then((m) => m.SignedoutModule),
|
loadChildren: () => import('./pages/signedout/signedout.module').then((m) => m.SignedoutModule),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'orgs/create',
|
||||||
|
component: OrgCreateComponent,
|
||||||
|
canActivate: [AuthGuard, RoleGuard],
|
||||||
|
data: {
|
||||||
|
roles: ['(org.create)?(iam.write)?'],
|
||||||
|
},
|
||||||
|
loadChildren: () => import('./pages/org-create/org-create.module').then((m) => m.OrgCreateModule),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'orgs',
|
path: 'orgs',
|
||||||
loadChildren: () => import('./pages/org-list/org-list.module').then((m) => m.OrgListModule),
|
loadChildren: () => import('./pages/org-list/org-list.module').then((m) => m.OrgListModule),
|
||||||
@ -52,15 +61,6 @@ const routes: Routes = [
|
|||||||
roles: ['iam.read', 'iam.write'],
|
roles: ['iam.read', 'iam.write'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'org/create',
|
|
||||||
component: OrgCreateComponent,
|
|
||||||
canActivate: [AuthGuard, RoleGuard],
|
|
||||||
data: {
|
|
||||||
roles: ['(org.create)?(iam.write)?'],
|
|
||||||
},
|
|
||||||
loadChildren: () => import('./pages/org-create/org-create.module').then((m) => m.OrgCreateModule),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'org',
|
path: 'org',
|
||||||
loadChildren: () => import('./pages/orgs/org.module').then((m) => m.OrgModule),
|
loadChildren: () => import('./pages/orgs/org.module').then((m) => m.OrgModule),
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
<a
|
<a
|
||||||
class="nav-item"
|
class="nav-item"
|
||||||
[routerLinkActiveOptions]="{ exact: true }"
|
[routerLinkActiveOptions]="{ exact: false }"
|
||||||
[routerLinkActive]="['active']"
|
[routerLinkActive]="['active']"
|
||||||
[routerLink]="['/orgs']"
|
[routerLink]="['/orgs']"
|
||||||
>
|
>
|
||||||
|
@ -56,7 +56,7 @@
|
|||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template cnslHasRole [hasRole]="['org.create', 'iam.write']">
|
<ng-template cnslHasRole [hasRole]="['org.create', 'iam.write']">
|
||||||
<button mat-button [routerLink]="['/org/create']" (click)="closedCard.emit()">
|
<button mat-button [routerLink]="['/orgs/create']" (click)="closedCard.emit()">
|
||||||
<mat-icon class="avatar">add</mat-icon>
|
<mat-icon class="avatar">add</mat-icon>
|
||||||
{{ 'MENU.NEWORG' | translate }}
|
{{ 'MENU.NEWORG' | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
</cnsl-filter-org>
|
</cnsl-filter-org>
|
||||||
|
|
||||||
<ng-template actions cnslHasRole [hasRole]="['org.create', 'iam.write']">
|
<ng-template actions cnslHasRole [hasRole]="['org.create', 'iam.write']">
|
||||||
<a [routerLink]="['/org', 'create']" color="primary" mat-raised-button class="cnsl-action-button">
|
<a [routerLink]="['/orgs', 'create']" color="primary" mat-raised-button class="cnsl-action-button">
|
||||||
<mat-icon class="icon">add</mat-icon>
|
<mat-icon class="icon">add</mat-icon>
|
||||||
<span>{{ 'ACTIONS.NEW' | translate }}</span>
|
<span>{{ 'ACTIONS.NEW' | translate }}</span>
|
||||||
<cnsl-action-keys (actionTriggered)="gotoRouterLink(['/org', 'create'])"> </cnsl-action-keys>
|
<cnsl-action-keys (actionTriggered)="gotoRouterLink(['/orgs', 'create'])"> </cnsl-action-keys>
|
||||||
</a>
|
</a>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
|
@ -4,15 +4,15 @@ import { MatDialog } from '@angular/material/dialog';
|
|||||||
import { Subject, Subscription } from 'rxjs';
|
import { Subject, Subscription } from 'rxjs';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
import {
|
import {
|
||||||
GetLabelPolicyResponse as AdminGetLabelPolicyResponse,
|
GetLabelPolicyResponse as AdminGetLabelPolicyResponse,
|
||||||
GetPreviewLabelPolicyResponse as AdminGetPreviewLabelPolicyResponse,
|
GetPreviewLabelPolicyResponse as AdminGetPreviewLabelPolicyResponse,
|
||||||
UpdateLabelPolicyRequest,
|
UpdateLabelPolicyRequest,
|
||||||
} from 'src/app/proto/generated/zitadel/admin_pb';
|
} from 'src/app/proto/generated/zitadel/admin_pb';
|
||||||
import {
|
import {
|
||||||
AddCustomLabelPolicyRequest,
|
AddCustomLabelPolicyRequest,
|
||||||
GetLabelPolicyResponse as MgmtGetLabelPolicyResponse,
|
GetLabelPolicyResponse as MgmtGetLabelPolicyResponse,
|
||||||
GetPreviewLabelPolicyResponse as MgmtGetPreviewLabelPolicyResponse,
|
GetPreviewLabelPolicyResponse as MgmtGetPreviewLabelPolicyResponse,
|
||||||
UpdateCustomLabelPolicyRequest,
|
UpdateCustomLabelPolicyRequest,
|
||||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||||
import { Org } from 'src/app/proto/generated/zitadel/org_pb';
|
import { Org } from 'src/app/proto/generated/zitadel/org_pb';
|
||||||
import { LabelPolicy } from 'src/app/proto/generated/zitadel/policy_pb';
|
import { LabelPolicy } from 'src/app/proto/generated/zitadel/policy_pb';
|
||||||
@ -112,7 +112,9 @@ export class PrivateLabelingPolicyComponent implements OnInit, OnDestroy {
|
|||||||
const file = filelist.item(0);
|
const file = filelist.item(0);
|
||||||
if (file) {
|
if (file) {
|
||||||
if (file.size > MAX_ALLOWED_SIZE) {
|
if (file.size > MAX_ALLOWED_SIZE) {
|
||||||
this.toast.showInfo('POLICY.PRIVATELABELING.MAXSIZEEXCEEDED', true);
|
this.toast.showError('POLICY.PRIVATELABELING.MAXSIZEEXCEEDED', false, true);
|
||||||
|
} else if (file.type === 'image/svg+xml') {
|
||||||
|
this.toast.showError('POLICY.PRIVATELABELING.NOSVGSUPPORTED', false, true);
|
||||||
} else {
|
} else {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('file', file);
|
formData.append('file', file);
|
||||||
|
@ -115,14 +115,23 @@
|
|||||||
</mat-select>
|
</mat-select>
|
||||||
</cnsl-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<mat-checkbox
|
<div class="email-is-verified">
|
||||||
class="checkbox"
|
<mat-checkbox class="block-checkbox" formControlName="isVerified">
|
||||||
[(ngModel)]="usePassword"
|
{{ 'USER.LOGINMETHODS.EMAIL.ISVERIFIED' | translate }}
|
||||||
[ngModelOptions]="{ standalone: true }"
|
</mat-checkbox>
|
||||||
(change)="initPwdValidators()"
|
|
||||||
>
|
<mat-checkbox
|
||||||
{{ 'ORG.PAGES.USEPASSWORD' | translate }}</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">
|
<ng-container *ngIf="usePassword && pwdForm">
|
||||||
<p class="section cnsl-secondary-text">{{ 'USER.CREATE.PASSWORDSECTION' | translate }}</p>
|
<p class="section cnsl-secondary-text">{{ 'USER.CREATE.PASSWORDSECTION' | translate }}</p>
|
||||||
|
@ -58,6 +58,16 @@ h1 {
|
|||||||
flex: 1 0 33%;
|
flex: 1 0 33%;
|
||||||
margin: 0 0.5rem;
|
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 {
|
.pwd-form {
|
||||||
@ -109,11 +119,6 @@ h1 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox {
|
|
||||||
flex-basis: 100%;
|
|
||||||
margin: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.complexity-view {
|
.complexity-view {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0 0.5rem;
|
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 { PasswordComplexityPolicy } from 'src/app/proto/generated/zitadel/policy_pb';
|
||||||
import { Gender } from 'src/app/proto/generated/zitadel/user_pb';
|
import { Gender } from 'src/app/proto/generated/zitadel/user_pb';
|
||||||
import { AdminService } from 'src/app/services/admin.service';
|
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 { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||||
import { ToastService } from 'src/app/services/toast.service';
|
import { ToastService } from 'src/app/services/toast.service';
|
||||||
@ -69,7 +70,16 @@ export class OrgCreateComponent {
|
|||||||
private fb: UntypedFormBuilder,
|
private fb: UntypedFormBuilder,
|
||||||
private mgmtService: ManagementService,
|
private mgmtService: ManagementService,
|
||||||
private authService: GrpcAuthService,
|
private authService: GrpcAuthService,
|
||||||
|
private breadcrumbService: BreadcrumbService,
|
||||||
) {
|
) {
|
||||||
|
const instanceBread = new Breadcrumb({
|
||||||
|
type: BreadcrumbType.INSTANCE,
|
||||||
|
name: 'Instance',
|
||||||
|
routerLink: ['/instance'],
|
||||||
|
});
|
||||||
|
|
||||||
|
breadcrumbService.setBreadcrumb([instanceBread]);
|
||||||
|
|
||||||
this.authService
|
this.authService
|
||||||
.isAllowed(['iam.write'])
|
.isAllowed(['iam.write'])
|
||||||
.pipe(take(1))
|
.pipe(take(1))
|
||||||
@ -96,7 +106,9 @@ export class OrgCreateComponent {
|
|||||||
createOrgRequest.setDomain(this.domain?.value);
|
createOrgRequest.setDomain(this.domain?.value);
|
||||||
|
|
||||||
const humanRequest: SetUpOrgRequest.Human = new SetUpOrgRequest.Human();
|
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);
|
humanRequest.setUserName(this.userName?.value);
|
||||||
|
|
||||||
const profile: SetUpOrgRequest.Human.Profile = new SetUpOrgRequest.Human.Profile();
|
const profile: SetUpOrgRequest.Human.Profile = new SetUpOrgRequest.Human.Profile();
|
||||||
@ -143,6 +155,7 @@ export class OrgCreateComponent {
|
|||||||
firstName: ['', [Validators.required]],
|
firstName: ['', [Validators.required]],
|
||||||
lastName: ['', [Validators.required]],
|
lastName: ['', [Validators.required]],
|
||||||
email: ['', [Validators.required]],
|
email: ['', [Validators.required]],
|
||||||
|
isVerified: [false, []],
|
||||||
gender: [''],
|
gender: [''],
|
||||||
nickName: [''],
|
nickName: [''],
|
||||||
preferredLanguage: [''],
|
preferredLanguage: [''],
|
||||||
@ -243,6 +256,10 @@ export class OrgCreateComponent {
|
|||||||
return this.userForm.get('email');
|
return this.userForm.get('email');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get isVerified(): AbstractControl | null {
|
||||||
|
return this.userForm.get('isVerified');
|
||||||
|
}
|
||||||
|
|
||||||
public get nickName(): AbstractControl | null {
|
public get nickName(): AbstractControl | null {
|
||||||
return this.userForm.get('nickName');
|
return this.userForm.get('nickName');
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
|||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||||
import { CreateLayoutModule } from 'src/app/modules/create-layout/create-layout.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 { InputModule } from 'src/app/modules/input/input.module';
|
||||||
import { PasswordComplexityViewModule } from 'src/app/modules/password-complexity-view/password-complexity-view.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';
|
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
|
||||||
@ -23,6 +24,7 @@ import { OrgCreateComponent } from './org-create.component';
|
|||||||
CommonModule,
|
CommonModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
|
InfoSectionModule,
|
||||||
InputModule,
|
InputModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
|
@ -1,41 +1,45 @@
|
|||||||
<cnsl-detail-layout [hasBackButton]="true" title="{{ 'USER.PASSWORD.TITLE' | translate }}"
|
<cnsl-detail-layout [hasBackButton]="true" title="{{ 'USER.PASSWORD.TITLE' | translate }}">
|
||||||
description="{{ 'USER.PASSWORD.DESCRIPTION' | translate }}">
|
<p class="password-info cnsl-secondary-text" sub>{{ 'USER.PASSWORD.DESCRIPTION' | translate }}</p>
|
||||||
|
|
||||||
<ng-container *ngIf="userId; else authUser">
|
<ng-container *ngIf="userId; else authUser">
|
||||||
<div class="validation" *ngIf="this.policy">
|
<form
|
||||||
<cnsl-password-complexity-view [policy]="this.policy" [password]="password">
|
*ngIf="passwordForm"
|
||||||
</cnsl-password-complexity-view>
|
autocomplete="new-password"
|
||||||
</div>
|
[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"
|
<span cnslError *ngIf="password?.errors?.required">
|
||||||
(ngSubmit)="setInitialPassword(userId)">
|
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||||
<div class="content center">
|
</span>
|
||||||
<cnsl-form-field class="formfield">
|
</cnsl-form-field>
|
||||||
<cnsl-label>{{ 'USER.PASSWORD.NEW' | translate }}</cnsl-label>
|
<cnsl-form-field class="formfield">
|
||||||
<input cnslInput autocomplete="off" name="password" formControlName="password" type="password" />
|
<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">
|
<div class="validation" *ngIf="this.policy">
|
||||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
<cnsl-password-complexity-view [policy]="this.policy" [password]="password"> </cnsl-password-complexity-view>
|
||||||
</span>
|
</div>
|
||||||
</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>
|
</div>
|
||||||
|
|
||||||
|
<button class="submit-button" [disabled]="passwordForm.invalid" mat-raised-button color="primary">
|
||||||
|
{{ 'USER.PASSWORD.SET' | translate }}
|
||||||
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-template #authUser>
|
<ng-template #authUser>
|
||||||
<form *ngIf="passwordForm" [formGroup]="passwordForm" (ngSubmit)="setPassword()">
|
<form *ngIf="passwordForm" [formGroup]="passwordForm" (ngSubmit)="setPassword()">
|
||||||
<div class="content">
|
<div class="password-content">
|
||||||
<cnsl-form-field class="formfield">
|
<cnsl-form-field class="formfield">
|
||||||
<cnsl-label>{{ 'USER.PASSWORD.OLD' | translate }}</cnsl-label>
|
<cnsl-label>{{ 'USER.PASSWORD.OLD' | translate }}</cnsl-label>
|
||||||
<input cnslInput autocomplete="off" name="password" type="password" formControlName="currentPassword" />
|
<input cnslInput autocomplete="off" name="password" type="password" formControlName="currentPassword" />
|
||||||
@ -45,29 +49,36 @@
|
|||||||
</cnsl-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<div class="validation between" *ngIf="this.policy">
|
<div class="validation between" *ngIf="this.policy">
|
||||||
<cnsl-password-complexity-view [policy]="this.policy" [password]="newPassword">
|
<cnsl-password-complexity-view [policy]="this.policy" [password]="newPassword"> </cnsl-password-complexity-view>
|
||||||
</cnsl-password-complexity-view>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<cnsl-form-field class="formfield">
|
<div class="side-by-side">
|
||||||
<cnsl-label>{{ 'USER.PASSWORD.NEW' | translate }}</cnsl-label>
|
<cnsl-form-field class="formfield">
|
||||||
<input cnslInput autocomplete="off" name="new password" type="password" formControlName="newPassword" />
|
<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">
|
<span cnslError *ngIf="newPassword?.errors?.required">
|
||||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||||
</span>
|
</span>
|
||||||
</cnsl-form-field>
|
</cnsl-form-field>
|
||||||
<cnsl-form-field class="formfield">
|
<cnsl-form-field class="formfield">
|
||||||
<cnsl-label>{{ 'USER.PASSWORD.CONFIRM' | translate }}</cnsl-label>
|
<cnsl-label>{{ 'USER.PASSWORD.CONFIRM' | translate }}</cnsl-label>
|
||||||
<input cnslInput autocomplete="off" name="password repeating" type="password"
|
<input
|
||||||
formControlName="confirmPassword" />
|
cnslInput
|
||||||
<span cnslError *ngIf="confirmPassword?.errors?.notequal">
|
autocomplete="off"
|
||||||
{{ 'USER.PASSWORD.NOTEQUAL' | translate }}
|
name="password repeating"
|
||||||
</span>
|
type="password"
|
||||||
</cnsl-form-field>
|
formControlName="confirmPassword"
|
||||||
|
/>
|
||||||
|
<span cnslError *ngIf="confirmPassword?.errors?.notequal">
|
||||||
|
{{ 'USER.PASSWORD.NOTEQUAL' | translate }}
|
||||||
|
</span>
|
||||||
|
</cnsl-form-field>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="submit-button" [disabled]="passwordForm.invalid" mat-raised-button color="primary">{{
|
<button class="submit-button" [disabled]="passwordForm.invalid" mat-raised-button color="primary">
|
||||||
'USER.PASSWORD.RESET' | translate }}</button>
|
{{ 'USER.PASSWORD.RESET' | translate }}
|
||||||
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</ng-template>
|
</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;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
margin: 0 -0.5rem;
|
max-width: 40rem;
|
||||||
|
|
||||||
.formfield {
|
.side-by-side {
|
||||||
margin: 0 0.5rem;
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
flex-direction: row;
|
||||||
|
margin: 0 -0.5rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 400px;
|
|
||||||
|
@media only screen and (max-width: 500px) {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.formfield {
|
||||||
|
flex: 1;
|
||||||
|
margin: 0 0.5rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.center {
|
.formfield {
|
||||||
align-items: center;
|
max-width: 400px;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,7 +39,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.submit-button {
|
.submit-button {
|
||||||
margin-top: 100px;
|
margin-top: 2rem;
|
||||||
display: block;
|
display: block;
|
||||||
padding: 0.5rem 4rem;
|
padding: 0.5rem 4rem;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ export class ToastService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public showError(error: any | string, isGrpc: boolean = true): void {
|
public showError(error: any | string, isGrpc: boolean = true, i18nKey: boolean = false): void {
|
||||||
if (isGrpc) {
|
if (isGrpc) {
|
||||||
const { message, code, metadata } = error;
|
const { message, code, metadata } = error;
|
||||||
if (code !== 16) {
|
if (code !== 16) {
|
||||||
@ -44,6 +44,13 @@ export class ToastService {
|
|||||||
this.showMessage(decodeURI(message), value, false);
|
this.showMessage(decodeURI(message), value, false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
} else if (i18nKey) {
|
||||||
|
this.translate
|
||||||
|
.get(error)
|
||||||
|
.pipe(take(1))
|
||||||
|
.subscribe((value) => {
|
||||||
|
this.showMessage(value, '', false);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
this.showMessage(error as string, '', false);
|
this.showMessage(error as string, '', false);
|
||||||
}
|
}
|
||||||
|
@ -482,7 +482,7 @@
|
|||||||
"SET": "Passwort neu setzen",
|
"SET": "Passwort neu setzen",
|
||||||
"RESENDNOTIFICATION": "Email zum Zurücksetzen senden",
|
"RESENDNOTIFICATION": "Email zum Zurücksetzen senden",
|
||||||
"REQUIRED": "Bitte prüfe, dass alle notwendigen Felder ausgefüllt sind.",
|
"REQUIRED": "Bitte prüfe, dass alle notwendigen Felder ausgefüllt sind.",
|
||||||
"MINLENGTHERROR": "Das Passwort muss mindestens {{value}} Zeichen lang sein.",
|
"MINLENGTHERROR": "Muss mindestens {{value}} Zeichen lang sein.",
|
||||||
"NOTEQUAL": "Die Passwörter stimmen nicht überein."
|
"NOTEQUAL": "Die Passwörter stimmen nicht überein."
|
||||||
},
|
},
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
@ -542,10 +542,10 @@
|
|||||||
"REQUIRED": "Das Eingabefeld ist leer.",
|
"REQUIRED": "Das Eingabefeld ist leer.",
|
||||||
"MINLENGTH": "Das Passwort muss mindestens {{requiredLength}} Zeichen lang sein.",
|
"MINLENGTH": "Das Passwort muss mindestens {{requiredLength}} Zeichen lang sein.",
|
||||||
"NOEMAIL": "Benutzername darf keine E-Mail-Adresse sein.",
|
"NOEMAIL": "Benutzername darf keine E-Mail-Adresse sein.",
|
||||||
"UPPERCASEMISSING": "Passwort muss einen Grossbuchstaben beinhalten.",
|
"UPPERCASEMISSING": "Muss einen Grossbuchstaben beinhalten.",
|
||||||
"LOWERCASEMISSING": "Passwort muss einen Kleinbuchstaben beinhalten.",
|
"LOWERCASEMISSING": "Muss einen Kleinbuchstaben beinhalten.",
|
||||||
"SYMBOLERROR": "Das Passwort muss ein Symbol/Satzzeichen beinhalten.",
|
"SYMBOLERROR": "Muss ein Symbol/Satzzeichen beinhalten.",
|
||||||
"NUMBERERROR": "Das Passwort muss eine Ziffer beinhalten."
|
"NUMBERERROR": "Muss eine Ziffer beinhalten."
|
||||||
},
|
},
|
||||||
"STATE": {
|
"STATE": {
|
||||||
"0": "Unbekannt",
|
"0": "Unbekannt",
|
||||||
@ -978,9 +978,9 @@
|
|||||||
"PWD_COMPLEXITY": {
|
"PWD_COMPLEXITY": {
|
||||||
"TITLE": "Passwortkomplexität",
|
"TITLE": "Passwortkomplexität",
|
||||||
"DESCRIPTION": "Stellt sicher, dass alle festgelegten Passwörter einem bestimmten Muster entsprechen.",
|
"DESCRIPTION": "Stellt sicher, dass alle festgelegten Passwörter einem bestimmten Muster entsprechen.",
|
||||||
"SYMBOLANDNUMBERERROR": "Das Passwort muss ein Symbol/Satzzeichen und eine Ziffer beinhalten.",
|
"SYMBOLANDNUMBERERROR": "Muss ein Symbol/Satzzeichen und eine Ziffer beinhalten.",
|
||||||
"SYMBOLERROR": "Das Passwort muss ein Symbol/Satzzeichen beinhalten.",
|
"SYMBOLERROR": "Muss ein Symbol/Satzzeichen beinhalten.",
|
||||||
"NUMBERERROR": "Das Passwort muss eine Ziffer beinhalten.",
|
"NUMBERERROR": "Muss eine Ziffer beinhalten.",
|
||||||
"PATTERNERROR": "Das Passwort erfüllt nicht die vorgeschriebene Richtlinie."
|
"PATTERNERROR": "Das Passwort erfüllt nicht die vorgeschriebene Richtlinie."
|
||||||
},
|
},
|
||||||
"PRIVATELABELING": {
|
"PRIVATELABELING": {
|
||||||
@ -1005,6 +1005,7 @@
|
|||||||
"MAXSIZE": "Die maximale Grösse von Uploads ist mit 524kB begrenzt",
|
"MAXSIZE": "Die maximale Grösse von Uploads ist mit 524kB begrenzt",
|
||||||
"EMAILNOSVG": "Das SVG Dateiformat wird nicht in emails unterstützt. Laden Sie deshalb ihr Logo im PNG oder einem anderen unterstützten Format hoch.",
|
"EMAILNOSVG": "Das SVG Dateiformat wird nicht in emails unterstützt. Laden Sie deshalb ihr Logo im PNG oder einem anderen unterstützten Format hoch.",
|
||||||
"MAXSIZEEXCEEDED": "Maximale Grösse von 524kB überschritten",
|
"MAXSIZEEXCEEDED": "Maximale Grösse von 524kB überschritten",
|
||||||
|
"NOSVGSUPPORTED": "SVG werden nicht unterstützt!",
|
||||||
"FONTINLOGINONLY": "Die Schriftart wird momentan nur im Login interface angezeigt.",
|
"FONTINLOGINONLY": "Die Schriftart wird momentan nur im Login interface angezeigt.",
|
||||||
"VIEWS": {
|
"VIEWS": {
|
||||||
"PREVIEW": "Vorschau",
|
"PREVIEW": "Vorschau",
|
||||||
|
@ -482,7 +482,7 @@
|
|||||||
"SET": "Set New Password",
|
"SET": "Set New Password",
|
||||||
"RESENDNOTIFICATION": "Send Password Reset Link",
|
"RESENDNOTIFICATION": "Send Password Reset Link",
|
||||||
"REQUIRED": "Some required fields are missing.",
|
"REQUIRED": "Some required fields are missing.",
|
||||||
"MINLENGTHERROR": "The password has to be at least {{value}} characters long.",
|
"MINLENGTHERROR": "Has to be at least {{value}} characters long.",
|
||||||
"NOTEQUAL": "The passwords provided do not match."
|
"NOTEQUAL": "The passwords provided do not match."
|
||||||
},
|
},
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
@ -542,10 +542,10 @@
|
|||||||
"REQUIRED": "The input field is empty.",
|
"REQUIRED": "The input field is empty.",
|
||||||
"MINLENGTH": "The password has to be at least {{requiredLength}} characters long.",
|
"MINLENGTH": "The password has to be at least {{requiredLength}} characters long.",
|
||||||
"NOEMAIL": "The user name cannot be an e-mail address.",
|
"NOEMAIL": "The user name cannot be an e-mail address.",
|
||||||
"UPPERCASEMISSING": "The password must include an uppercase character.",
|
"UPPERCASEMISSING": "Must include an uppercase character.",
|
||||||
"LOWERCASEMISSING": "The password must include a lowercase character.",
|
"LOWERCASEMISSING": "Must include a lowercase character.",
|
||||||
"SYMBOLERROR": "The password must include a symbol or punctuation mark.",
|
"SYMBOLERROR": "Must include a symbol or punctuation mark.",
|
||||||
"NUMBERERROR": "The password must include a digit."
|
"NUMBERERROR": "Must include a digit."
|
||||||
},
|
},
|
||||||
"STATE": {
|
"STATE": {
|
||||||
"0": "Unknown",
|
"0": "Unknown",
|
||||||
@ -978,9 +978,9 @@
|
|||||||
"PWD_COMPLEXITY": {
|
"PWD_COMPLEXITY": {
|
||||||
"TITLE": "Password Complexity",
|
"TITLE": "Password Complexity",
|
||||||
"DESCRIPTION": "Ensures that all set passwords correspond to a specific pattern",
|
"DESCRIPTION": "Ensures that all set passwords correspond to a specific pattern",
|
||||||
"SYMBOLANDNUMBERERROR": "The password must consist of a digit and a symbol/punctuation mark.",
|
"SYMBOLANDNUMBERERROR": "Must consist of a digit and a symbol/punctuation mark.",
|
||||||
"SYMBOLERROR": "The password must include a symbol/punctuation mark.",
|
"SYMBOLERROR": "Must include a symbol/punctuation mark.",
|
||||||
"NUMBERERROR": "The password must include a digit.",
|
"NUMBERERROR": "Must include a digit.",
|
||||||
"PATTERNERROR": "The password does not meet the required pattern."
|
"PATTERNERROR": "The password does not meet the required pattern."
|
||||||
},
|
},
|
||||||
"PRIVATELABELING": {
|
"PRIVATELABELING": {
|
||||||
@ -1005,6 +1005,7 @@
|
|||||||
"MAXSIZE": "The maximum size is limited to 524kB",
|
"MAXSIZE": "The maximum size is limited to 524kB",
|
||||||
"EMAILNOSVG": "The SVG file format is not supported in emails. Therefore upload your logo in PNG or other supported format.",
|
"EMAILNOSVG": "The SVG file format is not supported in emails. Therefore upload your logo in PNG or other supported format.",
|
||||||
"MAXSIZEEXCEEDED": "Maximum size of 524kB exceeded.",
|
"MAXSIZEEXCEEDED": "Maximum size of 524kB exceeded.",
|
||||||
|
"NOSVGSUPPORTED": "SVG are not supported!",
|
||||||
"FONTINLOGINONLY": "The font is currently only displayed in the login interface.",
|
"FONTINLOGINONLY": "The font is currently only displayed in the login interface.",
|
||||||
"VIEWS": {
|
"VIEWS": {
|
||||||
"PREVIEW": "Preview",
|
"PREVIEW": "Preview",
|
||||||
|
@ -482,7 +482,7 @@
|
|||||||
"SET": "Définir un nouveau mot de passe",
|
"SET": "Définir un nouveau mot de passe",
|
||||||
"RESENDNOTIFICATION": "Envoyer le lien de réinitialisation du mot de passe",
|
"RESENDNOTIFICATION": "Envoyer le lien de réinitialisation du mot de passe",
|
||||||
"REQUIRED": "Certains champs obligatoires sont manquants.",
|
"REQUIRED": "Certains champs obligatoires sont manquants.",
|
||||||
"MINLENGTHERROR": "Le mot de passe doit comporter au moins{{value}} caractères.",
|
"MINLENGTHERROR": "Doit comporter au moins {{value}} caractères.",
|
||||||
"NOTEQUAL": "Les mots de passe fournis ne correspondent pas."
|
"NOTEQUAL": "Les mots de passe fournis ne correspondent pas."
|
||||||
},
|
},
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
@ -542,10 +542,10 @@
|
|||||||
"REQUIRED": "Le champ de saisie est vide.",
|
"REQUIRED": "Le champ de saisie est vide.",
|
||||||
"MINLENGTH": "Le mot de passe doit comporter au moins{{length}} caractères.",
|
"MINLENGTH": "Le mot de passe doit comporter au moins{{length}} caractères.",
|
||||||
"NOEMAIL": "Le nom d'utilisateur ne peut pas être une adresse électronique.",
|
"NOEMAIL": "Le nom d'utilisateur ne peut pas être une adresse électronique.",
|
||||||
"UPPERCASEMISSING": "Le mot de passe doit comporter un caractère majuscule.",
|
"UPPERCASEMISSING": "Doit inclure un caractère majuscule.",
|
||||||
"LOWERCASEMISSING": "Le mot de passe doit inclure un caractère minuscule.",
|
"LOWERCASEMISSING": "Doit inclure un caractère minuscule.",
|
||||||
"SYMBOLERROR": "Le mot de passe doit inclure un symbole ou un signe de ponctuation.",
|
"SYMBOLERROR": "Doit inclure un symbole ou un signe de ponctuation.",
|
||||||
"NUMBERERROR": "Le mot de passe doit contenir un chiffre."
|
"NUMBERERROR": "Doit inclure un chiffre."
|
||||||
},
|
},
|
||||||
"STATE": {
|
"STATE": {
|
||||||
"0": "Inconnu",
|
"0": "Inconnu",
|
||||||
@ -978,9 +978,9 @@
|
|||||||
"PWD_COMPLEXITY": {
|
"PWD_COMPLEXITY": {
|
||||||
"TITLE": "Complexité des mots de passe",
|
"TITLE": "Complexité des mots de passe",
|
||||||
"DESCRIPTION": "Assure que tous les mots de passe définis correspondent à un modèle spécifique.",
|
"DESCRIPTION": "Assure que tous les mots de passe définis correspondent à un modèle spécifique.",
|
||||||
"SYMBOLANDNUMBERERROR": "Le mot de passe doit être composé d'un chiffre et d'un symbole/une marque de ponctuation.",
|
"SYMBOLANDNUMBERERROR": "Doit être composé d'un chiffre et d'un symbole/signe de ponctuation.",
|
||||||
"SYMBOLERROR": "Le mot de passe doit comprendre un symbole ou un signe de ponctuation.",
|
"SYMBOLERROR": "Doit inclure un symbole/un signe de ponctuation.",
|
||||||
"NUMBERERROR": "Le mot de passe doit comprendre un chiffre.",
|
"NUMBERERROR": "Doit inclure un chiffre.",
|
||||||
"PATTERNERROR": "Le mot de passe ne correspond pas au modèle requis."
|
"PATTERNERROR": "Le mot de passe ne correspond pas au modèle requis."
|
||||||
},
|
},
|
||||||
"PRIVATELABELING": {
|
"PRIVATELABELING": {
|
||||||
@ -1005,6 +1005,7 @@
|
|||||||
"MAXSIZE": "La taille maximale est limitée à 524 Ko.",
|
"MAXSIZE": "La taille maximale est limitée à 524 Ko.",
|
||||||
"EMAILNOSVG": "Le format de fichier SVG n'est pas supporté dans les emails. Téléchargez donc votre logo en PNG ou dans un autre format pris en charge.",
|
"EMAILNOSVG": "Le format de fichier SVG n'est pas supporté dans les emails. Téléchargez donc votre logo en PNG ou dans un autre format pris en charge.",
|
||||||
"MAXSIZEEXCEEDED": "La taille maximale de 524kB est dépassée.",
|
"MAXSIZEEXCEEDED": "La taille maximale de 524kB est dépassée.",
|
||||||
|
"NOSVGSUPPORTED": "SVG n'est pas pris en charge",
|
||||||
"FONTINLOGINONLY": "La police n'est actuellement affichée que dans l'interface de connexion.",
|
"FONTINLOGINONLY": "La police n'est actuellement affichée que dans l'interface de connexion.",
|
||||||
"VIEWS": {
|
"VIEWS": {
|
||||||
"PREVIEW": "Aperçu",
|
"PREVIEW": "Aperçu",
|
||||||
|
@ -482,7 +482,7 @@
|
|||||||
"SET": "Imposta nuova password",
|
"SET": "Imposta nuova password",
|
||||||
"RESENDNOTIFICATION": "Invia email per la reimpostazione",
|
"RESENDNOTIFICATION": "Invia email per la reimpostazione",
|
||||||
"REQUIRED": "Mancano alcuni campi obbligatori.",
|
"REQUIRED": "Mancano alcuni campi obbligatori.",
|
||||||
"MINLENGTHERROR": "La password deve essere lunga almeno {{valore}} caratteri.",
|
"MINLENGTHERROR": "Deve essere lunga almeno {{valore}} caratteri.",
|
||||||
"NOTEQUAL": "Le password fornite non corrispondono."
|
"NOTEQUAL": "Le password fornite non corrispondono."
|
||||||
},
|
},
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
@ -540,12 +540,12 @@
|
|||||||
"INVALIDPATTERN": "La password non soddisfa le regole definite.",
|
"INVALIDPATTERN": "La password non soddisfa le regole definite.",
|
||||||
"NOTANEMAIL": "Il valore dato non \u00e8 un indirizzo e-mail",
|
"NOTANEMAIL": "Il valore dato non \u00e8 un indirizzo e-mail",
|
||||||
"REQUIRED": "Il campo di input \u00e8 vuoto.",
|
"REQUIRED": "Il campo di input \u00e8 vuoto.",
|
||||||
"MINLENGTH": "La password deve essere lunga almeno {{requiredLength}} caratteri.",
|
"MINLENGTH": "Deve essere lunga almeno {{requiredLength}} caratteri.",
|
||||||
"NOEMAIL": "Il nome utente non pu\u00f2 essere un indirizzo e-mail.",
|
"NOEMAIL": "Il nome utente non pu\u00f2 essere un indirizzo e-mail.",
|
||||||
"UPPERCASEMISSING": "La password deve includere un carattere maiuscolo.",
|
"UPPERCASEMISSING": "Deve includere un carattere maiuscolo.",
|
||||||
"LOWERCASEMISSING": "La password deve includere un carattere minuscolo.",
|
"LOWERCASEMISSING": "Deve includere un carattere minuscolo.",
|
||||||
"SYMBOLERROR": "La password deve includere un simbolo o un segno di punteggiatura.",
|
"SYMBOLERROR": "Deve includere un simbolo o un segno di punteggiatura.",
|
||||||
"NUMBERERROR": "La password deve includere una cifra."
|
"NUMBERERROR": "Deve includere una cifra."
|
||||||
},
|
},
|
||||||
"STATE": {
|
"STATE": {
|
||||||
"0": "Sconosciuto",
|
"0": "Sconosciuto",
|
||||||
@ -978,9 +978,9 @@
|
|||||||
"PWD_COMPLEXITY": {
|
"PWD_COMPLEXITY": {
|
||||||
"TITLE": "Complessit\u00e0 della password",
|
"TITLE": "Complessit\u00e0 della password",
|
||||||
"DESCRIPTION": "Assicura che tutte le password impostate corrispondano a un modello specifico",
|
"DESCRIPTION": "Assicura che tutte le password impostate corrispondano a un modello specifico",
|
||||||
"SYMBOLANDNUMBERERROR": "La password deve essere composta da una cifra e un simbolo/segno di interpunzione.",
|
"SYMBOLANDNUMBERERROR": "Deve essere composta da una cifra e un simbolo/segno di interpunzione.",
|
||||||
"SYMBOLERROR": "La password deve includere un simbolo/segno di punteggiatura.",
|
"SYMBOLERROR": "Deve includere un simbolo/segno di punteggiatura.",
|
||||||
"NUMBERERROR": "La password deve includere una cifra.",
|
"NUMBERERROR": "Deve includere una cifra.",
|
||||||
"PATTERNERROR": "La password non corrisponde al modello richiesto."
|
"PATTERNERROR": "La password non corrisponde al modello richiesto."
|
||||||
},
|
},
|
||||||
"PRIVATELABELING": {
|
"PRIVATELABELING": {
|
||||||
@ -1005,6 +1005,7 @@
|
|||||||
"MAXSIZE": "La dimensione massima \u00e8 limitata a 524kB",
|
"MAXSIZE": "La dimensione massima \u00e8 limitata a 524kB",
|
||||||
"EMAILNOSVG": "Il formato di file SVG non \u00e8 supportato nelle email. Perci\u00f2 carica il tuo logo in PNG o in un altro formato supportato.",
|
"EMAILNOSVG": "Il formato di file SVG non \u00e8 supportato nelle email. Perci\u00f2 carica il tuo logo in PNG o in un altro formato supportato.",
|
||||||
"MAXSIZEEXCEEDED": "Dimensione massima di 524kB superata.",
|
"MAXSIZEEXCEEDED": "Dimensione massima di 524kB superata.",
|
||||||
|
"NOSVGSUPPORTED": "SVG non sono supportati",
|
||||||
"FONTINLOGINONLY": "Il carattere \u00e8 attualmente visualizzato solo nell'interfaccia di accesso.",
|
"FONTINLOGINONLY": "Il carattere \u00e8 attualmente visualizzato solo nell'interfaccia di accesso.",
|
||||||
"VIEWS": {
|
"VIEWS": {
|
||||||
"PREVIEW": "Anteprima",
|
"PREVIEW": "Anteprima",
|
||||||
|
@ -13,7 +13,7 @@ When planning your applications, investing time in researching your apps archite
|
|||||||
This guide introduces you to the grouping and structuring of ZITADEL projects which forms the base for all projects. This can be used as a quick start to the [B2B scenario](./b2b), which is merely focused on planning considerations if you are having projects with multiple organizations.
|
This guide introduces you to the grouping and structuring of ZITADEL projects which forms the base for all projects. This can be used as a quick start to the [B2B scenario](./b2b), which is merely focused on planning considerations if you are having projects with multiple organizations.
|
||||||
|
|
||||||
The journey of this guide starts with creating an Organization, the outermost layer of ZITADEL within your instance, as it is the vessel for projects, roles, applications and users.
|
The journey of this guide starts with creating an Organization, the outermost layer of ZITADEL within your instance, as it is the vessel for projects, roles, applications and users.
|
||||||
Creation can be done from [ZITADEL Console](https://{your_domain}.zitadel.cloud/ui/console/org/create). You can choose your current account for the organization owner or create a new one.
|
Creation can be done from [ZITADEL Console](https://{your_domain}.zitadel.cloud/ui/console/orgs/create). You can choose your current account for the organization owner or create a new one.
|
||||||
|
|
||||||
Depending on your Software Development Life Cycle (SDLC) you can create multiple organizations or projects to keep your applications environments seperated.
|
Depending on your Software Development Life Cycle (SDLC) you can create multiple organizations or projects to keep your applications environments seperated.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user