mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-04 21:32:15 +00:00
# Which Problems Are Solved Users were not yet able to specify (and test) the new login UI or self-hosted login UI for SAML applications through Console. # How the Problems Are Solved Added the configuration for SAML apps (as already available for OIDC) in Console. # Additional Changes None # Additional Context - closes #9354
534 lines
22 KiB
HTML
534 lines
22 KiB
HTML
<cnsl-top-view
|
|
title="{{ app?.name }}"
|
|
[hasActions]="isZitadel === false && (['project.app.write:' + projectId, 'project.app.write'] | hasRole | async)"
|
|
docLink="https://zitadel.com/docs/guides/manage/console/projects"
|
|
[sub]="app?.oidcConfig ? ('APP.OIDC.APPTYPE.' + app?.oidcConfig?.appType | translate) : app?.apiConfig ? 'API' : 'SAML'"
|
|
[isActive]="app?.state === AppState.APP_STATE_ACTIVE"
|
|
[isInactive]="app?.state === AppState.APP_STATE_INACTIVE"
|
|
stateTooltip="{{ 'APP.PAGES.DETAIL.STATE.' + app?.state | translate }}"
|
|
>
|
|
<ng-template topActions cnslHasRole [hasRole]="['project.app.write:' + projectId, 'project.app.write']">
|
|
<div
|
|
class="regen-secret"
|
|
*ngIf="isZitadel === false && this.app?.oidcConfig && (currentAuthMethod === 'CODE' || currentAuthMethod === 'POST')"
|
|
>
|
|
<button type="button" [disabled]="!canWrite" mat-menu-item (click)="regenerateOIDCClientSecret()">
|
|
{{ 'APP.OIDC.REGENERATESECRET' | translate }}
|
|
</button>
|
|
</div>
|
|
|
|
<div class="regen-secret" *ngIf="isZitadel === false && this.app?.apiConfig && currentAuthMethod === 'BASIC'">
|
|
<button [disabled]="!canWrite" mat-menu-item (click)="regenerateAPIClientSecret()">
|
|
{{ 'APP.API.REGENERATESECRET' | translate }}
|
|
</button>
|
|
</div>
|
|
|
|
<button *ngIf="isZitadel === false" mat-menu-item (click)="openNameDialog()" aria-label="Edit project name">
|
|
{{ 'ACTIONS.RENAME' | translate }}
|
|
</button>
|
|
<button
|
|
mat-menu-item
|
|
*ngIf="isZitadel === false && app?.state !== AppState.APP_STATE_INACTIVE"
|
|
(click)="changeState(AppState.APP_STATE_INACTIVE)"
|
|
>
|
|
{{ 'ACTIONS.DEACTIVATE' | translate }}
|
|
</button>
|
|
<button
|
|
mat-menu-item
|
|
*ngIf="isZitadel === false && app?.state === AppState.APP_STATE_INACTIVE"
|
|
(click)="changeState(AppState.APP_STATE_ACTIVE)"
|
|
>
|
|
{{ 'ACTIONS.REACTIVATE' | translate }}
|
|
</button>
|
|
<ng-template cnslHasRole [hasRole]="['project.app.delete:' + projectId, 'project.app.delete']">
|
|
<button
|
|
*ngIf="isZitadel === false"
|
|
mat-menu-item
|
|
matTooltip="{{ 'APP.PAGES.DELETE' | translate }}"
|
|
(click)="deleteApp()"
|
|
>
|
|
<span [style.color]="'var(--warn)'">{{ 'APP.PAGES.DELETE' | translate }}</span>
|
|
</button>
|
|
</ng-template>
|
|
</ng-template>
|
|
<span *ngIf="errorMessage" class="app-err-container">{{ errorMessage }}</span>
|
|
|
|
<cnsl-info-row topContent *ngIf="app" [app]="app"></cnsl-info-row>
|
|
</cnsl-top-view>
|
|
|
|
<div class="max-width-container">
|
|
<cnsl-info-section *ngIf="isNew()" class="problem" [type]="InfoSectionType.INFO">
|
|
<div class="jumptoproject-row">
|
|
<span class="jumptoproject">{{ 'APP.PAGES.JUMPTOPROJECT' | translate }}</span>
|
|
<a [routerLink]="['/projects', projectId]" color="primary" mat-raised-button>{{ 'ACTIONS.CONFIGURE' | translate }}</a>
|
|
</div>
|
|
</cnsl-info-section>
|
|
|
|
<div
|
|
class="compliance"
|
|
*ngIf="app && app.oidcConfig && app.oidcConfig.complianceProblemsList && app.oidcConfig.complianceProblemsList?.length"
|
|
>
|
|
<h2 class="compliance-title">{{ 'APP.COMPLIANCE' | translate }}</h2>
|
|
<cnsl-info-section class="problem" [type]="InfoSectionType.ALERT">
|
|
<ul style="margin: 0">
|
|
<li style="margin: 0 0 0.5rem 0" *ngFor="let problem of app.oidcConfig?.complianceProblemsList || []">
|
|
{{ problem.localizedMessage }}
|
|
</li>
|
|
</ul>
|
|
</cnsl-info-section>
|
|
</div>
|
|
|
|
<div class="app-main-content">
|
|
<cnsl-meta-layout>
|
|
<cnsl-sidenav [(ngModel)]="currentSetting" [settingsList]="settingsList">
|
|
<ng-container *ngIf="currentSetting === 'configuration'">
|
|
<cnsl-card *ngIf="oidcForm && app?.oidcConfig" title=" {{ 'APP.OIDC.TITLE' | translate }}">
|
|
<div
|
|
class="current-auth-method"
|
|
*ngIf="currentRadioItemAuthType"
|
|
[ngStyle]="{ background: currentRadioItemAuthType.background }"
|
|
>
|
|
<h3>{{ currentRadioItemAuthType.titleI18nKey | translate }}</h3>
|
|
<p>{{ currentRadioItemAuthType.descI18nKey | translate }}</p>
|
|
<span class="fill-space"></span>
|
|
<button mat-icon-button (click)="changeAuthMethod()"><i class="las la-pen"></i></button>
|
|
</div>
|
|
|
|
<form [formGroup]="oidcForm" (ngSubmit)="saveOIDCApp()">
|
|
<div class="app-oidc-content">
|
|
<div class="app-oidc-grid">
|
|
<cnsl-form-field class="app-formfield">
|
|
<cnsl-label>{{ 'APP.OIDC.CLIENTID' | translate }}</cnsl-label>
|
|
<input cnslInput formControlName="clientId" />
|
|
</cnsl-form-field>
|
|
|
|
<cnsl-form-field class="app-formfield">
|
|
<cnsl-label>{{ 'APP.TYPE' | translate }}</cnsl-label>
|
|
<mat-select formControlName="appType">
|
|
<mat-option *ngFor="let type of oidcAppTypes" [value]="type">
|
|
{{ 'APP.OIDC.APPTYPE.' + type | translate }}
|
|
</mat-option>
|
|
</mat-select>
|
|
</cnsl-form-field>
|
|
|
|
<cnsl-form-field class="app-formfield">
|
|
<cnsl-label>{{ 'APP.OIDC.RESPONSETYPE' | translate }}</cnsl-label>
|
|
<mat-select formControlName="responseTypesList" multiple>
|
|
<mat-option *ngFor="let type of oidcResponseTypes" [value]="type">
|
|
{{ 'APP.OIDC.RESPONSE.' + type | translate }}
|
|
</mat-option>
|
|
</mat-select>
|
|
</cnsl-form-field>
|
|
|
|
<cnsl-form-field class="app-formfield">
|
|
<cnsl-label>{{ 'APP.AUTHMETHOD' | translate }}</cnsl-label>
|
|
<mat-select formControlName="authMethodType">
|
|
<mat-option *ngFor="let type of oidcAuthMethodType" [value]="type">
|
|
{{ 'APP.OIDC.AUTHMETHOD.' + type | translate }}
|
|
</mat-option>
|
|
</mat-select>
|
|
</cnsl-form-field>
|
|
|
|
<cnsl-form-field class="app-formfield">
|
|
<cnsl-label>{{ 'APP.OIDC.GRANTTYPE' | translate }}</cnsl-label>
|
|
<mat-select formControlName="grantTypesList" multiple>
|
|
<mat-option *ngFor="let grant of oidcGrantTypes" [value]="grant">
|
|
{{ 'APP.OIDC.GRANT.' + grant | translate }}
|
|
</mat-option>
|
|
</mat-select>
|
|
</cnsl-form-field>
|
|
|
|
<mat-checkbox
|
|
color="primary"
|
|
class="rt"
|
|
(change)="toggleRefreshToken($event)"
|
|
[disabled]="!this.grantTypesList?.value.includes(OIDCGrantType.OIDC_GRANT_TYPE_AUTHORIZATION_CODE)"
|
|
[checked]="this.grantTypesList?.value.includes(OIDCGrantType.OIDC_GRANT_TYPE_REFRESH_TOKEN)"
|
|
>
|
|
{{ 'APP.OIDC.REFRESHTOKEN' | translate }}
|
|
</mat-checkbox>
|
|
|
|
<mat-checkbox
|
|
*ngIf="oidcLoginV2"
|
|
color="primary"
|
|
class="rt"
|
|
[formControl]="oidcLoginV2"
|
|
name="loginV2"
|
|
matTooltip="{{ 'APP.LOGINV2DESC' | translate }}"
|
|
>
|
|
{{ 'APP.LOGINV2.USEV2' | translate }}
|
|
</mat-checkbox>
|
|
|
|
<cnsl-form-field class="app-formfield">
|
|
<cnsl-label>{{ 'APP.LOGINV2.BASEURL' | translate }}</cnsl-label>
|
|
<input cnslInput formControlName="loginV2BaseURL" />
|
|
</cnsl-form-field>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="btn-container">
|
|
<button
|
|
class="submit-button"
|
|
type="submit"
|
|
color="primary"
|
|
[disabled]="oidcForm.invalid || !canWrite"
|
|
mat-raised-button
|
|
>
|
|
{{ 'ACTIONS.SAVE' | translate }}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</cnsl-card>
|
|
|
|
<cnsl-card *ngIf="samlForm && app?.samlConfig" title="{{ 'APP.SAML.CONFIGSECTION' | translate }}">
|
|
<h3 class="title cnsl-secondary-text">
|
|
{{ 'APP.SAML.CHOOSEMETADATASOURCE' | translate }}
|
|
</h3>
|
|
|
|
<div class="metadata-option">
|
|
<span class="saml-config-option">{{ 'APP.SAML.METADATAOPT1' | translate }}</span>
|
|
<form [formGroup]="samlForm">
|
|
<cnsl-form-field class="formfield">
|
|
<input cnslInput formControlName="metadataUrl" placeholder="https://" />
|
|
</cnsl-form-field>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="metadata-option">
|
|
<span class="saml-config-option">{{ 'APP.SAML.METADATAOPT2' | translate }}</span>
|
|
<input
|
|
#xmlFileInput
|
|
style="display: none"
|
|
class="file-input"
|
|
type="file"
|
|
accept="text/xml,application/xml"
|
|
(change)="onDropXML($any($event.target).files)"
|
|
/>
|
|
<button class="upload-button" mat-stroked-button (click)="$event.preventDefault(); xmlFileInput.click()">
|
|
{{ 'APP.SAML.UPLOAD' | translate }}
|
|
</button>
|
|
</div>
|
|
|
|
<div class="metadata-option">
|
|
<span class="saml-config-option">{{ 'APP.SAML.METADATAOPT3' | translate }}</span>
|
|
<form [formGroup]="samlForm">
|
|
<cnsl-form-field class="formfield">
|
|
<cnsl-label>{{ 'APP.SAML.ENTITYID' | translate }}</cnsl-label>
|
|
<input cnslInput formControlName="entityId" placeholder="https://" />
|
|
</cnsl-form-field>
|
|
<cnsl-form-field class="formfield">
|
|
<cnsl-label>{{ 'APP.SAML.ACSURL' | translate }}</cnsl-label>
|
|
<input cnslInput formControlName="acsURL" placeholder="https://" />
|
|
</cnsl-form-field>
|
|
</form>
|
|
</div>
|
|
|
|
<div
|
|
class="saml-xml"
|
|
[ngClass]="{ disabled: !!metadataUrl?.value }"
|
|
*ngIf="decodedBase64 && app && app.samlConfig && !app.samlConfig.metadataUrl"
|
|
>
|
|
<ngx-codemirror
|
|
[(ngModel)]="decodedBase64"
|
|
[disabled]="!!metadataUrl?.value"
|
|
[options]="{
|
|
lineNumbers: true,
|
|
theme: 'material',
|
|
mode: 'application/xml',
|
|
}"
|
|
></ngx-codemirror>
|
|
</div>
|
|
|
|
<div class="saml-login-version">
|
|
<form [formGroup]="samlForm">
|
|
<mat-checkbox
|
|
*ngIf="samlLoginV2"
|
|
color="primary"
|
|
class="rt"
|
|
[formControl]="samlLoginV2"
|
|
name="loginV2"
|
|
matTooltip="{{ 'APP.LOGINV2DESC' | translate }}"
|
|
>
|
|
{{ 'APP.LOGINV2.USEV2' | translate }}
|
|
</mat-checkbox>
|
|
|
|
<cnsl-form-field class="app-formfield">
|
|
<cnsl-label>{{ 'APP.LOGINV2.BASEURL' | translate }}</cnsl-label>
|
|
<input cnslInput formControlName="loginV2BaseURL" />
|
|
</cnsl-form-field>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="btn-container">
|
|
<button
|
|
class="submit-button"
|
|
type="submit"
|
|
color="primary"
|
|
(click)="saveSAMLApp()"
|
|
[disabled]="samlForm.invalid || !canWrite"
|
|
mat-raised-button
|
|
>
|
|
{{ 'ACTIONS.SAVE' | translate }}
|
|
</button>
|
|
</div>
|
|
</cnsl-card>
|
|
</ng-container>
|
|
|
|
<ng-container *ngIf="currentSetting === 'token'">
|
|
<cnsl-card *ngIf="oidcTokenForm && app?.oidcConfig" title=" {{ 'APP.OIDC.TOKENSECTIONTITLE' | translate }}">
|
|
<form [formGroup]="oidcTokenForm" (ngSubmit)="saveOIDCApp()">
|
|
<cnsl-form-field class="app-formfield">
|
|
<cnsl-label>{{ 'APP.OIDC.TOKENTYPE' | translate }}</cnsl-label>
|
|
<mat-select formControlName="accessTokenType">
|
|
<mat-option *ngFor="let type of oidcTokenTypes" [value]="type">
|
|
{{ 'APP.OIDC.TOKENTYPE' + type | translate }}
|
|
</mat-option>
|
|
</mat-select>
|
|
</cnsl-form-field>
|
|
|
|
<mat-checkbox
|
|
*ngIf="accessTokenType?.value === OIDCTokenType.OIDC_TOKEN_TYPE_JWT"
|
|
class="full-width"
|
|
style="margin-top: 1.5rem"
|
|
formControlName="accessTokenRoleAssertion"
|
|
color="primary"
|
|
>
|
|
{{ 'APP.OIDC.ACCESSTOKENROLEASSERTION' | translate }}</mat-checkbox
|
|
>
|
|
|
|
<cnsl-info-section class="full-width app-desc">
|
|
<span>{{ 'APP.OIDC.ACCESSTOKENROLEASSERTION_DESCRIPTION' | translate }}</span>
|
|
</cnsl-info-section>
|
|
|
|
<mat-checkbox
|
|
class="full-width"
|
|
style="margin-top: 1.5rem"
|
|
formControlName="idTokenRoleAssertion"
|
|
color="primary"
|
|
>
|
|
{{ 'APP.OIDC.IDTOKENROLEASSERTION' | translate }}</mat-checkbox
|
|
>
|
|
<cnsl-info-section class="full-width app-desc">
|
|
<span>{{ 'APP.OIDC.IDTOKENROLEASSERTION_DESCRIPTION' | translate }}</span>
|
|
</cnsl-info-section>
|
|
|
|
<mat-checkbox
|
|
class="full-width"
|
|
style="margin-top: 1.5rem"
|
|
formControlName="idTokenUserinfoAssertion"
|
|
color="primary"
|
|
>
|
|
{{ 'APP.OIDC.IDTOKENUSERINFOASSERTION' | translate }}</mat-checkbox
|
|
>
|
|
<cnsl-info-section class="full-width app-desc">
|
|
<span>{{ 'APP.OIDC.IDTOKENUSERINFOASSERTION_DESCRIPTION' | translate }}</span>
|
|
</cnsl-info-section>
|
|
|
|
<p class="clockskew-title cnsl-secondary-text">ClockSkew</p>
|
|
<!-- TODO: The 'tickInterval' property no longer exists -->
|
|
<mat-slider
|
|
color="primary"
|
|
class="clockskew-slider"
|
|
thumbLabel
|
|
[displayWith]="formatClockSkewLabel"
|
|
min="0"
|
|
[step]="1"
|
|
max="5"
|
|
><input matSliderThumb formControlName="clockSkewSeconds" />
|
|
</mat-slider>
|
|
<cnsl-info-section class="full-width app-desc">
|
|
<span>{{ 'APP.OIDC.CLOCKSKEW' | translate }}</span>
|
|
</cnsl-info-section>
|
|
|
|
<div class="btn-container">
|
|
<button
|
|
class="submit-button"
|
|
type="submit"
|
|
color="primary"
|
|
[disabled]="oidcTokenForm.invalid || !canWrite"
|
|
mat-raised-button
|
|
>
|
|
{{ 'ACTIONS.SAVE' | translate }}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</cnsl-card>
|
|
</ng-container>
|
|
|
|
<ng-container *ngIf="currentSetting === 'redirect-uris'">
|
|
<cnsl-card title=" {{ 'APP.OIDC.REDIRECTSECTIONTITLE' | translate }}">
|
|
<cnsl-info-section *ngIf="appType?.value === OIDCAppType.OIDC_APP_TYPE_NATIVE">
|
|
<div class="dev-col">
|
|
<span>{{ 'APP.OIDC.REDIRECTDESCRIPTIONNATIVE' | translate }}</span>
|
|
<mat-slide-toggle
|
|
*ngIf="devMode"
|
|
color="primary"
|
|
class="devmode"
|
|
[formControl]="devMode"
|
|
name="devMode"
|
|
matTooltip="{{ 'APP.OIDC.DEVMODEDESC' | translate }}"
|
|
>
|
|
{{ 'APP.OIDC.DEVMODE' | translate }}
|
|
</mat-slide-toggle>
|
|
</div>
|
|
</cnsl-info-section>
|
|
<cnsl-info-section
|
|
*ngIf="
|
|
appType?.value === OIDCAppType.OIDC_APP_TYPE_WEB || appType?.value === OIDCAppType.OIDC_APP_TYPE_USER_AGENT
|
|
"
|
|
>
|
|
<div class="dev-col">
|
|
<span>{{ 'APP.OIDC.REDIRECTDESCRIPTIONWEB' | translate }}</span>
|
|
<mat-slide-toggle
|
|
*ngIf="devMode"
|
|
color="primary"
|
|
class="devmode"
|
|
[formControl]="devMode"
|
|
name="devMode"
|
|
matTooltip="{{ 'APP.OIDC.DEVMODEDESC' | translate }}"
|
|
>
|
|
{{ 'APP.OIDC.DEVMODE' | translate }}
|
|
</mat-slide-toggle>
|
|
</div>
|
|
</cnsl-info-section>
|
|
|
|
<mat-checkbox
|
|
*ngIf="skipNativeAppSuccessPage && appType?.value === OIDCAppType.OIDC_APP_TYPE_NATIVE"
|
|
class="full-width"
|
|
style="margin-top: 1.5rem"
|
|
[formControl]="skipNativeAppSuccessPage"
|
|
color="primary"
|
|
>
|
|
{{ 'APP.OIDC.SKIPNATIVEAPPSUCCESSPAGE' | translate }}</mat-checkbox
|
|
>
|
|
<cnsl-info-section *ngIf="appType?.value === OIDCAppType.OIDC_APP_TYPE_NATIVE" class="full-width app-desc">
|
|
<span>{{ 'APP.OIDC.SKIPNATIVEAPPSUCCESSPAGE_DESCRIPTION' | translate }}</span>
|
|
</cnsl-info-section>
|
|
|
|
<cnsl-redirect-uris
|
|
*ngIf="appType?.value !== undefined"
|
|
class="redirect-section"
|
|
[disabled]="!canWrite"
|
|
[devMode]="!!devMode?.value"
|
|
[(ngModel)]="redirectUrisList"
|
|
title="{{ 'APP.OIDC.REDIRECT' | translate }}"
|
|
[isNative]="appType?.value === OIDCAppType.OIDC_APP_TYPE_NATIVE"
|
|
>
|
|
</cnsl-redirect-uris>
|
|
|
|
<cnsl-redirect-uris
|
|
*ngIf="appType?.value !== undefined"
|
|
class="redirect-section"
|
|
[disabled]="!canWrite"
|
|
[devMode]="!!devMode?.value"
|
|
[(ngModel)]="postLogoutRedirectUrisList"
|
|
title="{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}"
|
|
[isNative]="appType?.value === OIDCAppType.OIDC_APP_TYPE_NATIVE"
|
|
>
|
|
</cnsl-redirect-uris>
|
|
|
|
<div class="btn-container">
|
|
<button class="submit-button" color="primary" (click)="saveOIDCApp()" [disabled]="!canWrite" mat-raised-button>
|
|
{{ 'ACTIONS.SAVE' | translate }}
|
|
</button>
|
|
</div>
|
|
</cnsl-card>
|
|
</ng-container>
|
|
|
|
<ng-container *ngIf="currentSetting === 'additional-origins'">
|
|
<cnsl-card title=" {{ 'APP.ADDITIONALORIGINS' | translate }}">
|
|
<p class="app-desc cnsl-secondary-text">{{ 'APP.ADDITIONALORIGINSDESC' | translate }}</p>
|
|
<cnsl-additional-origins
|
|
*ngIf="additionalOriginsList && appType && appType?.value !== undefined"
|
|
class="app-input"
|
|
[canWrite]="canWrite"
|
|
[getValues]="requestRedirectValuesSubject$"
|
|
(changedUris)="additionalOriginsListChanged($event)"
|
|
[urisList]="additionalOriginsList"
|
|
title="{{ 'APP.ORIGINS' | translate }}"
|
|
>
|
|
</cnsl-additional-origins>
|
|
|
|
<div class="btn-container">
|
|
<button class="submit-button" (click)="saveOIDCApp()" color="primary" [disabled]="!canWrite" mat-raised-button>
|
|
{{ 'ACTIONS.SAVE' | translate }}
|
|
</button>
|
|
</div>
|
|
</cnsl-card>
|
|
</ng-container>
|
|
<ng-container *ngIf="currentSetting === 'urls'">
|
|
<cnsl-card title=" {{ 'APP.URLS' | translate }}">
|
|
<cnsl-info-section *ngIf="issuer$ | async as issuer">
|
|
<div
|
|
class="link"
|
|
[innerHtml]="'APP.OIDC.WELLKNOWN' | translate: { url: issuer + '/.well-known/openid-configuration' }"
|
|
></div>
|
|
</cnsl-info-section>
|
|
<ng-container *ngIf="app?.apiConfig && apiURLs$ | async as apiURLs">
|
|
<cnsl-copy-row
|
|
labelMinWidth="220px"
|
|
*ngFor="let apiUrl of apiURLs"
|
|
[label]="apiUrl[0]"
|
|
[value]="apiUrl[1]"
|
|
></cnsl-copy-row>
|
|
</ng-container>
|
|
<ng-container *ngIf="app?.samlConfig && samlURLs$ | async as samlMap">
|
|
<cnsl-copy-row
|
|
labelMinWidth="220px"
|
|
*ngIf="samlMap['samlCertificateURL'] as url"
|
|
[label]="'APP.SAML.CERTIFICATE' | translate"
|
|
[value]="url"
|
|
>
|
|
<a class="download-button" mat-stroked-button [href]="url" download>{{ 'ACTIONS.DOWNLOAD' | translate }}</a>
|
|
</cnsl-copy-row>
|
|
<cnsl-copy-row
|
|
labelMinWidth="220px"
|
|
*ngIf="samlMap['samlSSO'] as url"
|
|
label="Single Sign On (SSO)"
|
|
[value]="url"
|
|
></cnsl-copy-row>
|
|
<cnsl-copy-row
|
|
labelMinWidth="220px"
|
|
*ngIf="samlMap['samlSLO'] as url"
|
|
label="Single Logout (SLO)"
|
|
[value]="url"
|
|
></cnsl-copy-row>
|
|
</ng-container>
|
|
<ng-container *ngIf="app?.oidcConfig && wellknownURLs$ | async as wellKnownURLs">
|
|
<ng-container *ngFor="let wellknown of wellKnownURLs">
|
|
<cnsl-copy-row labelMinWidth="220px" [label]="wellknown[0]" [value]="wellknown[1]"></cnsl-copy-row>
|
|
</ng-container>
|
|
</ng-container>
|
|
</cnsl-card>
|
|
</ng-container>
|
|
|
|
<ng-container *ngIf="currentSetting === 'configuration'">
|
|
<cnsl-card
|
|
*ngIf="initialAuthMethod === 'PK_JWT' && projectId && app && app.id"
|
|
title="{{ 'USER.MACHINE.KEYSTITLE' | translate }}"
|
|
description="{{ 'USER.MACHINE.KEYSDESC' | translate }}"
|
|
>
|
|
<cnsl-client-keys [projectId]="projectId" [appId]="app.id"></cnsl-client-keys>
|
|
|
|
<div *ngIf="apiForm && app?.apiConfig" class="btn-container">
|
|
<button
|
|
class="submit-button"
|
|
(click)="saveAPIApp()"
|
|
color="primary"
|
|
[disabled]="apiForm.invalid || !canWrite"
|
|
mat-raised-button
|
|
>
|
|
{{ 'ACTIONS.SAVE' | translate }}
|
|
</button>
|
|
</div>
|
|
</cnsl-card>
|
|
</ng-container>
|
|
</cnsl-sidenav>
|
|
|
|
<div metainfo>
|
|
<cnsl-changes *ngIf="app" [changeType]="ChangeType.APP" [id]="app.id" [secId]="projectId"></cnsl-changes>
|
|
</div>
|
|
</cnsl-meta-layout>
|
|
</div>
|
|
</div>
|