1
0
mirror of https://github.com/bitwarden/web synced 2025-12-06 00:03:28 +00:00
Files
web/bitwarden_license/src/app/organizations/manage/sso.component.html
2021-11-23 21:11:47 +10:00

364 lines
18 KiB
HTML

<div class="page-header d-flex">
<h1>{{'singleSignOn' | i18n}}</h1>
</div>
<ng-container *ngIf="loading">
<i class="fa fa-spinner fa-spin text-muted" title="{{'loading' | i18n}}" aria-hidden="true"></i>
<span class="sr-only">{{'loading' | i18n}}</span>
</ng-container>
<form #form (ngSubmit)="submit()" [formGroup]="data" [appApiAction]="formPromise" *ngIf="!loading" ngNativeValidate>
<p>
{{'ssoPolicyHelpStart' | i18n}}
<a routerLink="../policies">{{'ssoPolicyHelpLink' | i18n}}</a>
{{'ssoPolicyHelpEnd' | i18n}}
<br>
{{'ssoPolicyHelpKeyConnector' | i18n}}
</p>
<div class="form-group">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="enabled" [formControl]="enabled" name="Enabled">
<label class="form-check-label" for="enabled">{{'allowSso' | i18n}}</label>
</div>
<small class="form-text text-muted">{{'allowSsoDesc' | i18n}}</small>
</div>
<div class="form-group">
<label>{{'memberDecryptionOption' | i18n}}</label>
<div class="form-check form-check-block">
<input class="form-check-input" type="radio" id="memberDecryptionPass" [value]="false" formControlName="keyConnectorEnabled">
<label class="form-check-label" for="memberDecryptionPass">
{{'masterPass' | i18n}}
<small>{{'memberDecryptionPassDesc' | i18n}}</small>
</label>
</div>
<div class="form-check mt-2 form-check-block">
<input class="form-check-input" type="radio" id="memberDecryptionKey" [value]="true" formControlName="keyConnectorEnabled"
[attr.disabled]="!organization.useKeyConnector || null">
<label class="form-check-label" for="memberDecryptionKey">
{{'keyConnector' | i18n}}
<a target="_blank" rel="noopener" appA11yTitle="{{'learnMore' | i18n}}"
href="https://bitwarden.com/help/article/about-key-connector/">
<i class="fa fa-question-circle-o" aria-hidden="true"></i>
</a>
<small>{{'memberDecryptionKeyConnectorDesc' | i18n}}</small>
</label>
</div>
</div>
<ng-container *ngIf="data.value.keyConnectorEnabled">
<app-callout type="warning" [useAlertRole]="true">
{{'keyConnectorWarning' | i18n}}
</app-callout>
<div class="form-group">
<label for="keyConnectorUrl">{{'keyConnectorUrl' | i18n}}</label>
<div class="input-group">
<input class="form-control" formControlName="keyConnectorUrl" id="keyConnectorUrl" required>
<div class="input-group-append">
<button type="button" class="btn btn-outline-secondary" (click)="validateKeyConnectorUrl()"
[disabled]="!enableTestKeyConnector">
<i class="fa fa-spinner fa-spin" title="{{'loading' | i18n}}" aria-hidden="true"
*ngIf="keyConnectorUrl.pending"></i>
<span *ngIf="!keyConnectorUrl.pending">
{{'keyConnectorTest' | i18n}}
</span>
</button>
</div>
</div>
<ng-container *ngIf="keyConnectorUrl.pristine && !keyConnectorUrl.pending">
<div class="text-danger" *ngIf="keyConnectorUrl.hasError('invalidUrl')" role="alert">
<i class="fa fa-exclamation-circle" aria-hidden="true"></i>
{{'keyConnectorTestFail' | i18n}}
</div>
<div class="text-success" *ngIf="!keyConnectorUrl.hasError('invalidUrl')" role="alert">
<i class="fa fa-check-circle-o" aria-hidden="true"></i>
{{'keyConnectorTestSuccess' | i18n}}
</div>
</ng-container>
</div>
</ng-container>
<div class="form-group">
<label for="type">{{'type' | i18n}}</label>
<select class="form-control" id="type" formControlName="configType">
<option value="0" disabled>{{'selectType' | i18n}}</option>
<option value="1">OpenID Connect</option>
<option value="2">SAML 2.0</option>
</select>
</div>
<!-- OIDC -->
<div *ngIf="data.value.configType == 1">
<div class="config-section">
<h2>{{'openIdConnectConfig' | i18n}}</h2>
<div class="form-group">
<label>{{'callbackPath' | i18n}}</label>
<div class="input-group">
<input class="form-control" readonly [value]="callbackPath">
<div class="input-group-append">
<button type="button" class="btn btn-outline-secondary"
appA11yTitle="{{'copyValue' | i18n}}"
(click)="copy(callbackPath)">
<i class="fa fa-lg fa-clone" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
<div class="form-group">
<label>{{'signedOutCallbackPath' | i18n}}</label>
<div class="input-group">
<input class="form-control" readonly [value]="signedOutCallbackPath">
<div class="input-group-append">
<button type="button" class="btn btn-outline-secondary"
appA11yTitle="{{'copyValue' | i18n}}"
(click)="copy(signedOutCallbackPath)">
<i class="fa fa-lg fa-clone" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
<div class="form-group">
<label for="authority">{{'authority' | i18n}}</label>
<input class="form-control" formControlName="authority" id="authority">
</div>
<div class="form-group">
<label for="clientId">{{'clientId' | i18n}}</label>
<input class="form-control" formControlName="clientId" id="clientId">
</div>
<div class="form-group">
<label for="clientSecret">{{'clientSecret' | i18n}}</label>
<input class="form-control" formControlName="clientSecret" id="clientSecret">
</div>
<div class="form-group">
<label for="metadataAddress">{{'metadataAddress' | i18n}}</label>
<input class="form-control" formControlName="metadataAddress" id="metadataAddress">
</div>
<div class="form-group">
<label for="redirectBehavior">{{'oidcRedirectBehavior' | i18n}}</label>
<select class="form-control" formControlName="redirectBehavior" id="redirectBehavior">
<option value="0">Redirect GET</option>
<option value="1">Form POST</option>
</select>
</div>
<div class="form-group">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="getClaimsFromUserInfoEndpoint"
formControlName="getClaimsFromUserInfoEndpoint">
<label class="form-check-label" for="getClaimsFromUserInfoEndpoint">
{{'getClaimsFromUserInfoEndpoint' | i18n}}
</label>
</div>
</div>
<div class="form-group">
<label for="additionalScopes">{{'additionalScopes' | i18n}}</label>
<input class="form-control" formControlName="additionalScopes" id="additionalScopes">
</div>
<div class="form-group">
<label for="additionalUserIdClaimTypes">{{'additionalUserIdClaimTypes' | i18n}}</label>
<input class="form-control" formControlName="additionalUserIdClaimTypes"
id="additionalUserIdClaimTypes">
</div>
<div class="form-group">
<label for="additionalEmailClaimTypes">{{'additionalEmailClaimTypes' | i18n}}</label>
<input class="form-control" formControlName="additionalEmailClaimTypes"
id="additionalEmailClaimTypes">
</div>
<div class="form-group">
<label for="additionalNameClaimTypes">{{'additionalNameClaimTypes' | i18n}}</label>
<input class="form-control" formControlName="additionalNameClaimTypes"
id="additionalNameClaimTypes">
</div>
<div class="form-group">
<label for="acrValues">{{'acrValues' | i18n}}</label>
<input class="form-control" formControlName="acrValues" id="acrValues">
</div>
<div class="form-group">
<label for="expectedReturnAcrValue">{{'expectedReturnAcrValue' | i18n}}</label>
<input class="form-control" formControlName="expectedReturnAcrValue" id="expectedReturnAcrValue">
</div>
</div>
</div>
<div *ngIf="data.value.configType == 2">
<!-- SAML2 SP -->
<div class="config-section">
<h2>{{'samlSpConfig' | i18n}}</h2>
<div class="form-group">
<label>{{'spEntityId' | i18n}}</label>
<div class="input-group">
<input class="form-control" readonly [value]="spEntityId" >
<div class="input-group-append">
<button type="button" class="btn btn-outline-secondary"
appA11yTitle="{{'copyValue' | i18n}}"
(click)="copy(spEntityId)">
<i class="fa fa-lg fa-clone" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
<div class="form-group">
<label>{{'spMetadataUrl' | i18n}}</label>
<div class="input-group">
<input class="form-control" readonly [value]="spMetadataUrl">
<div class="input-group-append">
<button type="button" class="btn btn-outline-secondary"
appA11yTitle="{{'launch' | i18n}}"
(click)="launchUri(spMetadataUrl)">
<i class="fa fa-lg fa-external-link" aria-hidden="true"></i>
</button>
<button type="button" class="btn btn-outline-secondary"
appA11yTitle="{{'copyValue' | i18n}}"
(click)="copy(spMetadataUrl)">
<i class="fa fa-lg fa-clone" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
<div class="form-group">
<label>{{'spAcsUrl' | i18n}}</label>
<div class="input-group">
<input class="form-control" readonly [value]="spAcsUrl">
<div class="input-group-append">
<button type="button" class="btn btn-outline-secondary"
appA11yTitle="{{'copyValue' | i18n}}"
(click)="copy(spAcsUrl)">
<i class="fa fa-lg fa-clone" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
<div class="form-group">
<label for="spNameIdFormat">{{'spNameIdFormat' | i18n}}</label>
<select class="form-control" formControlName="spNameIdFormat" id="spNameIdFormat">
<option value="0">Not Configured</option>
<option value="1">Unspecified</option>
<option value="2">Email Address</option>
<option value="3">X.509 Subject Name</option>
<option value="4">Windows Domain Qualified Name</option>
<option value="5">Kerberos Principal Name</option>
<option value="6">Entity Identifier</option>
<option value="7">Persistent</option>
<option value="8">Transient</option>
</select>
</div>
<div class="form-group">
<label for="spOutboundSigningAlgorithm">{{'spOutboundSigningAlgorithm' | i18n}}</label>
<select class="form-control" formControlName="spOutboundSigningAlgorithm"
id="spOutboundSigningAlgorithm">
<option *ngFor="let o of samlSigningAlgorithms" [ngValue]="o">{{o}}</option>
</select>
</div>
<div class="form-group">
<label for="spSigningBehavior">{{'spSigningBehavior' | i18n}}</label>
<select class="form-control" formControlName="spSigningBehavior" id="spSigningBehavior">
<option value="0">If IdP Wants Authn Requests Signed</option>
<option value="1">Always</option>
<option value="3">Never</option>
</select>
</div>
<div class="form-group">
<label for="spMinIncomingSigningAlgorithm">{{'spMinIncomingSigningAlgorithm' | i18n}}</label>
<select class="form-control" formControlName="spMinIncomingSigningAlgorithm"
id="spMinIncomingSigningAlgorithm">
<option *ngFor="let o of samlSigningAlgorithms" [ngValue]="o">{{o}}</option>
</select>
</div>
<div class="form-group">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="spWantAssertionsSigned"
formControlName="spWantAssertionsSigned">
<label class="form-check-label" for="spWantAssertionsSigned">
{{'spWantAssertionsSigned' | i18n}}
</label>
</div>
</div>
<div class="form-group">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="spValidateCertificates"
formControlName="spValidateCertificates">
<label class="form-check-label" for="spValidateCertificates">
{{'spValidateCertificates' | i18n}}
</label>
</div>
</div>
</div>
<!-- SAML2 IDP -->
<div class="config-section">
<h2>{{'samlIdpConfig' | i18n}}</h2>
<div class="form-group">
<label for="idpEntityId">{{'idpEntityId' | i18n}}</label>
<input class="form-control" formControlName="idpEntityId" id="idpEntityId">
</div>
<div class="form-group">
<label for="idpBindingType">{{'idpBindingType' | i18n}}</label>
<select class="form-control" formControlName="idpBindingType" id="idpBindingType">
<option value="1">Redirect</option>
<option value="2">HTTP POST</option>
<option value="4">Artifact</option>
</select>
</div>
<div class="form-group">
<label for="idpSingleSignOnServiceUrl">{{'idpSingleSignOnServiceUrl' | i18n}}</label>
<input class="form-control" formControlName="idpSingleSignOnServiceUrl" id="idpSingleSignOnServiceUrl">
</div>
<div class="form-group">
<label for="idpSingleLogoutServiceUrl">{{'idpSingleLogoutServiceUrl' | i18n}}</label>
<input class="form-control" formControlName="idpSingleLogoutServiceUrl" id="idpSingleLogoutServiceUrl">
</div>
<div class="form-group">
<label for="idpArtifactResolutionServiceUrl">{{'idpArtifactResolutionServiceUrl' | i18n}}</label>
<input class="form-control" formControlName="idpArtifactResolutionServiceUrl"
id="idpArtifactResolutionServiceUrl">
</div>
<div class="form-group">
<label for="idpX509PublicCert">{{'idpX509PublicCert' | i18n}}</label>
<textarea formControlName="idpX509PublicCert" class="form-control form-control-sm text-monospace"
rows="6" id="idpX509PublicCert"></textarea>
</div>
<div class="form-group">
<label for="idpOutboundSigningAlgorithm">{{'idpOutboundSigningAlgorithm' | i18n}}</label>
<select class="form-control" formControlName="idpOutboundSigningAlgorithm"
id="idpOutboundSigningAlgorithm">
<option *ngFor="let o of samlSigningAlgorithms" [ngValue]="o">{{o}}</option>
</select>
</div>
<div class="form-group">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="idpAllowUnsolicitedAuthnResponse"
formControlName="idpAllowUnsolicitedAuthnResponse">
<label class="form-check-label" for="idpAllowUnsolicitedAuthnResponse">
{{'idpAllowUnsolicitedAuthnResponse' | i18n}}
</label>
</div>
</div>
<div class="form-group">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="idpDisableOutboundLogoutRequests"
formControlName="idpDisableOutboundLogoutRequests">
<label class="form-check-label" for="idpDisableOutboundLogoutRequests">
{{'idpDisableOutboundLogoutRequests' | i18n}}
</label>
</div>
</div>
<div class="form-group">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="idpWantAuthnRequestsSigned"
formControlName="idpWantAuthnRequestsSigned">
<label class="form-check-label" for="idpWantAuthnRequestsSigned">
{{'idpWantAuthnRequestsSigned' | i18n}}
</label>
</div>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary btn-submit" [disabled]="form.loading">
<i class="fa fa-spinner fa-spin" title="{{'loading' | i18n}}" aria-hidden="true"></i>
<span>{{'save' | i18n}}</span>
</button>
</form>