mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 21:17:32 +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:
@@ -155,7 +155,7 @@ export class AppComponent implements OnDestroy {
|
|||||||
update: UpdateService,
|
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('%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 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');
|
console.log('%cIf you know exactly what you are doing, you should work for us', 'font-size: 16px');
|
||||||
this.setLanguage();
|
this.setLanguage();
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<ng-container *ngIf="currentCreateStep == 1">
|
<ng-container *ngIf="currentCreateStep == 1">
|
||||||
<h1>{{'ORG.PAGES.ORGDETAIL_TITLE' | translate}}</h1>
|
<h1>{{'ORG.PAGES.ORGDETAIL_TITLE' | translate}}</h1>
|
||||||
<form [formGroup]="orgForm">
|
<form [formGroup]="orgForm" (ngSubmit)="next()">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<mat-form-field class="formfield">
|
<mat-form-field class="formfield">
|
||||||
<mat-label>{{ 'ORG_DETAIL.DETAIL.NAME' | translate }}</mat-label>
|
<mat-label>{{ 'ORG_DETAIL.DETAIL.NAME' | translate }}</mat-label>
|
||||||
@@ -21,6 +21,11 @@
|
|||||||
<input matInput formControlName="domain" />
|
<input matInput formControlName="domain" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<button [disabled]="orgForm.invalid" color="primary" mat-raised-button class="continue-button"
|
||||||
|
cdkFocusInitial type="submit">
|
||||||
|
{{'CONTINUE' | translate}}
|
||||||
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<!-- <div *ngIf="name?.touched" @openClose>
|
<!-- <div *ngIf="name?.touched" @openClose>
|
||||||
@@ -107,61 +112,66 @@
|
|||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</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">
|
<ng-container *ngIf="usePassword">
|
||||||
<mat-label>{{ 'USER.PASSWORD.NEW' | translate }}</mat-label>
|
<p class="section">{{ 'USER.CREATE.PASSWORDSECTION' | translate }}</p>
|
||||||
<input autocomplete="off" name="firstpassword" matInput formControlName="password"
|
|
||||||
type="password" />
|
|
||||||
|
|
||||||
<mat-error *ngIf="password?.errors?.required">
|
<mat-form-field class="formfield" *ngIf="password">
|
||||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
<mat-label>{{ 'USER.PASSWORD.NEW' | translate }}</mat-label>
|
||||||
</mat-error>
|
<input autocomplete="off" name="firstpassword" matInput formControlName="password"
|
||||||
<mat-error *ngIf="password?.errors?.symbolValidator">
|
type="password" />
|
||||||
{{ 'USER.VALIDATION.SYMBOLERROR' | translate }}
|
|
||||||
</mat-error>
|
<mat-error *ngIf="password?.errors?.required">
|
||||||
<mat-error *ngIf="password?.errors?.numberValidator">
|
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||||
{{ 'USER.VALIDATION.NUMBERERROR' | translate }}
|
</mat-error>
|
||||||
</mat-error>
|
<mat-error *ngIf="password?.errors?.symbolValidator">
|
||||||
<mat-error *ngIf="password?.errors?.upperCaseValidator">
|
{{ 'USER.VALIDATION.SYMBOLERROR' | translate }}
|
||||||
{{ 'USER.VALIDATION.UPPERCASEMISSING' | translate }}
|
</mat-error>
|
||||||
</mat-error>
|
<mat-error *ngIf="password?.errors?.numberValidator">
|
||||||
<mat-error *ngIf="password?.errors?.lowerCaseValidator">
|
{{ 'USER.VALIDATION.NUMBERERROR' | translate }}
|
||||||
{{ 'USER.VALIDATION.LOWERCASEMISSING' | translate }}
|
</mat-error>
|
||||||
</mat-error>
|
<mat-error *ngIf="password?.errors?.upperCaseValidator">
|
||||||
<mat-error *ngIf="password?.errors?.minlength">
|
{{ 'USER.VALIDATION.UPPERCASEMISSING' | translate }}
|
||||||
{{ 'USER.VALIDATION.MINLENGTH' | translate:password?.errors?.minlength }}
|
</mat-error>
|
||||||
</mat-error>
|
<mat-error *ngIf="password?.errors?.lowerCaseValidator">
|
||||||
</mat-form-field>
|
{{ 'USER.VALIDATION.LOWERCASEMISSING' | translate }}
|
||||||
<mat-form-field class="formfield">
|
</mat-error>
|
||||||
<mat-label>{{ 'USER.PASSWORD.CONFIRM' | translate }}</mat-label>
|
<mat-error *ngIf="password?.errors?.minlength">
|
||||||
<input autocomplete="off" name="confirmPassword" matInput formControlName="confirmPassword"
|
{{ 'USER.VALIDATION.MINLENGTH' | translate:password?.errors?.minlength }}
|
||||||
type="password" />
|
</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">
|
<mat-error *ngIf="confirmPassword?.errors?.required">
|
||||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
<mat-error *ngIf="confirmPassword?.errors?.symbolValidator">
|
<mat-error *ngIf="confirmPassword?.errors?.symbolValidator">
|
||||||
{{ 'USER.VALIDATION.SYMBOLERROR' | translate }}
|
{{ 'USER.VALIDATION.SYMBOLERROR' | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
<mat-error *ngIf="confirmPassword?.errors?.numberValidator">
|
<mat-error *ngIf="confirmPassword?.errors?.numberValidator">
|
||||||
{{ 'USER.VALIDATION.NUMBERERROR' | translate }}
|
{{ 'USER.VALIDATION.NUMBERERROR' | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
<mat-error *ngIf="confirmPassword?.errors?.notequal">
|
<mat-error *ngIf="confirmPassword?.errors?.notequal">
|
||||||
{{ 'USER.PASSWORD.NOTEQUAL' | translate }}
|
{{ 'USER.PASSWORD.NOTEQUAL' | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
<mat-error *ngIf="confirmPassword?.errors?.upperCaseValidator">
|
<mat-error *ngIf="confirmPassword?.errors?.upperCaseValidator">
|
||||||
{{ 'USER.VALIDATION.UPPERCASEMISSING' | translate }}
|
{{ 'USER.VALIDATION.UPPERCASEMISSING' | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
<mat-error *ngIf="confirmPassword?.errors?.lowerCaseValidator">
|
<mat-error *ngIf="confirmPassword?.errors?.lowerCaseValidator">
|
||||||
{{ 'USER.VALIDATION.LOWERCASEMISSING' | translate }}
|
{{ 'USER.VALIDATION.LOWERCASEMISSING' | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
<mat-error *ngIf="confirmPassword?.errors?.minlength">
|
<mat-error *ngIf="confirmPassword?.errors?.minlength">
|
||||||
{{ 'USER.VALIDATION.MINLENGTH' | translate:confirmPassword?.errors?.minlength }}
|
{{ 'USER.VALIDATION.MINLENGTH' | translate:confirmPassword?.errors?.minlength }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-container">
|
<div class="btn-container">
|
||||||
<button color="primary" class="continue-button" [disabled]="orgForm.invalid || userForm.invalid"
|
<button color="primary" class="continue-button" [disabled]="orgForm.invalid || userForm.invalid"
|
||||||
@@ -170,11 +180,4 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</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>
|
</div>
|
@@ -140,3 +140,7 @@ h1 {
|
|||||||
border-radius: 0.5rem;
|
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 { CreateOrgRequest, CreateUserRequest, Gender, OrgSetUpResponse } from 'src/app/proto/generated/admin_pb';
|
||||||
import { PasswordComplexityPolicy } from 'src/app/proto/generated/auth_pb';
|
import { PasswordComplexityPolicy } from 'src/app/proto/generated/auth_pb';
|
||||||
import { AdminService } from 'src/app/services/admin.service';
|
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';
|
import { ToastService } from 'src/app/services/toast.service';
|
||||||
|
|
||||||
function passwordConfirmValidator(c: AbstractControl): any {
|
function passwordConfirmValidator(c: AbstractControl): any {
|
||||||
@@ -54,14 +54,14 @@ export class OrgCreateComponent {
|
|||||||
public languages: string[] = ['de', 'en'];
|
public languages: string[] = ['de', 'en'];
|
||||||
|
|
||||||
public policy!: PasswordComplexityPolicy.AsObject;
|
public policy!: PasswordComplexityPolicy.AsObject;
|
||||||
|
public usePassword: boolean = false;
|
||||||
constructor(
|
constructor(
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private toast: ToastService,
|
private toast: ToastService,
|
||||||
private adminService: AdminService,
|
private adminService: AdminService,
|
||||||
private _location: Location,
|
private _location: Location,
|
||||||
private fb: FormBuilder,
|
private fb: FormBuilder,
|
||||||
private authUserService: AuthUserService,
|
private orgService: OrgService,
|
||||||
) {
|
) {
|
||||||
const validators: Validators[] = [];
|
const validators: Validators[] = [];
|
||||||
|
|
||||||
@@ -69,49 +69,8 @@ export class OrgCreateComponent {
|
|||||||
name: ['', [Validators.required]],
|
name: ['', [Validators.required]],
|
||||||
domain: [''],
|
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({
|
this.initForm();
|
||||||
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]],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public createSteps: number = 2;
|
public createSteps: number = 2;
|
||||||
@@ -150,6 +109,66 @@ export class OrgCreateComponent {
|
|||||||
this.currentCreateStep--;
|
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 {
|
public get name(): AbstractControl | null {
|
||||||
return this.orgForm.get('name');
|
return this.orgForm.get('name');
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ import { CommonModule } from '@angular/common';
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
import { MatInputModule } from '@angular/material/input';
|
||||||
@@ -26,6 +27,7 @@ import { OrgCreateComponent } from './org-create.component';
|
|||||||
MatSelectModule,
|
MatSelectModule,
|
||||||
PipesModule,
|
PipesModule,
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
|
MatCheckboxModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class OrgCreateModule { }
|
export class OrgCreateModule { }
|
||||||
|
@@ -58,7 +58,6 @@
|
|||||||
padding: .5rem 0;
|
padding: .5rem 0;
|
||||||
|
|
||||||
.left-desc {
|
.left-desc {
|
||||||
text-transform: uppercase;
|
|
||||||
color: #8795a1;
|
color: #8795a1;
|
||||||
font-size: .9rem;
|
font-size: .9rem;
|
||||||
}
|
}
|
||||||
|
@@ -36,8 +36,7 @@
|
|||||||
</app-card>
|
</app-card>
|
||||||
|
|
||||||
<ng-template appHasRole [appHasRole]="['user.read', 'user.read:'+user?.id]">
|
<ng-template appHasRole [appHasRole]="['user.read', 'user.read:'+user?.id]">
|
||||||
<app-card title="{{ 'USER.PROFILE.TITLE' | translate }}"
|
<app-card title="{{ 'USER.PROFILE.TITLE' | translate }}">
|
||||||
description="{{'USER.PROFILE.DESCRIPTION' | translate}}">
|
|
||||||
<app-detail-form
|
<app-detail-form
|
||||||
*ngIf="((authUserService.isAllowed(['user.write:' + user?.id, 'user.write']) | async) || false) as canwrite"
|
*ngIf="((authUserService.isAllowed(['user.write:' + user?.id, 'user.write']) | async) || false) as canwrite"
|
||||||
[disabled]="canwrite" [genders]="genders" [languages]="languages" [profile]="user"
|
[disabled]="canwrite" [genders]="genders" [languages]="languages" [profile]="user"
|
||||||
|
@@ -43,9 +43,7 @@
|
|||||||
<td mat-cell *matCellDef="let user">
|
<td mat-cell *matCellDef="let user">
|
||||||
<mat-checkbox color="primary" (click)="$event.stopPropagation()"
|
<mat-checkbox color="primary" (click)="$event.stopPropagation()"
|
||||||
(change)="$event ? selection.toggle(user) : null" [checked]="selection.isSelected(user)">
|
(change)="$event ? selection.toggle(user) : null" [checked]="selection.isSelected(user)">
|
||||||
<app-avatar *ngIf="user && (user.displayName || (user.firstName && user.lastName))"
|
<app-avatar *ngIf="user && user.displayName" class="avatar" [name]="user.displayName"
|
||||||
class="avatar"
|
|
||||||
[name]="user.displayName ? user.displayName : (user.firstName + ' '+ user.lastName)"
|
|
||||||
[size]="32">
|
[size]="32">
|
||||||
</app-avatar>
|
</app-avatar>
|
||||||
</mat-checkbox>
|
</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> {
|
public async GetMyOrg(): Promise<Org> {
|
||||||
return await this.request(
|
return await this.request(
|
||||||
c => c.getMyOrg,
|
c => c.getMyOrg,
|
||||||
|
@@ -245,7 +245,8 @@
|
|||||||
"DOWNLOAD_FILE":"Datei download",
|
"DOWNLOAD_FILE":"Datei download",
|
||||||
"SELECTORGTOOLTIP":"Wähle diese Organisation",
|
"SELECTORGTOOLTIP":"Wähle diese Organisation",
|
||||||
"PRIMARYDOMAIN":"Primäre Domain",
|
"PRIMARYDOMAIN":"Primäre Domain",
|
||||||
"STATE":"Status"
|
"STATE":"Status",
|
||||||
|
"USEPASSWORD":"Initiales Password setzen"
|
||||||
},
|
},
|
||||||
"DOMAINS": {
|
"DOMAINS": {
|
||||||
"NEW":"Domain hinzufügen",
|
"NEW":"Domain hinzufügen",
|
||||||
|
@@ -245,7 +245,8 @@
|
|||||||
"DOWNLOAD_FILE":"Download file",
|
"DOWNLOAD_FILE":"Download file",
|
||||||
"SELECTORGTOOLTIP":"Select this organisation",
|
"SELECTORGTOOLTIP":"Select this organisation",
|
||||||
"PRIMARYDOMAIN":"Primary Domain",
|
"PRIMARYDOMAIN":"Primary Domain",
|
||||||
"STATE":"State"
|
"STATE":"State",
|
||||||
|
"USEPASSWORD":"Set initial password"
|
||||||
},
|
},
|
||||||
"DOMAINS": {
|
"DOMAINS": {
|
||||||
"NEW":"Add Domain",
|
"NEW":"Add Domain",
|
||||||
|
Reference in New Issue
Block a user