mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 09:37:45 +00:00
fix(console): move org domains into settings page of the organization (#6612)
* fix: hide domains settings for unauthorized users * refine sidenav object mapping * move domains to settings * change docs * set anchor to list element * remove canwrite check in ngif --------- Co-authored-by: Miguel A. C <doncicuto@gmail.com>
This commit is contained in:
@@ -158,14 +158,6 @@ const routes: Routes = [
|
||||
requiresAll: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'domains',
|
||||
loadChildren: () => import('./pages/domains/domains.module'),
|
||||
canActivate: [AuthGuard, RoleGuard],
|
||||
data: {
|
||||
roles: ['org.read'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'org-settings',
|
||||
loadChildren: () => import('./pages/org-settings/org-settings.module'),
|
||||
|
67
console/src/app/modules/domains/domains.component.html
Normal file
67
console/src/app/modules/domains/domains.component.html
Normal file
@@ -0,0 +1,67 @@
|
||||
<ng-container *ngIf="['org.write$'] | hasRole as canwrite$">
|
||||
<div class="domain-top-view">
|
||||
<div>
|
||||
<div class="domain-title-row">
|
||||
<h2>{{ 'ORG.DOMAINS.TITLE' | translate }}</h2>
|
||||
<a
|
||||
mat-icon-button
|
||||
href="https://zitadel.com/docs/guides/manage/console/organizations#how-zitadel-handles-usernames"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<i class="las la-info-circle"></i>
|
||||
</a>
|
||||
</div>
|
||||
<p class="desc cnsl-secondary-text">{{ 'ORG.DOMAINS.DESCRIPTION' | translate }}</p>
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
|
||||
<button
|
||||
[disabled]="(canwrite$ | async) === false"
|
||||
matTooltip="Add domain"
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
class="cnsl-action-button"
|
||||
(click)="addNewDomain()"
|
||||
>
|
||||
<mat-icon>add</mat-icon>
|
||||
<span>{{ 'ACTIONS.NEW' | translate }}</span>
|
||||
<cnsl-action-keys (actionTriggered)="addNewDomain()"> </cnsl-action-keys>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<cnsl-card *ngFor="let domain of domains" class="domain-card">
|
||||
<div class="domain">
|
||||
<span class="title">{{ domain.domainName }}</span>
|
||||
|
||||
<i matTooltip="verified" *ngIf="domain.isVerified" class="verified las la-check-circle"></i>
|
||||
<i matTooltip="primary" *ngIf="domain.isPrimary" class="primary las la-star"></i>
|
||||
<a
|
||||
*ngIf="domain.isVerified && !domain.isPrimary && (canwrite$ | async)"
|
||||
class="primaryset"
|
||||
(click)="setPrimary(domain)"
|
||||
>{{ 'ORG.DOMAINS.SETPRIMARY' | translate }}</a
|
||||
>
|
||||
|
||||
<span class="fill-space"></span>
|
||||
<button
|
||||
mat-icon-button
|
||||
[disabled]="(canwrite$ | async) === false || domain.isVerified"
|
||||
*ngIf="verifyOrgDomains"
|
||||
(click)="verifyDomain(domain)"
|
||||
>
|
||||
<i class="las la-pen"></i>
|
||||
</button>
|
||||
<button
|
||||
class="domain-rem-button"
|
||||
[disabled]="(canwrite$ | async) === false || domain.isPrimary"
|
||||
matTooltip="Remove domain"
|
||||
color="warn"
|
||||
mat-icon-button
|
||||
(click)="removeDomain(domain.domainName)"
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</cnsl-card>
|
||||
</ng-container>
|
@@ -1,7 +1,6 @@
|
||||
.domain-top-view {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-top: 2rem;
|
||||
|
||||
.domain-title-row {
|
||||
display: flex;
|
@@ -14,13 +14,11 @@ import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.mod
|
||||
|
||||
import { AddDomainDialogModule } from './add-domain-dialog/add-domain-dialog.module';
|
||||
import { DomainVerificationComponent } from './domain-verification/domain-verification.component';
|
||||
import { DomainsRoutingModule } from './domains-routing.module';
|
||||
import { DomainsComponent } from './domains.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [DomainsComponent, DomainVerificationComponent],
|
||||
imports: [
|
||||
DomainsRoutingModule,
|
||||
AddDomainDialogModule,
|
||||
CommonModule,
|
||||
MatIconModule,
|
||||
@@ -36,5 +34,6 @@ import { DomainsComponent } from './domains.component';
|
||||
InfoSectionModule,
|
||||
MatProgressSpinnerModule,
|
||||
],
|
||||
exports: [DomainsComponent],
|
||||
})
|
||||
export default class DomainsModule {}
|
@@ -177,17 +177,6 @@
|
||||
</a>
|
||||
</ng-template>
|
||||
|
||||
<ng-template cnslHasRole [hasRole]="['org.read']">
|
||||
<a
|
||||
class="nav-item"
|
||||
[routerLinkActive]="['active']"
|
||||
[routerLink]="['/domains']"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
>
|
||||
<span class="label">{{ 'MENU.DOMAINS' | translate }}</span>
|
||||
</a>
|
||||
</ng-template>
|
||||
|
||||
<ng-template cnslHasRole [hasRole]="['org.read']">
|
||||
<a
|
||||
class="nav-item"
|
||||
|
@@ -5,7 +5,6 @@
|
||||
<h2>{{ 'POLICY.DOMAIN_POLICY.TITLE' | translate }}</h2>
|
||||
<cnsl-info-section *ngIf="isDefault"> {{ 'POLICY.DEFAULTLABEL' | translate }}</cnsl-info-section>
|
||||
|
||||
<!-- <ng-template cnslHasRole [hasRole]="['domain.policy.delete']"> -->
|
||||
<button
|
||||
*ngIf="serviceType === PolicyComponentServiceType.MGMT && !isDefault"
|
||||
matTooltip="{{ 'POLICY.RESET' | translate }}"
|
||||
@@ -26,7 +25,6 @@
|
||||
>
|
||||
{{ 'POLICY.RESET' | translate }}
|
||||
</button>
|
||||
<!-- </ng-template> -->
|
||||
|
||||
<div class="domain-policy-content" *ngIf="domainData">
|
||||
<div class="row">
|
||||
|
@@ -18,6 +18,9 @@
|
||||
<ng-container *ngIf="currentSetting === 'login'">
|
||||
<cnsl-login-policy [serviceType]="serviceType"></cnsl-login-policy>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="currentSetting === 'verified_domains'">
|
||||
<cnsl-domains></cnsl-domains>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="currentSetting === 'domain' && (['iam.policy.write'] | hasRole | async) === true">
|
||||
<cnsl-domain-policy [serviceType]="serviceType"></cnsl-domain-policy>
|
||||
</ng-container>
|
||||
|
@@ -5,6 +5,7 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
|
||||
|
||||
import { CardModule } from '../card/card.module';
|
||||
import DomainsModule from '../domains/domains.module';
|
||||
import { DomainPolicyModule } from '../policies/domain-policy/domain-policy.module';
|
||||
import { GeneralSettingsModule } from '../policies/general-settings/general-settings.module';
|
||||
import { IdpSettingsModule } from '../policies/idp-settings/idp-settings.module';
|
||||
@@ -40,6 +41,7 @@ import { SettingsListComponent } from './settings-list.component';
|
||||
PrivacyPolicyModule,
|
||||
MessageTextsPolicyModule,
|
||||
SecurityPolicyModule,
|
||||
DomainsModule,
|
||||
LoginTextsPolicyModule,
|
||||
DomainPolicyModule,
|
||||
TranslateModule,
|
||||
|
@@ -43,6 +43,15 @@ export const LOGIN: SidenavSetting = {
|
||||
},
|
||||
};
|
||||
|
||||
export const VERIFIED_DOMAINS: SidenavSetting = {
|
||||
id: 'verified_domains',
|
||||
i18nKey: 'SETTINGS.LIST.VERIFIED_DOMAINS',
|
||||
groupI18nKey: 'SETTINGS.GROUPS.DOMAIN',
|
||||
requiredRoles: {
|
||||
[PolicyComponentServiceType.MGMT]: ['org.read'],
|
||||
},
|
||||
};
|
||||
|
||||
export const DOMAIN: SidenavSetting = {
|
||||
id: 'domain',
|
||||
i18nKey: 'SETTINGS.LIST.DOMAIN',
|
||||
|
@@ -1,17 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { DomainsComponent } from './domains.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: DomainsComponent,
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class DomainsRoutingModule {}
|
@@ -1,69 +0,0 @@
|
||||
<div class="max-width-container">
|
||||
<ng-container *ngIf="['org.write$'] | hasRole as canwrite$">
|
||||
<div class="domain-top-view">
|
||||
<div>
|
||||
<div class="domain-title-row">
|
||||
<h1>{{ 'ORG.DOMAINS.TITLE' | translate }}</h1>
|
||||
<a
|
||||
mat-icon-button
|
||||
href="https://zitadel.com/docs/guides/manage/console/organizations#how-zitadel-handles-usernames"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<i class="las la-info-circle"></i>
|
||||
</a>
|
||||
</div>
|
||||
<p class="desc cnsl-secondary-text">{{ 'ORG.DOMAINS.DESCRIPTION' | translate }}</p>
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
|
||||
<button
|
||||
[disabled]="(canwrite$ | async) === false"
|
||||
matTooltip="Add domain"
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
class="cnsl-action-button"
|
||||
(click)="addNewDomain()"
|
||||
>
|
||||
<mat-icon>add</mat-icon>
|
||||
<span>{{ 'ACTIONS.NEW' | translate }}</span>
|
||||
<cnsl-action-keys (actionTriggered)="addNewDomain()"> </cnsl-action-keys>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<cnsl-card *ngFor="let domain of domains" class="domain-card">
|
||||
<div class="domain">
|
||||
<span class="title">{{ domain.domainName }}</span>
|
||||
|
||||
<i matTooltip="verified" *ngIf="domain.isVerified" class="verified las la-check-circle"></i>
|
||||
<i matTooltip="primary" *ngIf="domain.isPrimary" class="primary las la-star"></i>
|
||||
<a
|
||||
*ngIf="domain.isVerified && !domain.isPrimary && (canwrite$ | async)"
|
||||
class="primaryset"
|
||||
(click)="setPrimary(domain)"
|
||||
>{{ 'ORG.DOMAINS.SETPRIMARY' | translate }}</a
|
||||
>
|
||||
|
||||
<span class="fill-space"></span>
|
||||
<button
|
||||
mat-icon-button
|
||||
[disabled]="(canwrite$ | async) === false || domain.isVerified"
|
||||
*ngIf="(canwrite$ | async) && verifyOrgDomains"
|
||||
(click)="verifyDomain(domain)"
|
||||
>
|
||||
<i class="las la-pen"></i>
|
||||
</button>
|
||||
<button
|
||||
class="domain-rem-button"
|
||||
[disabled]="(canwrite$ | async) === false || domain.isPrimary"
|
||||
matTooltip="Remove domain"
|
||||
color="warn"
|
||||
mat-icon-button
|
||||
(click)="removeDomain(domain.domainName)"
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</cnsl-card>
|
||||
</ng-container>
|
||||
</div>
|
@@ -8,9 +8,11 @@
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
</div>
|
||||
<cnsl-settings-list
|
||||
[selectedId]="id"
|
||||
[serviceType]="PolicyComponentServiceType.ADMIN"
|
||||
[settingsList]="settingsList"
|
||||
></cnsl-settings-list>
|
||||
<ng-container *ngIf="settingsList | async as list">
|
||||
<cnsl-settings-list
|
||||
[selectedId]="id"
|
||||
[serviceType]="PolicyComponentServiceType.ADMIN"
|
||||
[settingsList]="list"
|
||||
></cnsl-settings-list>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, Params } from '@angular/router';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { Observable, of, Subject, takeUntil } from 'rxjs';
|
||||
import { PolicyComponentServiceType } from 'src/app/modules/policies/policy-component-types.enum';
|
||||
import { SidenavSetting } from 'src/app/modules/sidenav/sidenav.component';
|
||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
|
||||
@@ -22,7 +22,6 @@ import {
|
||||
SECRETS,
|
||||
SECURITY,
|
||||
} from '../../modules/settings-list/settings';
|
||||
import { checkSettingsPermissions } from '../org-settings/org-settings.component';
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-instance-settings',
|
||||
@@ -55,7 +54,7 @@ export class InstanceSettingsComponent implements OnInit, OnDestroy {
|
||||
SECURITY,
|
||||
];
|
||||
|
||||
public settingsList: SidenavSetting[] = [];
|
||||
public settingsList: Observable<SidenavSetting[]> = of([]);
|
||||
|
||||
private destroy$: Subject<void> = new Subject();
|
||||
constructor(
|
||||
@@ -81,13 +80,7 @@ export class InstanceSettingsComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
checkSettingsPermissions(this.defaultSettingsList, PolicyComponentServiceType.ADMIN, this.authService).subscribe(
|
||||
(allowed) => {
|
||||
this.settingsList = this.defaultSettingsList.filter((setting, index) => {
|
||||
return allowed[index];
|
||||
});
|
||||
},
|
||||
);
|
||||
this.settingsList = this.authService.isAllowedMapper(this.defaultSettingsList, (setting) => setting.requiredRoles.admin);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
|
@@ -8,9 +8,11 @@
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
</div>
|
||||
<cnsl-settings-list
|
||||
[selectedId]="id"
|
||||
[serviceType]="PolicyComponentServiceType.MGMT"
|
||||
[settingsList]="settingsList"
|
||||
></cnsl-settings-list>
|
||||
<ng-container *ngIf="settingsList | async as list">
|
||||
<cnsl-settings-list
|
||||
[selectedId]="id"
|
||||
[serviceType]="PolicyComponentServiceType.MGMT"
|
||||
[settingsList]="list"
|
||||
></cnsl-settings-list>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, Params } from '@angular/router';
|
||||
import { forkJoin, of, take } from 'rxjs';
|
||||
import { Observable, of, take } from 'rxjs';
|
||||
import { PolicyComponentServiceType } from 'src/app/modules/policies/policy-component-types.enum';
|
||||
import { SidenavSetting } from 'src/app/modules/sidenav/sidenav.component';
|
||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
MESSAGETEXTS,
|
||||
NOTIFICATION_POLICY,
|
||||
PRIVACYPOLICY,
|
||||
VERIFIED_DOMAINS,
|
||||
} from '../../modules/settings-list/settings';
|
||||
|
||||
@Component({
|
||||
@@ -34,6 +35,7 @@ export class OrgSettingsComponent implements OnInit {
|
||||
COMPLEXITY,
|
||||
LOCKOUT,
|
||||
NOTIFICATION_POLICY,
|
||||
VERIFIED_DOMAINS,
|
||||
DOMAIN,
|
||||
BRANDING,
|
||||
MESSAGETEXTS,
|
||||
@@ -41,7 +43,7 @@ export class OrgSettingsComponent implements OnInit {
|
||||
PRIVACYPOLICY,
|
||||
];
|
||||
|
||||
public settingsList: SidenavSetting[] = [];
|
||||
public settingsList: Observable<Array<SidenavSetting>> = of([]);
|
||||
|
||||
constructor(
|
||||
breadcrumbService: BreadcrumbService,
|
||||
@@ -65,40 +67,8 @@ export class OrgSettingsComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
checkSettingsPermissions(this.defaultSettingsList, PolicyComponentServiceType.MGMT, this.authService).subscribe(
|
||||
(allowed) => {
|
||||
this.settingsList = this.defaultSettingsList.filter((setting, index) => {
|
||||
return allowed[index];
|
||||
});
|
||||
},
|
||||
);
|
||||
this.settingsList = this.authService
|
||||
.isAllowedMapper(this.defaultSettingsList, (setting) => setting.requiredRoles.mgmt)
|
||||
.pipe(take(1));
|
||||
}
|
||||
}
|
||||
|
||||
// Return a Observables<boolean>[] that will wait till all service calls are finished to then check if user is allowed to see a setting
|
||||
export function checkSettingsPermissions(settings: SidenavSetting[], serviceType: string, authService: GrpcAuthService) {
|
||||
return forkJoin(
|
||||
settings
|
||||
.filter((setting) => {
|
||||
if (serviceType === PolicyComponentServiceType.ADMIN) {
|
||||
return setting.requiredRoles && setting.requiredRoles.admin;
|
||||
} else {
|
||||
return setting.requiredRoles && setting.requiredRoles.mgmt;
|
||||
}
|
||||
})
|
||||
.map((setting) => {
|
||||
if (!setting.requiredRoles) {
|
||||
return of(true);
|
||||
}
|
||||
|
||||
if (!setting.requiredRoles.mgmt) {
|
||||
return of(true);
|
||||
}
|
||||
|
||||
if (setting.requiredRoles.mgmt) {
|
||||
return authService.isAllowed(setting.requiredRoles.mgmt).pipe(take(1));
|
||||
}
|
||||
return of(false);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@@ -309,10 +309,7 @@ export class GrpcAuthService {
|
||||
filter(([hL, p]) => {
|
||||
return hL === true && !!p.length;
|
||||
}),
|
||||
map(([_, zroles]) => {
|
||||
const what = this.hasRoles(zroles, roles, requiresAll);
|
||||
return what;
|
||||
}),
|
||||
map(([_, zroles]) => this.hasRoles(zroles, roles, requiresAll)),
|
||||
distinctUntilChanged(),
|
||||
);
|
||||
} else {
|
||||
@@ -320,6 +317,31 @@ export class GrpcAuthService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* filters objects based on roles
|
||||
* @param objects array of objects
|
||||
* @param mapper mapping function which maps to a string[] or Regexp[] of roles
|
||||
* @param requiresAll wheter all, or just a single roles is required to fulfill
|
||||
*/
|
||||
public isAllowedMapper<T>(
|
||||
objects: T[],
|
||||
mapper: (attr: any) => string[] | RegExp[],
|
||||
requiresAll: boolean = false,
|
||||
): Observable<T[]> {
|
||||
return this.fetchedZitadelPermissions.pipe(
|
||||
withLatestFrom(this.zitadelPermissions),
|
||||
filter(([hL, p]) => {
|
||||
return hL === true && !!p.length;
|
||||
}),
|
||||
map(([_, zroles]) => {
|
||||
return objects.filter((obj) => {
|
||||
const roles = mapper(obj);
|
||||
return this.hasRoles(zroles, roles, requiresAll);
|
||||
});
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if user has one of the provided roles
|
||||
* @param userRoles roles of the user
|
||||
|
@@ -95,7 +95,6 @@
|
||||
"EVENTS": "Събития",
|
||||
"FAILEDEVENTS": "Неуспешни събития",
|
||||
"ORGANIZATION": "Организация",
|
||||
"DOMAINS": "Домейни",
|
||||
"PROJECT": "Проекти",
|
||||
"PROJECTOVERVIEW": "Преглед",
|
||||
"PROJECTGRANTS": "Грантове",
|
||||
@@ -947,7 +946,7 @@
|
||||
},
|
||||
"DOMAINS": {
|
||||
"NEW": "Добавете домейн",
|
||||
"TITLE": "Домейни",
|
||||
"TITLE": "Проверени домейни",
|
||||
"DESCRIPTION": "Конфигурирайте вашите домейни. ",
|
||||
"SETPRIMARY": "Задайте като основен",
|
||||
"DELETE": {
|
||||
@@ -1017,6 +1016,7 @@
|
||||
"NOTIFICATIONS_DESC": "Настройки за SMTP и SMS",
|
||||
"MESSAGETEXTS": "Текстове на съобщения",
|
||||
"IDP": "Доставчици на идентичност",
|
||||
"VERIFIED_DOMAINS": "Проверени домейни",
|
||||
"DOMAIN": "Настройки на домейна",
|
||||
"LOGINTEXTS": "Текстове на интерфейса за влизане",
|
||||
"BRANDING": "Брандиране",
|
||||
|
@@ -95,7 +95,6 @@
|
||||
"EVENTS": "Events",
|
||||
"FAILEDEVENTS": "Fehlerhafte Events",
|
||||
"ORGANIZATION": "Organisation",
|
||||
"DOMAINS": "Domänen",
|
||||
"PROJECT": "Projekte",
|
||||
"PROJECTOVERVIEW": "Übersicht",
|
||||
"PROJECTGRANTS": "Berechtigte Organisationen",
|
||||
@@ -953,7 +952,7 @@
|
||||
},
|
||||
"DOMAINS": {
|
||||
"NEW": "Domain hinzufügen",
|
||||
"TITLE": "Domänen",
|
||||
"TITLE": "Verifizierte Domains",
|
||||
"DESCRIPTION": "Konfiguriere die Domains, die für Domain discovery und als Suffix für die Benutzer verwendet werden können.",
|
||||
"SETPRIMARY": "Primäre Domain setzen",
|
||||
"DELETE": {
|
||||
@@ -1023,6 +1022,7 @@
|
||||
"NOTIFICATIONS_DESC": "SMTP und SMS Einstellungen",
|
||||
"MESSAGETEXTS": "Benachrichtigungstexte",
|
||||
"IDP": "Identitätsanbieter",
|
||||
"VERIFIED_DOMAINS": "Verifizierte Domains",
|
||||
"DOMAIN": "Domain Einstellungen",
|
||||
"LOGINTEXTS": "Login Interface Texte",
|
||||
"BRANDING": "Branding",
|
||||
|
@@ -95,7 +95,6 @@
|
||||
"EVENTS": "Events",
|
||||
"FAILEDEVENTS": "Failed Events",
|
||||
"ORGANIZATION": "Organization",
|
||||
"DOMAINS": "Domains",
|
||||
"PROJECT": "Projects",
|
||||
"PROJECTOVERVIEW": "Overview",
|
||||
"PROJECTGRANTS": "Grants",
|
||||
@@ -954,7 +953,7 @@
|
||||
},
|
||||
"DOMAINS": {
|
||||
"NEW": "Add Domain",
|
||||
"TITLE": "Domains",
|
||||
"TITLE": "Verified domains",
|
||||
"DESCRIPTION": "Configure your organization domains. This domain can be used for domain discovery and username suffixing.",
|
||||
"SETPRIMARY": "Set as Primary",
|
||||
"DELETE": {
|
||||
@@ -1024,6 +1023,7 @@
|
||||
"NOTIFICATIONS_DESC": "SMTP and SMS Settings",
|
||||
"MESSAGETEXTS": "Message Texts",
|
||||
"IDP": "Identity Providers",
|
||||
"VERIFIED_DOMAINS": "Verified domains",
|
||||
"DOMAIN": "Domain settings",
|
||||
"LOGINTEXTS": "Login Interface Texts",
|
||||
"BRANDING": "Branding",
|
||||
|
@@ -95,7 +95,6 @@
|
||||
"EVENTS": "Eventos",
|
||||
"FAILEDEVENTS": "Eventos fallidos",
|
||||
"ORGANIZATION": "Organización",
|
||||
"DOMAINS": "Dominios",
|
||||
"PROJECT": "Proyectos",
|
||||
"PROJECTOVERVIEW": "Resumen",
|
||||
"PROJECTGRANTS": "Concesiones",
|
||||
@@ -954,7 +953,7 @@
|
||||
},
|
||||
"DOMAINS": {
|
||||
"NEW": "Añadir dominio",
|
||||
"TITLE": "Dominios",
|
||||
"TITLE": "Dominios verificados",
|
||||
"DESCRIPTION": "Configura tus dominios. Este dominio puede usarse para iniciar sesión con tus usuarios.",
|
||||
"SETPRIMARY": "Establecer como primario",
|
||||
"DELETE": {
|
||||
@@ -1024,6 +1023,7 @@
|
||||
"NOTIFICATIONS_DESC": "Ajustes SMTP y SMS",
|
||||
"MESSAGETEXTS": "Mensajes de texto",
|
||||
"IDP": "Proveedores de identidad",
|
||||
"VERIFIED_DOMAINS": "Dominios verificados",
|
||||
"DOMAIN": "Ajustes de dominio",
|
||||
"LOGINTEXTS": "Textos de interfaz de inicio de sesión",
|
||||
"BRANDING": "Imagen de marca",
|
||||
|
@@ -95,7 +95,6 @@
|
||||
"EVENTS": "Événements",
|
||||
"FAILEDEVENTS": "Événements échoués",
|
||||
"ORGANIZATION": "Organisation",
|
||||
"DOMAINS": "Domaines",
|
||||
"PROJECT": "Projets",
|
||||
"PROJECTOVERVIEW": "Vue d'ensemble",
|
||||
"PROJECTGRANTS": "Subventions",
|
||||
@@ -953,7 +952,7 @@
|
||||
},
|
||||
"DOMAINS": {
|
||||
"NEW": "Ajouter un domaine",
|
||||
"TITLE": "Domaines",
|
||||
"TITLE": "Domaines vérifiés",
|
||||
"DESCRIPTION": "Configurez vos domaines. Ce domaine peut être utilisé pour se connecter avec vos utilisateurs.",
|
||||
"SETPRIMARY": "Définir comme primaire",
|
||||
"DELETE": {
|
||||
@@ -1023,6 +1022,7 @@
|
||||
"NOTIFICATIONS_DESC": "Paramètres SMTP et SMS",
|
||||
"MESSAGETEXTS": "Textes des messages",
|
||||
"IDP": "Fournisseurs d'identité",
|
||||
"VERIFIED_DAMAINS": "Domaines vérifiés",
|
||||
"DOMAIN": "Paramètres du domaine",
|
||||
"LOGINTEXTS": "Textes de l'interface de connexion",
|
||||
"BRANDING": "Image de marque",
|
||||
|
@@ -95,7 +95,6 @@
|
||||
"EVENTS": "Eventi",
|
||||
"FAILEDEVENTS": "Eventi falliti",
|
||||
"ORGANIZATION": "Organizzazione",
|
||||
"DOMAINS": "Domini",
|
||||
"PROJECT": "Progetti",
|
||||
"PROJECTOVERVIEW": "Progetto",
|
||||
"PROJECTGRANTS": "Organizzazioni ammissibili",
|
||||
@@ -953,7 +952,7 @@
|
||||
},
|
||||
"DOMAINS": {
|
||||
"NEW": "Aggiungi dominio",
|
||||
"TITLE": "Domini",
|
||||
"TITLE": "Domini verificati",
|
||||
"DESCRIPTION": "Configura i tuoi domini. Questo dominio pu\u00f2 essere utilizzato per accedere con i tuoi utenti.",
|
||||
"SETPRIMARY": "Impostato come primario",
|
||||
"DELETE": {
|
||||
@@ -1023,6 +1022,7 @@
|
||||
"NOTIFICATIONS_DESC": "Impostazioni SMTP e SMS",
|
||||
"MESSAGETEXTS": "Testi di notifica",
|
||||
"IDP": "Fornitori di identità",
|
||||
"VERIFIED_DAMAINS": "Domini verificati",
|
||||
"DOMAIN": "Impostazioni del dominio",
|
||||
"LOGINTEXTS": "Testi dell'interfaccia login",
|
||||
"BRANDING": "Branding",
|
||||
|
@@ -95,7 +95,6 @@
|
||||
"EVENTS": "イベント",
|
||||
"FAILEDEVENTS": "失敗したイベント",
|
||||
"ORGANIZATION": "組織",
|
||||
"DOMAINS": "ドメイン",
|
||||
"PROJECT": "プロジェクト",
|
||||
"PROJECTOVERVIEW": "概要",
|
||||
"PROJECTGRANTS": "グラント",
|
||||
@@ -954,7 +953,7 @@
|
||||
},
|
||||
"DOMAINS": {
|
||||
"NEW": "ドメインを追加する",
|
||||
"TITLE": "ドメイン",
|
||||
"TITLE": "検証済みドメイン",
|
||||
"DESCRIPTION": "ドメインを設定します。このドメインは、ユーザーのログインで使用できます。",
|
||||
"SETPRIMARY": "プライマリとして設定する",
|
||||
"DELETE": {
|
||||
@@ -1024,6 +1023,7 @@
|
||||
"NOTIFICATIONS_DESC": "SMTPおよびSMS設定",
|
||||
"MESSAGETEXTS": "メッセージテキスト",
|
||||
"IDP": "IDプロバイダー",
|
||||
"VERIFIED_DAMAINS": "検証済みドメイン",
|
||||
"DOMAIN": "ドメイン設定",
|
||||
"LOGINTEXTS": "ログイン画面のテキスト",
|
||||
"BRANDING": "ブランディング",
|
||||
|
@@ -95,7 +95,6 @@
|
||||
"EVENTS": "Настани",
|
||||
"FAILEDEVENTS": "Неуспешни настани",
|
||||
"ORGANIZATION": "Организација",
|
||||
"DOMAINS": "Домени",
|
||||
"PROJECT": "Проекти",
|
||||
"PROJECTOVERVIEW": "Преглед",
|
||||
"PROJECTGRANTS": "Овластувања",
|
||||
@@ -954,7 +953,7 @@
|
||||
},
|
||||
"DOMAINS": {
|
||||
"NEW": "Додади домен",
|
||||
"TITLE": "Домени",
|
||||
"TITLE": "Потврдени домени",
|
||||
"DESCRIPTION": "Конфигурирајте ги вашите домени. Овој домен може да се користи за најава на вашите корисници.",
|
||||
"SETPRIMARY": "Постави како основен",
|
||||
"DELETE": {
|
||||
@@ -1025,6 +1024,7 @@
|
||||
"NOTIFICATIONS_DESC": "Подесувања за SMTP и SMS",
|
||||
"MESSAGETEXTS": "Текстови на пораки",
|
||||
"IDP": "Identity Providers",
|
||||
"VERIFIED_DAMAINS": "Потврдени домени",
|
||||
"DOMAIN": "Подесувања за домен",
|
||||
"LOGINTEXTS": "Текстови на интерфејс за најава",
|
||||
"BRANDING": "Брендирање",
|
||||
|
@@ -95,7 +95,6 @@
|
||||
"EVENTS": "Zdarzenia",
|
||||
"FAILEDEVENTS": "Nieudane Zdarzenia",
|
||||
"ORGANIZATION": "Organizacja",
|
||||
"DOMAINS": "Domeny",
|
||||
"PROJECT": "Projekty",
|
||||
"PROJECTOVERVIEW": "Przegląd",
|
||||
"PROJECTGRANTS": "Uprawnienia",
|
||||
@@ -953,7 +952,7 @@
|
||||
},
|
||||
"DOMAINS": {
|
||||
"NEW": "Dodaj domenę",
|
||||
"TITLE": "Domeny",
|
||||
"TITLE": "Zweryfikowane domeny",
|
||||
"DESCRIPTION": "Skonfiguruj swoje domeny. Ta domena może być używana do logowania się z Twoimi użytkownikami.",
|
||||
"SETPRIMARY": "Ustaw jako główną",
|
||||
"DELETE": {
|
||||
@@ -1023,6 +1022,7 @@
|
||||
"NOTIFICATIONS_DESC": "Ustawienia SMTP i SMS",
|
||||
"MESSAGETEXTS": "Teksty wiadomości",
|
||||
"IDP": "Dostawcy tożsamości",
|
||||
"VERIFIED_DAMAINS": "Zweryfikowane domeny",
|
||||
"DOMAIN": "Ustawienia domeny",
|
||||
"LOGINTEXTS": "Teksty interfejsu logowania",
|
||||
"BRANDING": "Marka",
|
||||
|
@@ -95,7 +95,6 @@
|
||||
"EVENTS": "Eventos",
|
||||
"FAILEDEVENTS": "Eventos com Falha",
|
||||
"ORGANIZATION": "Organização",
|
||||
"DOMAINS": "Domínios",
|
||||
"PROJECT": "Projetos",
|
||||
"PROJECTOVERVIEW": "Visão Geral",
|
||||
"PROJECTGRANTS": "Autorizações",
|
||||
@@ -954,7 +953,7 @@
|
||||
},
|
||||
"DOMAINS": {
|
||||
"NEW": "Adicionar Domínio",
|
||||
"TITLE": "Domínios",
|
||||
"TITLE": "Domínios verificados",
|
||||
"DESCRIPTION": "Configure seus domínios. Este domínio pode ser usado para o login dos seus usuários.",
|
||||
"SETPRIMARY": "Definir como Principal",
|
||||
"DELETE": {
|
||||
@@ -1025,6 +1024,7 @@
|
||||
"NOTIFICATIONS_DESC": "Configurações de SMTP e SMS",
|
||||
"MESSAGETEXTS": "Textos de Mensagem",
|
||||
"IDP": "Provedores de Identidade",
|
||||
"VERIFIED_DAMAINS": "Domínios verificados",
|
||||
"DOMAIN": "Configurações de Domínio",
|
||||
"LOGINTEXTS": "Textos da Interface de Login",
|
||||
"BRANDING": "Marca",
|
||||
|
@@ -95,7 +95,6 @@
|
||||
"EVENTS": "活动",
|
||||
"FAILEDEVENTS": "失败事件",
|
||||
"ORGANIZATION": "组织",
|
||||
"DOMAINS": "域名",
|
||||
"PROJECT": "项目",
|
||||
"PROJECTOVERVIEW": "概览",
|
||||
"PROJECTGRANTS": "授予",
|
||||
@@ -953,7 +952,7 @@
|
||||
},
|
||||
"DOMAINS": {
|
||||
"NEW": "添加域名",
|
||||
"TITLE": "域名",
|
||||
"TITLE": "已验证的域名",
|
||||
"DESCRIPTION": "配置您的域名。此域名可用于您的用户登录。",
|
||||
"SETPRIMARY": "设置为主域名",
|
||||
"DELETE": {
|
||||
@@ -1023,6 +1022,7 @@
|
||||
"NOTIFICATIONS_DESC": "SMTP 和 SMS 设置",
|
||||
"MESSAGETEXTS": "消息文本",
|
||||
"IDP": "身份提供者",
|
||||
"VERIFIED_DAMAINS": "已验证的域名",
|
||||
"DOMAIN": "域名设置",
|
||||
"LOGINTEXTS": "登录界面文本",
|
||||
"BRANDING": "品牌标识",
|
||||
|
Reference in New Issue
Block a user