fix(console, login): console - ensure permission is available, login - i18n fixes, input borders, lgn-touched script to add class on blur (#3760)

* permission restriction, member, login i18n input borders, secondary text

* add touched js
This commit is contained in:
Max Peintner 2022-06-07 11:25:56 +02:00 committed by GitHub
parent c1f59c7950
commit 233d80502d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 333 additions and 71 deletions

View File

@ -150,7 +150,8 @@ const routes: Routes = [
loadChildren: () => import('./pages/instance-settings/instance-settings.module').then((m) => m.InstanceSettingsModule),
canActivate: [AuthGuard, RoleGuard],
data: {
roles: ['iam.read', 'iam.write'],
roles: ['iam.read', 'iam.policy.read'],
requiresAll: true,
},
},
{
@ -166,7 +167,7 @@ const routes: Routes = [
loadChildren: () => import('./pages/org-settings/org-settings.module').then((m) => m.OrgSettingsModule),
canActivate: [AuthGuard, RoleGuard],
data: {
roles: ['org.read', 'org.write'],
roles: ['policy.read'],
},
},
{

View File

@ -6,20 +6,14 @@ import { filter, switchMap } from 'rxjs/operators';
import { GrpcAuthService } from '../services/grpc-auth.service';
@Injectable({
providedIn: 'root',
providedIn: 'root',
})
export class RoleGuard implements CanActivate {
constructor(private authService: GrpcAuthService) {}
constructor(private authService: GrpcAuthService) { }
public canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
): Observable<boolean> {
return this.authService.fetchedZitadelPermissions.pipe(
filter((permissionsFetched) => !!permissionsFetched),
).pipe(
switchMap(_ => this.authService.isAllowed(route.data['roles'])),
);
}
public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.authService.fetchedZitadelPermissions
.pipe(filter((permissionsFetched) => !!permissionsFetched))
.pipe(switchMap((_) => this.authService.isAllowed(route.data['roles'], route.data['requiresAll'])));
}
}

View File

@ -30,6 +30,10 @@
margin-bottom: 0.5rem;
box-sizing: border-box;
@media only screen and (max-width: 500px) {
border-bottom: none;
}
.date {
font-weight: 500;
font-size: 0.8rem;

View File

@ -216,7 +216,16 @@
<button
actions
[disabled]="
serviceType === PolicyComponentServiceType.MGMT && idp?.providerType === IDPOwnerType.IDP_OWNER_TYPE_ORG
(serviceType === PolicyComponentServiceType.MGMT && idp?.providerType === IDPOwnerType.IDP_OWNER_TYPE_ORG) ||
([
serviceType === PolicyComponentServiceType.ADMIN
? 'iam.idp.write'
: serviceType === PolicyComponentServiceType.MGMT
? 'org.idp.write'
: ''
]
| hasRole
| async) === false
"
mat-icon-button
color="warn"

View File

@ -92,6 +92,7 @@
color="warn"
(click)="$event.stopPropagation(); triggerDeleteMember(member)"
mat-icon-button
[disabled]="canDelete === false"
>
<i class="las la-trash"></i>
</button>
@ -110,13 +111,13 @@
<mat-chip
class="cnsl-chip"
*ngFor="let role of member.rolesList"
[removable]="true"
[removable]="canWrite"
[selectable]="false"
(removed)="removeRole(member, role)"
>
<div class="cnsl-chip-dot" [style.background]="getColor(role)"></div>
<span>{{ role | roletransform }}</span>
<button matChipRemove>
<button *ngIf="canWrite" matChipRemove>
<mat-icon>cancel</mat-icon>
</button>
</mat-chip>
@ -126,8 +127,9 @@
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr
class="highlight pointer"
(click)="addRole(member)"
class="highlight"
[ngClass]="{ pointer: canWrite }"
(click)="canWrite ? addRole(member) : null"
mat-row
*matRowDef="let member; columns: displayedColumns"
></tr>

View File

@ -64,6 +64,7 @@
[routerLinkActiveOptions]="{ exact: false }"
[routerLinkActive]="['active']"
[routerLink]="['/settings']"
*ngIf="['iam.read', 'iam.policy.read'] | hasRole: true | async"
>
<div class="c_label">
<span> {{ 'MENU.SETTINGS' | translate }} </span>
@ -169,6 +170,7 @@
[routerLinkActive]="['active']"
[routerLinkActiveOptions]="{ exact: false }"
[routerLink]="['/org-settings']"
*ngIf="['policy.read'] | hasRole | async"
>
<span class="label">{{ 'MENU.SETTINGS' | translate }}</span>
</a>

View File

@ -37,12 +37,24 @@
<input id="smtp-user" cnslInput name="smtp-user" autocomplete="smtp-user" formControlName="user" />
</cnsl-form-field>
<button class="set-password-btn" (click)="setSMTPPassword()" mat-stroked-button>
<button
class="set-password-btn"
[disabled]="(['iam.write'] | hasRole | async) === false"
(click)="setSMTPPassword()"
mat-stroked-button
>
{{ 'SETTING.SMTP.SETPASSWORD' | translate }}
</button>
<div class="general-btn-container">
<button class="save-button" (click)="savePolicy()" color="primary" type="submit" mat-raised-button>
<button
class="save-button"
[disabled]="form.disabled"
(click)="savePolicy()"
color="primary"
type="submit"
mat-raised-button
>
{{ 'ACTIONS.SAVE' | translate }}
</button>
</div>
@ -65,13 +77,9 @@
></span>
<span class="fill-space"></span>
<button mat-icon-button (click)="addSMSProvider()"><i class="las la-pen"></i></button>
<button [disabled]="(['iam.write'] | hasRole | async) === false" mat-icon-button (click)="addSMSProvider()">
<i class="las la-pen"></i>
</button>
</div>
</cnsl-card>
<!-- <button mat-stroked-button (click)="addSMSProvider()">
<div class="sms-card add">
<mat-icon>add</mat-icon>
<span>{{ 'ACTIONS.ADD' | translate }}</span>
</div>
</button> -->
</div>

View File

@ -1,6 +1,7 @@
import { Component, Input, OnInit } from '@angular/core';
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { take } from 'rxjs';
import {
AddSMSProviderTwilioRequest,
UpdateSMTPConfigPasswordRequest,
@ -9,6 +10,7 @@ import {
} from 'src/app/proto/generated/zitadel/admin_pb';
import { DebugNotificationProvider, SMSProvider, SMSProviderConfigState } from 'src/app/proto/generated/zitadel/settings_pb';
import { AdminService } from 'src/app/services/admin.service';
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
import { ToastService } from 'src/app/services/toast.service';
import { InfoSectionType } from '../../info-section/info-section.component';
@ -44,18 +46,27 @@ export class NotificationSettingsComponent implements OnInit {
private dialog: MatDialog,
private toast: ToastService,
private fb: FormBuilder,
private authService: GrpcAuthService,
) {
this.form = this.fb.group({
senderAddress: ['', [Validators.required]],
senderName: ['', [Validators.required]],
tls: [true, [Validators.required]],
host: ['', [Validators.required]],
user: ['', [Validators.required]],
senderAddress: [{ disabled: true, value: '' }, [Validators.required]],
senderName: [{ disabled: true, value: '' }, [Validators.required]],
tls: [{ disabled: true, value: true }, [Validators.required]],
host: [{ disabled: true, value: '' }, [Validators.required]],
user: [{ disabled: true, value: '' }, [Validators.required]],
});
}
ngOnInit(): void {
this.fetchData();
this.authService
.isAllowed(['iam.write'])
.pipe(take(1))
.subscribe((allowed) => {
if (allowed) {
this.form.enable();
}
});
}
private fetchData(): void {

View File

@ -7,6 +7,7 @@ import { MatIconModule } from '@angular/material/icon';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatSelectModule } from '@angular/material/select';
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 { FormFieldModule } from '../../form-field/form-field.module';
@ -24,6 +25,7 @@ import { SMTPPasswordDialogComponent } from './smtp-password-dialog/smtp-passwor
InfoSectionModule,
FormsModule,
ReactiveFormsModule,
HasRolePipeModule,
MatButtonModule,
MatCheckboxModule,
InputModule,

View File

@ -39,7 +39,14 @@
</cnsl-form-field>
</form>
<div class="oidc-btn-container">
<button class="save-button" (click)="savePolicy()" color="primary" type="submit" mat-raised-button>
<button
[disabled]="form.disabled"
class="save-button"
(click)="savePolicy()"
color="primary"
type="submit"
mat-raised-button
>
{{ 'ACTIONS.SAVE' | translate }}
</button>
</div>

View File

@ -1,9 +1,11 @@
import { Component, OnInit } from '@angular/core';
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Duration } from 'google-protobuf/google/protobuf/duration_pb';
import { take } from 'rxjs';
import { SetDefaultLanguageResponse, UpdateOIDCSettingsRequest } from 'src/app/proto/generated/zitadel/admin_pb';
import { OIDCSettings } from 'src/app/proto/generated/zitadel/settings_pb';
import { AdminService } from 'src/app/services/admin.service';
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
import { ToastService } from 'src/app/services/toast.service';
@Component({
@ -16,17 +18,30 @@ export class OIDCConfigurationComponent implements OnInit {
public loading: boolean = false;
public form!: FormGroup;
constructor(private service: AdminService, private fb: FormBuilder, private toast: ToastService) {
constructor(
private service: AdminService,
private fb: FormBuilder,
private toast: ToastService,
private authService: GrpcAuthService,
) {
this.form = this.fb.group({
accessTokenLifetime: [12, [Validators.required]],
idTokenLifetime: [12, [Validators.required]],
refreshTokenExpiration: [30, [Validators.required]],
refreshTokenIdleExpiration: [90, [Validators.required]],
accessTokenLifetime: [{ disabled: true, value: 12 }, [Validators.required]],
idTokenLifetime: [{ disabled: true, value: 12 }, [Validators.required]],
refreshTokenExpiration: [{ disabled: true, value: 30 }, [Validators.required]],
refreshTokenIdleExpiration: [{ disabled: true, value: 90 }, [Validators.required]],
});
}
ngOnInit(): void {
this.fetchData();
this.authService
.isAllowed(['iam.write'])
.pipe(take(1))
.subscribe((allowed) => {
if (allowed) {
this.form.enable();
}
});
}
private fetchData(): void {

View File

@ -57,6 +57,18 @@
*ngIf="serviceType === PolicyComponentServiceType.MGMT && !isDefault"
matTooltip="{{ 'POLICY.RESET' | translate }}"
color="warn"
[disabled]="
view === View.CURRENT ||
([
serviceType === PolicyComponentServiceType.ADMIN
? 'iam.policy.delete'
: serviceType === PolicyComponentServiceType.MGMT
? 'policy.delete'
: ''
]
| hasRole
| async) === false
"
(click)="removePolicy()"
mat-stroked-button
>
@ -136,7 +148,18 @@
mat-icon-button
color="warn"
(click)="deleteAsset(AssetType.LOGO, theme)"
[disabled]="view === View.CURRENT"
[disabled]="
view === View.CURRENT ||
([
serviceType === PolicyComponentServiceType.ADMIN
? 'iam.policy.write'
: serviceType === PolicyComponentServiceType.MGMT
? 'policy.write'
: ''
]
| hasRole
| async) === false
"
matTooltip="{{ 'ACTIONS.DELETE' | translate }}"
>
<i class="las la-ban"></i>
@ -151,9 +174,22 @@
(change)="onDropLogo(theme, $any($event.target).files)"
/>
<button
class="asset-add-btn"
mat-icon-button
matTooltip="{{ 'POLICY.PRIVATELABELING.BTN' | translate }}"
*ngIf="view !== View.CURRENT"
[disabled]="
view === View.CURRENT ||
([
serviceType === PolicyComponentServiceType.ADMIN
? 'iam.policy.write'
: serviceType === PolicyComponentServiceType.MGMT
? 'policy.write'
: ''
]
| hasRole
| async) === false
"
(click)="$event.preventDefault(); selectedFile.click()"
>
<mat-icon>add</mat-icon>
@ -183,7 +219,18 @@
mat-icon-button
color="warn"
(click)="deleteAsset(AssetType.ICON, theme)"
[disabled]="view === View.CURRENT"
[disabled]="
view === View.CURRENT ||
([
serviceType === PolicyComponentServiceType.ADMIN
? 'iam.policy.write'
: serviceType === PolicyComponentServiceType.MGMT
? 'policy.write'
: ''
]
| hasRole
| async) === false
"
matTooltip="{{ 'ACTIONS.DELETE' | translate }}"
>
<i class="las la-ban"></i>
@ -199,8 +246,21 @@
/>
<button
mat-icon-button
class="asset-add-btn"
matTooltip="{{ 'POLICY.PRIVATELABELING.BTN' | translate }}"
*ngIf="view !== View.CURRENT"
[disabled]="
view === View.CURRENT ||
([
serviceType === PolicyComponentServiceType.ADMIN
? 'iam.policy.write'
: serviceType === PolicyComponentServiceType.MGMT
? 'policy.write'
: ''
]
| hasRole
| async) === false
"
(click)="$event.preventDefault(); selectedIconFile.click()"
>
<mat-icon>add</mat-icon>
@ -232,7 +292,18 @@
<div class="colors" *ngIf="data && previewData">
<div class="color">
<cnsl-color
[disabled]="view === View.CURRENT"
[disabled]="
view === View.CURRENT ||
([
serviceType === PolicyComponentServiceType.ADMIN
? 'iam.policy.write'
: serviceType === PolicyComponentServiceType.MGMT
? 'policy.write'
: ''
]
| hasRole
| async) === false
"
[colorType]="ColorType.BACKGROUNDDARK"
(previewChanged)="previewData.backgroundColorDark !== $event ? setDarkBackgroundColorAndSave($event) : null"
name="Background Color"
@ -243,7 +314,18 @@
<div class="color">
<cnsl-color
[disabled]="view === View.CURRENT"
[disabled]="
view === View.CURRENT ||
([
serviceType === PolicyComponentServiceType.ADMIN
? 'iam.policy.write'
: serviceType === PolicyComponentServiceType.MGMT
? 'policy.write'
: ''
]
| hasRole
| async) === false
"
[colorType]="ColorType.PRIMARY"
(previewChanged)="previewData.primaryColorDark !== $event ? setDarkPrimaryColorAndSave($event) : null"
name="Primary Color"
@ -255,7 +337,18 @@
<div class="color">
<cnsl-color
[disabled]="view === View.CURRENT"
[disabled]="
view === View.CURRENT ||
([
serviceType === PolicyComponentServiceType.ADMIN
? 'iam.policy.write'
: serviceType === PolicyComponentServiceType.MGMT
? 'policy.write'
: ''
]
| hasRole
| async) === false
"
[colorType]="ColorType.WARN"
(previewChanged)="previewData.warnColorDark !== $event ? setDarkWarnColorAndSave($event) : null"
name="Warn Color"
@ -267,7 +360,18 @@
<div class="color">
<cnsl-color
[disabled]="view === View.CURRENT"
[disabled]="
view === View.CURRENT ||
([
serviceType === PolicyComponentServiceType.ADMIN
? 'iam.policy.write'
: serviceType === PolicyComponentServiceType.MGMT
? 'policy.write'
: ''
]
| hasRole
| async) === false
"
[colorType]="ColorType.FONTDARK"
(previewChanged)="previewData.fontColorDark !== $event ? setDarkFontColorAndSave($event) : null"
name="Font Color"
@ -283,7 +387,18 @@
<div class="colors" *ngIf="data && previewData">
<div class="color">
<cnsl-color
[disabled]="view === View.CURRENT"
[disabled]="
view === View.CURRENT ||
([
serviceType === PolicyComponentServiceType.ADMIN
? 'iam.policy.write'
: serviceType === PolicyComponentServiceType.MGMT
? 'policy.write'
: ''
]
| hasRole
| async) === false
"
[colorType]="ColorType.BACKGROUNDLIGHT"
(previewChanged)="previewData.backgroundColor !== $event ? setBackgroundColorAndSave($event) : null"
name="Background Color"
@ -294,7 +409,18 @@
<div class="color">
<cnsl-color
[disabled]="view === View.CURRENT"
[disabled]="
view === View.CURRENT ||
([
serviceType === PolicyComponentServiceType.ADMIN
? 'iam.policy.write'
: serviceType === PolicyComponentServiceType.MGMT
? 'policy.write'
: ''
]
| hasRole
| async) === false
"
[colorType]="ColorType.PRIMARY"
(previewChanged)="previewData.primaryColor !== $event ? setPrimaryColorAndSave($event) : null"
name="Primary Color"
@ -306,7 +432,18 @@
<div class="color">
<cnsl-color
[disabled]="view === View.CURRENT"
[disabled]="
view === View.CURRENT ||
([
serviceType === PolicyComponentServiceType.ADMIN
? 'iam.policy.write'
: serviceType === PolicyComponentServiceType.MGMT
? 'policy.write'
: ''
]
| hasRole
| async) === false
"
[colorType]="ColorType.WARN"
name="Warn Color"
(previewChanged)="previewData.warnColor !== $event ? setWarnColorAndSave($event) : null"
@ -317,7 +454,18 @@
<div class="color">
<cnsl-color
[disabled]="view === View.CURRENT"
[disabled]="
view === View.CURRENT ||
([
serviceType === PolicyComponentServiceType.ADMIN
? 'iam.policy.write'
: serviceType === PolicyComponentServiceType.MGMT
? 'policy.write'
: ''
]
| hasRole
| async) === false
"
[colorType]="ColorType.FONTLIGHT"
(previewChanged)="previewData.fontColor !== $event ? setFontColorAndSave($event) : null"
name="Font Color"
@ -349,7 +497,18 @@
<button
class="dl-btn"
[disabled]="view === View.CURRENT"
[disabled]="
view === View.CURRENT ||
([
serviceType === PolicyComponentServiceType.ADMIN
? 'iam.policy.write'
: serviceType === PolicyComponentServiceType.MGMT
? 'policy.write'
: ''
]
| hasRole
| async) === false
"
mat-icon-button
color="warn"
(click)="deleteFont()"
@ -375,7 +534,19 @@
(change)="onDropFont($any($event.target).files)"
/>
<a
class="btn"
class="asset-add-btn"
[disabled]="
view === View.CURRENT ||
([
serviceType === PolicyComponentServiceType.ADMIN
? 'iam.policy.write'
: serviceType === PolicyComponentServiceType.MGMT
? 'policy.write'
: ''
]
| hasRole
| async) === false
"
mat-icon-button
*ngIf="view !== View.CURRENT"
(click)="selectedFontFile.click()"

View File

@ -168,6 +168,12 @@
flex: 1;
}
.asset-add-btn {
&[disabled] {
color: map-get($foreground, disabled-text);
}
}
.img-wrapper {
position: relative;
height: 70px;

View File

@ -7,7 +7,7 @@
<cnsl-card class="generator" [nomargin]="true" *ngFor="let gen of AVAILABLEGENERATORS">
<div class="row">
<h3 class="title">{{ 'SETTING.SECRETS.TYPE.' + gen | translate }}</h3>
<button mat-icon-button (click)="openGeneratorDialog(gen)">
<button mat-icon-button (click)="openGeneratorDialog(gen)" [disabled]="(['iam.write'] | hasRole | async) === false">
<i class="las la-pen"></i>
</button>
</div>

View File

@ -7,6 +7,7 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatSelectModule } from '@angular/material/select';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
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 { FormFieldModule } from '../../form-field/form-field.module';
@ -21,6 +22,7 @@ import { SecretGeneratorComponent } from './secret-generator.component';
MatIconModule,
CardModule,
FormsModule,
HasRolePipeModule,
MatButtonModule,
FormFieldModule,
ReactiveFormsModule,

View File

@ -39,6 +39,7 @@
grid-template-columns: 1fr;
gap: 1rem;
justify-content: space-evenly;
padding-bottom: 1rem;
@media only screen and (min-width: 599px) {
grid-template-columns: 1fr 1fr;

View File

@ -17,7 +17,7 @@
(addClicked)="openAddMember()"
(showDetailClicked)="showDetail()"
(refreshClicked)="loadMembers()"
[disabled]="false"
[disabled]="(['iam.member.write'] | hasRole | async) === false"
>
</cnsl-contributors>
</div>

View File

@ -81,7 +81,7 @@ export class InstanceComponent {
}),
)
.then(() => {
this.toast.showInfo('IAM.TOAST.MEMBERADDED');
this.toast.showInfo('IAM.TOAST.MEMBERADDED', true);
setTimeout(() => {
this.loadMembers();
}, 1000);

View File

@ -16,7 +16,7 @@
(addClicked)="openAddMember()"
(showDetailClicked)="showDetail()"
(refreshClicked)="loadMembers()"
[disabled]="false"
[disabled]="(['org.member.write'] | hasRole | async) === false"
>
</cnsl-contributors>

View File

@ -21,6 +21,10 @@
border-bottom: 1px solid #ffffff20;
flex-wrap: wrap;
&:last-child {
border-bottom: none;
}
.left {
.label {
font-size: 13px;

View File

@ -6,7 +6,7 @@ Login:
LoginNameLabel: Loginname
UsernamePlaceHolder: username
LoginnamePlaceHolder: username@domain
ExternalUserDescription: Melde dich mit einem externen Benutzer an
ExternalUserDescription: oder melde dich mit einem externen Benutzer an
MustBeMemberOfOrg: Der Benutzer muss der Organisation {{.OrgName}} angehören.
RegisterButtonText: registrieren
NextButtonText: weiter
@ -159,7 +159,7 @@ PasswordlessRegistrationDone:
PasswordChange:
Title: Passwort ändern
Description: Ändere dein Password in dem du dein altes und dann dein neuen Passwort eingibst.
Description: Ändere dein Passwort in dem du dein altes und dann dein neues Passwort eingibst.
OldPasswordLabel: Altes Passwort
NewPasswordLabel: Neues Passwort
NewPasswordConfirmLabel: Passwort Bestätigung

View File

@ -0,0 +1,13 @@
let inputs = document.getElementsByTagName("input");
if (inputs && inputs.length) {
for (let input of inputs) {
input.addEventListener("focus", () => {
input.classList.add("lgn-focused");
});
input.addEventListener("blur", () => {
input.classList.add("lgn-touched");
input.classList.remove("lgn-focused");
});
}
}

View File

@ -1,4 +1,4 @@
@import 'identity_provider_base';
@import "identity_provider_base";
.lgn-idp {
@include lgn-idp-base;

View File

@ -1,11 +1,10 @@
@import 'identity_provider';
@import "identity_provider";
@mixin lgn-idp-theme() {
@include lgn-idp-color();
}
@mixin lgn-idp-color() {
.lgn-idp {
border-color: var(--zitadel-color-divider);
@ -20,6 +19,12 @@
background-color: var(--zitadel-color-google-background);
}
}
.lgn-idp-providers {
.lgn-idp-desc {
color: var(--zitadel-color-label);
}
}
}
@mixin lgn-idp-elevation($zValue, $opacity: $lgn-elevation-opacity) {

View File

@ -31,7 +31,7 @@
}
// overwrite if state is warn
&[color="warn"] {
&.lgn-touched[color="warn"] {
border-color: var(--zitadel-color-warn);
}
}

View File

@ -45,7 +45,7 @@
--zitadel-color-footer-line: rgba(0, 0, 0, 0.12);
--zitadel-color-input-background: #00000003;
--zitadel-color-input-border: #00000040;
--zitadel-color-input-border: #1a191938;
--zitadel-color-input-border-hover: #1a1b1b;
--zitadel-color-input-border-active: var(--zitadel-color-primary-500);
--zitadel-color-input-placeholder: var(--zitadel-color-grey-600);
@ -156,7 +156,7 @@
--zitadel-color-footer-line: rgba(255, 255, 255, 0.12);
--zitadel-color-input-background: rgba(0, 0, 0, 0.2);
--zitadel-color-input-border: #403e3e;
--zitadel-color-input-border: #f9f7f725;
--zitadel-color-input-border-hover: #aeafb1;
--zitadel-color-input-border-active: var(--zitadel-color-primary-500);
--zitadel-color-input-placeholder: var(--zitadel-color-grey-600);

View File

@ -40,7 +40,7 @@
--zitadel-color-background-contrast: rgb(0, 0, 0);
--zitadel-color-footer-line: rgba(0, 0, 0, 0.12);
--zitadel-color-input-background: #00000003;
--zitadel-color-input-border: #00000040;
--zitadel-color-input-border: #1a191938;
--zitadel-color-input-border-hover: #1a1b1b;
--zitadel-color-input-border-active: var(--zitadel-color-primary-500);
--zitadel-color-input-placeholder: var(--zitadel-color-grey-600);
@ -136,7 +136,7 @@
--zitadel-color-background-contrast: rgb(255, 255, 255);
--zitadel-color-footer-line: rgba(255, 255, 255, 0.12);
--zitadel-color-input-background: rgba(0, 0, 0, 0.2);
--zitadel-color-input-border: #403e3e;
--zitadel-color-input-border: #f9f7f725;
--zitadel-color-input-border-hover: #aeafb1;
--zitadel-color-input-border-active: var(--zitadel-color-primary-500);
--zitadel-color-input-placeholder: var(--zitadel-color-grey-600);
@ -2721,9 +2721,9 @@ select:focus,
.lgn-select:focus {
border-color: var(--zitadel-color-input-border-active);
}
.lgn-input[color=warn],
select[color=warn],
.lgn-select[color=warn] {
.lgn-input.lgn-touched[color=warn],
select.lgn-touched[color=warn],
.lgn-select.lgn-touched[color=warn] {
border-color: var(--zitadel-color-warn);
}
@ -2921,6 +2921,10 @@ ul li i.lgn-valid {
background-color: var(--zitadel-color-google-background);
}
.lgn-idp-providers .lgn-idp-desc {
color: var(--zitadel-color-label);
}
.lgn-success-label {
color: var(--zitadel-color-success);
background-color: var(--zitadel-color-success-background);

File diff suppressed because one or more lines are too long

View File

@ -42,7 +42,7 @@
{{if hasExternalLogin }}
<div class="lgn-idp-providers">
<p>{{t "Login.ExternalUserDescription"}}</p>
<p class="lgn-idp-desc">{{t "Login.ExternalUserDescription"}}</p>
{{ $reqid := .AuthReqID}}
{{range $provider := .IDPProviders}}

View File

@ -33,6 +33,7 @@
</div>
</div>
<script src="{{ resourceUrl "scripts/avatar.js" }}"></script>
<script src="{{ resourceUrl "scripts/touched.js" }}"></script>
</body>
<footer>
{{template "footer" .}}