mirror of
https://github.com/bitwarden/browser.git
synced 2025-04-16 20:27:03 +02:00
Remove Business Portal and add SSO configuration (#1213)
This commit is contained in:
parent
4ff38c7148
commit
3eda0aa2cd
README.mdwebpack.config.js
bitwarden_license/src/app
app.module.ts
organizations
config
jslibsrc
app
app.module.tsoss-routing.module.ts
layouts
organizations
manage
settings
services
wildcard-routing.module.tslocales/en
@ -52,7 +52,6 @@ You can also manually adjusting your API endpoint settings by adding `config/loc
|
|||||||
"proxyIdentity": "http://your-identity-url",
|
"proxyIdentity": "http://your-identity-url",
|
||||||
"proxyEvents": "http://your-events-url",
|
"proxyEvents": "http://your-events-url",
|
||||||
"proxyNotifications": "http://your-notifications-url",
|
"proxyNotifications": "http://your-notifications-url",
|
||||||
"proxyPortal": "http://your-portal-url",
|
|
||||||
"allowedHosts": ["hostnames-to-allow-in-webpack"],
|
"allowedHosts": ["hostnames-to-allow-in-webpack"],
|
||||||
"urls": {
|
"urls": {
|
||||||
|
|
||||||
|
@ -9,13 +9,14 @@ import { RouterModule } from '@angular/router';
|
|||||||
|
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
|
import { OrganizationsModule } from './organizations/organizations.module';
|
||||||
import { DisablePersonalVaultExportPolicyComponent } from './policies/disable-personal-vault-export.component';
|
import { DisablePersonalVaultExportPolicyComponent } from './policies/disable-personal-vault-export.component';
|
||||||
import { MaximumVaultTimeoutPolicyComponent } from './policies/maximum-vault-timeout.component';
|
import { MaximumVaultTimeoutPolicyComponent } from './policies/maximum-vault-timeout.component';
|
||||||
|
|
||||||
import { OssRoutingModule } from 'src/app/oss-routing.module';
|
import { OssRoutingModule } from 'src/app/oss-routing.module';
|
||||||
import { OssModule } from 'src/app/oss.module';
|
import { OssModule } from 'src/app/oss.module';
|
||||||
import { ServicesModule } from 'src/app/services/services.module';
|
import { ServicesModule } from 'src/app/services/services.module';
|
||||||
|
import { WildcardRoutingModule } from 'src/app/wildcard-routing.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@ -29,7 +30,9 @@ import { ServicesModule } from 'src/app/services/services.module';
|
|||||||
DragDropModule,
|
DragDropModule,
|
||||||
AppRoutingModule,
|
AppRoutingModule,
|
||||||
OssRoutingModule,
|
OssRoutingModule,
|
||||||
|
OrganizationsModule,
|
||||||
RouterModule,
|
RouterModule,
|
||||||
|
WildcardRoutingModule, // Needs to be last to catch all non-existing routes
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
|
@ -0,0 +1,284 @@
|
|||||||
|
<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">
|
||||||
|
<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">{{'enabled' | i18n}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<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(data.value.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(data.value.signedOutCallbackPath)">
|
||||||
|
<i class="fa fa-lg fa-clone" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{'authority' | i18n}}</label>
|
||||||
|
<input class="form-control" formControlName="authority">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{'clientId' | i18n}}</label>
|
||||||
|
<input class="form-control" formControlName="clientId">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{'clientSecret' | i18n}}</label>
|
||||||
|
<input class="form-control" formControlName="clientSecret">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{'metadataAddress' | i18n}}</label>
|
||||||
|
<input class="form-control" formControlName="metadataAddress">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{'oidcRedirectBehavior' | i18n}}</label>
|
||||||
|
<select class="form-control" formControlName="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>{{'additionalScopes' | i18n}}</label>
|
||||||
|
<input class="form-control" formControlName="additionalScopes">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{'additionalUserIdClaimTypes' | i18n}}</label>
|
||||||
|
<input class="form-control" formControlName="additionalUserIdClaimTypes">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{'additionalEmailClaimTypes' | i18n}}</label>
|
||||||
|
<input class="form-control" formControlName="additionalEmailClaimTypes">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{'additionalNameClaimTypes' | i18n}}</label>
|
||||||
|
<input class="form-control" formControlName="additionalNameClaimTypes">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{'acrValues' | i18n}}</label>
|
||||||
|
<input class="form-control" formControlName="acrValues">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{'expectedReturnAcrValue' | i18n}}</label>
|
||||||
|
<input class="form-control" formControlName="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(data.value.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="{{'copyValue' | i18n}}"
|
||||||
|
(click)="launchUri(data.value.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(data.value.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(data.value.spAcsUrl)">
|
||||||
|
<i class="fa fa-lg fa-clone" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{'spNameIdFormat' | i18n}}</label>
|
||||||
|
<select class="form-control" formControlName="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>{{'spOutboundSigningAlgorithm' | i18n}}</label>
|
||||||
|
<select class="form-control" formControlName="spOutboundSigningAlgorithm">
|
||||||
|
<option *ngFor="let o of samlSigningAlgorithms" [ngValue]="o">{{o}}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{'spSigningBehavior' | i18n}}</label>
|
||||||
|
<select class="form-control" formControlName="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>{{'spMinIncomingSigningAlgorithm' | i18n}}</label>
|
||||||
|
<select class="form-control" formControlName="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>{{'idpEntityId' | i18n}}</label>
|
||||||
|
<input class="form-control" formControlName="idpEntityId">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{'idpBindingType' | i18n}}</label>
|
||||||
|
<select class="form-control" formControlName="idpBindingType">
|
||||||
|
<option value="1">Redirect</option>
|
||||||
|
<option value="2">HTTP POST</option>
|
||||||
|
<option value="4">Artifact</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{'idpSingleSignOnServiceUrl' | i18n}}</label>
|
||||||
|
<input class="form-control" formControlName="idpSingleSignOnServiceUrl">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{'idpSingleLogoutServiceUrl' | i18n}}</label>
|
||||||
|
<input class="form-control" formControlName="idpSingleLogoutServiceUrl">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{'idpArtifactResolutionServiceUrl' | i18n}}</label>
|
||||||
|
<input class="form-control" formControlName="idpArtifactResolutionServiceUrl">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{'idpX509PublicCert' | i18n}}</label>
|
||||||
|
<textarea formControlName="idpX509PublicCert" class="form-control form-control-sm text-monospace" rows="6"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{'idpOutboundSigningAlgorithm' | i18n}}</label>
|
||||||
|
<select class="form-control" formControlName="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>
|
121
bitwarden_license/src/app/organizations/manage/sso.component.ts
Normal file
121
bitwarden_license/src/app/organizations/manage/sso.component.ts
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
import {
|
||||||
|
Component,
|
||||||
|
OnInit,
|
||||||
|
} from '@angular/core';
|
||||||
|
import { FormBuilder } from '@angular/forms';
|
||||||
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
|
||||||
|
import { ApiService } from 'jslib-common/abstractions/api.service';
|
||||||
|
import { I18nService } from 'jslib-common/abstractions/i18n.service';
|
||||||
|
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
|
||||||
|
import { OrganizationSsoRequest } from 'jslib-common/models/request/organization/organizationSsoRequest';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-org-manage-sso',
|
||||||
|
templateUrl: 'sso.component.html',
|
||||||
|
})
|
||||||
|
export class SsoComponent implements OnInit {
|
||||||
|
|
||||||
|
samlSigningAlgorithms = [
|
||||||
|
'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
|
||||||
|
'http://www.w3.org/2000/09/xmldsig#rsa-sha384',
|
||||||
|
'http://www.w3.org/2000/09/xmldsig#rsa-sha512',
|
||||||
|
'http://www.w3.org/2000/09/xmldsig#rsa-sha1',
|
||||||
|
];
|
||||||
|
|
||||||
|
loading = true;
|
||||||
|
organizationId: string;
|
||||||
|
formPromise: Promise<any>;
|
||||||
|
|
||||||
|
callbackPath: string;
|
||||||
|
signedOutCallbackPath: string;
|
||||||
|
spEntityId: string;
|
||||||
|
spMetadataUrl: string;
|
||||||
|
spAcsUrl: string;
|
||||||
|
|
||||||
|
enabled = this.fb.control(false);
|
||||||
|
data = this.fb.group({
|
||||||
|
configType: [],
|
||||||
|
|
||||||
|
// OpenId
|
||||||
|
authority: [],
|
||||||
|
clientId: [],
|
||||||
|
clientSecret: [],
|
||||||
|
metadataAddress: [],
|
||||||
|
redirectBehavior: [],
|
||||||
|
getClaimsFromUserInfoEndpoint: [],
|
||||||
|
additionalScopes: [],
|
||||||
|
additionalUserIdClaimTypes: [],
|
||||||
|
additionalEmailClaimTypes: [],
|
||||||
|
additionalNameClaimTypes: [],
|
||||||
|
acrValues: [],
|
||||||
|
expectedReturnAcrValue: [],
|
||||||
|
|
||||||
|
// SAML
|
||||||
|
spNameIdFormat: [],
|
||||||
|
spOutboundSigningAlgorithm: [],
|
||||||
|
spSigningBehavior: [],
|
||||||
|
spMinIncomingSigningAlgorithm: [],
|
||||||
|
spWantAssertionsSigned: [],
|
||||||
|
spValidateCertificates: [],
|
||||||
|
|
||||||
|
idpEntityId: [],
|
||||||
|
idpBindingType: [],
|
||||||
|
idpSingleSignOnServiceUrl: [],
|
||||||
|
idpSingleLogoutServiceUrl: [],
|
||||||
|
idpArtifactResolutionServiceUrl: [],
|
||||||
|
idpX509PublicCert: [],
|
||||||
|
idpOutboundSigningAlgorithm: [],
|
||||||
|
idpAllowUnsolicitedAuthnResponse: [],
|
||||||
|
idpDisableOutboundLogoutRequests: [],
|
||||||
|
idpWantAuthnRequestsSigned: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
constructor(private fb: FormBuilder, private route: ActivatedRoute, private apiService: ApiService,
|
||||||
|
private platformUtilsService: PlatformUtilsService, private i18nService: I18nService) { }
|
||||||
|
|
||||||
|
async ngOnInit() {
|
||||||
|
this.route.parent.parent.params.subscribe(async params => {
|
||||||
|
this.organizationId = params.organizationId;
|
||||||
|
await this.load();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async load() {
|
||||||
|
const ssoSettings = await this.apiService.getOrganizationSso(this.organizationId);
|
||||||
|
|
||||||
|
this.data.patchValue(ssoSettings.data);
|
||||||
|
this.enabled.setValue(ssoSettings.enabled);
|
||||||
|
|
||||||
|
this.callbackPath = ssoSettings.urls.callbackPath;
|
||||||
|
this.signedOutCallbackPath = ssoSettings.urls.signedOutCallbackPath;
|
||||||
|
this.spEntityId = ssoSettings.urls.spEntityId;
|
||||||
|
this.spMetadataUrl = ssoSettings.urls.spMetadataUrl;
|
||||||
|
this.spAcsUrl = ssoSettings.urls.spAcsUrl;
|
||||||
|
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
copy(value: string) {
|
||||||
|
this.platformUtilsService.copyToClipboard(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
launchUri(url: string) {
|
||||||
|
this.platformUtilsService.launchUri(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
async submit() {
|
||||||
|
const request = new OrganizationSsoRequest();
|
||||||
|
request.enabled = this.enabled.value;
|
||||||
|
request.data = this.data.value;
|
||||||
|
|
||||||
|
this.formPromise = this.apiService.postOrganizationSso(this.organizationId, request);
|
||||||
|
|
||||||
|
const response = await this.formPromise;
|
||||||
|
this.data.patchValue(response.data);
|
||||||
|
this.enabled.setValue(response.enabled);
|
||||||
|
|
||||||
|
this.formPromise = null;
|
||||||
|
this.platformUtilsService.showToast('success', null, this.i18nService.t('ssoSettingsSaved'));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
|
||||||
|
import { AuthGuardService } from 'jslib-angular/services/auth-guard.service';
|
||||||
|
|
||||||
|
import { Permissions } from 'jslib-common/enums/permissions';
|
||||||
|
|
||||||
|
import { OrganizationLayoutComponent } from 'src/app/layouts/organization-layout.component';
|
||||||
|
import { ManageComponent } from 'src/app/organizations/manage/manage.component';
|
||||||
|
import { OrganizationGuardService } from 'src/app/services/organization-guard.service';
|
||||||
|
import { OrganizationTypeGuardService } from 'src/app/services/organization-type-guard.service';
|
||||||
|
|
||||||
|
import { SsoComponent } from './manage/sso.component';
|
||||||
|
|
||||||
|
const routes: Routes = [
|
||||||
|
{
|
||||||
|
path: 'organizations/:organizationId',
|
||||||
|
component: OrganizationLayoutComponent,
|
||||||
|
canActivate: [AuthGuardService, OrganizationGuardService],
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'manage',
|
||||||
|
component: ManageComponent,
|
||||||
|
canActivate: [OrganizationTypeGuardService],
|
||||||
|
data: {
|
||||||
|
permissions: [
|
||||||
|
Permissions.ManageAssignedCollections,
|
||||||
|
Permissions.ManageAllCollections,
|
||||||
|
Permissions.AccessEventLogs,
|
||||||
|
Permissions.ManageGroups,
|
||||||
|
Permissions.ManageUsers,
|
||||||
|
Permissions.ManagePolicies,
|
||||||
|
Permissions.ManageSso,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'sso',
|
||||||
|
component: SsoComponent,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [RouterModule.forChild(routes)],
|
||||||
|
exports: [RouterModule],
|
||||||
|
})
|
||||||
|
export class OrganizationsRoutingModule { }
|
@ -0,0 +1,22 @@
|
|||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
|
|
||||||
|
import { OssModule } from 'src/app/oss.module';
|
||||||
|
|
||||||
|
import { SsoComponent } from './manage/sso.component';
|
||||||
|
import { OrganizationsRoutingModule } from './organizations-routing.module';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
FormsModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
OssModule,
|
||||||
|
OrganizationsRoutingModule,
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
SsoComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class OrganizationsModule {}
|
@ -1,8 +1,7 @@
|
|||||||
{
|
{
|
||||||
"urls": {
|
"urls": {
|
||||||
"icons": "https://icons.bitwarden.net",
|
"icons": "https://icons.bitwarden.net",
|
||||||
"notifications": "https://notifications.bitwarden.com",
|
"notifications": "https://notifications.bitwarden.com"
|
||||||
"enterprise": "https://portal.bitwarden.com"
|
|
||||||
},
|
},
|
||||||
"stripeKey": "pk_live_bpN0P37nMxrMQkcaHXtAybJk",
|
"stripeKey": "pk_live_bpN0P37nMxrMQkcaHXtAybJk",
|
||||||
"braintreeKey": "production_qfbsv8kc_njj2zjtyngtjmbjd",
|
"braintreeKey": "production_qfbsv8kc_njj2zjtyngtjmbjd",
|
||||||
|
@ -3,10 +3,8 @@
|
|||||||
"proxyIdentity": "http://localhost:33656",
|
"proxyIdentity": "http://localhost:33656",
|
||||||
"proxyEvents": "http://localhost:46273",
|
"proxyEvents": "http://localhost:46273",
|
||||||
"proxyNotifications": "http://localhost:61840",
|
"proxyNotifications": "http://localhost:61840",
|
||||||
"proxyEnterprise": "http://localhost:52313",
|
|
||||||
"allowedHosts": [],
|
"allowedHosts": [],
|
||||||
"urls": {
|
"urls": {
|
||||||
"notifications": "http://localhost:61840",
|
"notifications": "http://localhost:61840"
|
||||||
"enterprise": "http://localhost:52313"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
"urls": {
|
"urls": {
|
||||||
"icons": "https://icons.qa.bitwarden.pw",
|
"icons": "https://icons.qa.bitwarden.pw",
|
||||||
"notifications": "https://notifications.qa.bitwarden.pw",
|
"notifications": "https://notifications.qa.bitwarden.pw"
|
||||||
"enterprise": "https://portal.qa.bitwarden.pw"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
jslib
2
jslib
@ -1 +1 @@
|
|||||||
Subproject commit 91c5393ae7a84e9f4d90391d072cae56e7a3ff41
|
Subproject commit bfa9a1e1bc05fe96c121eb4709729e85dfb3b008
|
@ -10,6 +10,7 @@ import { AppComponent } from './app.component';
|
|||||||
import { OssRoutingModule } from './oss-routing.module';
|
import { OssRoutingModule } from './oss-routing.module';
|
||||||
import { OssModule } from './oss.module';
|
import { OssModule } from './oss.module';
|
||||||
import { ServicesModule } from './services/services.module';
|
import { ServicesModule } from './services/services.module';
|
||||||
|
import { WildcardRoutingModule } from './wildcard-routing.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@ -21,6 +22,7 @@ import { ServicesModule } from './services/services.module';
|
|||||||
InfiniteScrollModule,
|
InfiniteScrollModule,
|
||||||
DragDropModule,
|
DragDropModule,
|
||||||
OssRoutingModule,
|
OssRoutingModule,
|
||||||
|
WildcardRoutingModule, // Needs to be last to catch all non-existing routes
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
|
@ -48,15 +48,6 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-auto d-flex align-items-center">
|
|
||||||
<button class="btn btn-primary" (click)="goToBusinessPortal()" #businessBtn
|
|
||||||
[appApiAction]="businessTokenPromise" *ngIf="showBusinessPortalButton">
|
|
||||||
<i class="fa fa-bank fa-fw" [hidden]="businessBtn.loading" aria-hidden="true"></i>
|
|
||||||
<i class="fa fa-spinner fa-spin fa-fw" [hidden]="!businessBtn.loading" title="{{'loading' | i18n}}"
|
|
||||||
aria-hidden="true"></i>
|
|
||||||
{{'businessPortal' | i18n}} →
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
|
@ -9,9 +9,6 @@ import { ActivatedRoute } from '@angular/router';
|
|||||||
|
|
||||||
import { BroadcasterService } from 'jslib-angular/services/broadcaster.service';
|
import { BroadcasterService } from 'jslib-angular/services/broadcaster.service';
|
||||||
|
|
||||||
import { ApiService } from 'jslib-common/abstractions/api.service';
|
|
||||||
import { EnvironmentService } from 'jslib-common/abstractions/environment.service';
|
|
||||||
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
|
|
||||||
import { UserService } from 'jslib-common/abstractions/user.service';
|
import { UserService } from 'jslib-common/abstractions/user.service';
|
||||||
|
|
||||||
import { Organization } from 'jslib-common/models/domain/organization';
|
import { Organization } from 'jslib-common/models/domain/organization';
|
||||||
@ -26,16 +23,11 @@ export class OrganizationLayoutComponent implements OnInit, OnDestroy {
|
|||||||
organization: Organization;
|
organization: Organization;
|
||||||
businessTokenPromise: Promise<any>;
|
businessTokenPromise: Promise<any>;
|
||||||
private organizationId: string;
|
private organizationId: string;
|
||||||
private businessUrl: string;
|
|
||||||
|
|
||||||
constructor(private route: ActivatedRoute, private userService: UserService,
|
constructor(private route: ActivatedRoute, private userService: UserService,
|
||||||
private broadcasterService: BroadcasterService, private ngZone: NgZone,
|
private broadcasterService: BroadcasterService, private ngZone: NgZone) { }
|
||||||
private apiService: ApiService, private platformUtilsService: PlatformUtilsService,
|
|
||||||
private environmentService: EnvironmentService) { }
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.businessUrl = this.environmentService.getEnterpriseUrl();
|
|
||||||
|
|
||||||
document.body.classList.remove('layout_frontend');
|
document.body.classList.remove('layout_frontend');
|
||||||
this.route.params.subscribe(async params => {
|
this.route.params.subscribe(async params => {
|
||||||
this.organizationId = params.organizationId;
|
this.organizationId = params.organizationId;
|
||||||
@ -60,22 +52,6 @@ export class OrganizationLayoutComponent implements OnInit, OnDestroy {
|
|||||||
this.organization = await this.userService.getOrganization(this.organizationId);
|
this.organization = await this.userService.getOrganization(this.organizationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
async goToBusinessPortal() {
|
|
||||||
if (this.businessTokenPromise != null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
this.businessTokenPromise = this.apiService.getEnterprisePortalSignInToken();
|
|
||||||
const token = await this.businessTokenPromise;
|
|
||||||
if (token != null) {
|
|
||||||
const userId = await this.userService.getUserId();
|
|
||||||
this.platformUtilsService.launchUri(this.businessUrl + '/login?userId=' + userId +
|
|
||||||
'&token=' + (window as any).encodeURIComponent(token) + '&organizationId=' + this.organization.id);
|
|
||||||
}
|
|
||||||
} catch { }
|
|
||||||
this.businessTokenPromise = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
get showMenuBar() {
|
get showMenuBar() {
|
||||||
return this.showManageTab || this.showToolsTab || this.organization.isOwner;
|
return this.showManageTab || this.showToolsTab || this.organization.isOwner;
|
||||||
}
|
}
|
||||||
@ -93,10 +69,6 @@ export class OrganizationLayoutComponent implements OnInit, OnDestroy {
|
|||||||
return this.organization.canAccessImportExport || this.organization.canAccessReports;
|
return this.organization.canAccessImportExport || this.organization.canAccessReports;
|
||||||
}
|
}
|
||||||
|
|
||||||
get showBusinessPortalButton(): boolean {
|
|
||||||
return this.organization.useBusinessPortal && this.organization.canAccessBusinessPortal;
|
|
||||||
}
|
|
||||||
|
|
||||||
get toolsRoute(): string {
|
get toolsRoute(): string {
|
||||||
return this.organization.canAccessImportExport ?
|
return this.organization.canAccessImportExport ?
|
||||||
'tools/import' :
|
'tools/import' :
|
||||||
|
@ -20,6 +20,10 @@
|
|||||||
*ngIf="organization.canManagePolicies && accessPolicies">
|
*ngIf="organization.canManagePolicies && accessPolicies">
|
||||||
{{'policies' | i18n}}
|
{{'policies' | i18n}}
|
||||||
</a>
|
</a>
|
||||||
|
<a routerLink="sso" class="list-group-item" routerLinkActive="active"
|
||||||
|
*ngIf="organization.canManageSso && accessSso">
|
||||||
|
{{'singleSignOn' | i18n}}
|
||||||
|
</a>
|
||||||
<a routerLink="events" class="list-group-item" routerLinkActive="active"
|
<a routerLink="events" class="list-group-item" routerLinkActive="active"
|
||||||
*ngIf="organization.canAccessEventLogs && accessEvents">
|
*ngIf="organization.canAccessEventLogs && accessEvents">
|
||||||
{{'eventLogs' | i18n}}
|
{{'eventLogs' | i18n}}
|
||||||
|
@ -14,16 +14,18 @@ import { Organization } from 'jslib-common/models/domain/organization';
|
|||||||
})
|
})
|
||||||
export class ManageComponent implements OnInit {
|
export class ManageComponent implements OnInit {
|
||||||
organization: Organization;
|
organization: Organization;
|
||||||
accessPolicies = false;
|
accessPolicies: boolean = false;
|
||||||
accessGroups = false;
|
accessGroups: boolean = false;
|
||||||
accessEvents = false;
|
accessEvents: boolean = false;
|
||||||
|
accessSso: boolean = false;
|
||||||
|
|
||||||
constructor(private route: ActivatedRoute, private userService: UserService) { }
|
constructor(private route: ActivatedRoute, private userService: UserService) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.route.parent.params.subscribe(async params => {
|
this.route.parent.params.subscribe(async params => {
|
||||||
this.organization = await this.userService.getOrganization(params.organizationId);
|
this.organization = await this.userService.getOrganization(params.organizationId);
|
||||||
this.accessPolicies = this.organization.usePolicies;
|
this.accessPolicies = this.organization.usePolicies;
|
||||||
|
this.accessSso = this.organization.useSso;
|
||||||
this.accessEvents = this.organization.useEvents;
|
this.accessEvents = this.organization.useEvents;
|
||||||
this.accessGroups = this.organization.useGroups;
|
this.accessGroups = this.organization.useGroups;
|
||||||
});
|
});
|
||||||
|
@ -12,9 +12,6 @@ import {
|
|||||||
import { PolicyType } from 'jslib-common/enums/policyType';
|
import { PolicyType } from 'jslib-common/enums/policyType';
|
||||||
|
|
||||||
import { ApiService } from 'jslib-common/abstractions/api.service';
|
import { ApiService } from 'jslib-common/abstractions/api.service';
|
||||||
import { EnvironmentService } from 'jslib-common/abstractions/environment.service';
|
|
||||||
import { I18nService } from 'jslib-common/abstractions/i18n.service';
|
|
||||||
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
|
|
||||||
import { UserService } from 'jslib-common/abstractions/user.service';
|
import { UserService } from 'jslib-common/abstractions/user.service';
|
||||||
|
|
||||||
import { ModalService } from 'jslib-angular/services/modal.service';
|
import { ModalService } from 'jslib-angular/services/modal.service';
|
||||||
@ -25,7 +22,7 @@ import { Organization } from 'jslib-common/models/domain/organization';
|
|||||||
|
|
||||||
import { PolicyEditComponent } from './policy-edit.component';
|
import { PolicyEditComponent } from './policy-edit.component';
|
||||||
|
|
||||||
import { PolicyListService } from 'src/app/services/policy-list.service';
|
import { PolicyListService } from '../../services/policy-list.service';
|
||||||
import { BasePolicy } from '../policies/base-policy.component';
|
import { BasePolicy } from '../policies/base-policy.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -40,19 +37,12 @@ export class PoliciesComponent implements OnInit {
|
|||||||
policies: BasePolicy[];
|
policies: BasePolicy[];
|
||||||
organization: Organization;
|
organization: Organization;
|
||||||
|
|
||||||
// Remove when removing deprecation warning
|
|
||||||
enterpriseTokenPromise: Promise<any>;
|
|
||||||
|
|
||||||
private enterpriseUrl: string;
|
|
||||||
|
|
||||||
private orgPolicies: PolicyResponse[];
|
private orgPolicies: PolicyResponse[];
|
||||||
private policiesEnabledMap: Map<PolicyType, boolean> = new Map<PolicyType, boolean>();
|
private policiesEnabledMap: Map<PolicyType, boolean> = new Map<PolicyType, boolean>();
|
||||||
|
|
||||||
constructor(private apiService: ApiService, private route: ActivatedRoute,
|
constructor(private apiService: ApiService, private route: ActivatedRoute,
|
||||||
private i18nService: I18nService, private modalService: ModalService,
|
private modalService: ModalService, private userService: UserService,
|
||||||
private platformUtilsService: PlatformUtilsService, private userService: UserService,
|
private policyListService: PolicyListService, private router: Router) { }
|
||||||
private policyListService: PolicyListService, private router: Router,
|
|
||||||
private environmentService: EnvironmentService) { }
|
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.route.parent.parent.params.subscribe(async params => {
|
this.route.parent.parent.params.subscribe(async params => {
|
||||||
@ -89,9 +79,6 @@ export class PoliciesComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove when removing deprecation warning
|
|
||||||
this.enterpriseUrl = this.environmentService.getEnterpriseUrl();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async load() {
|
async load() {
|
||||||
@ -115,21 +102,4 @@ export class PoliciesComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove when removing deprecation warning
|
|
||||||
async goToEnterprisePortal() {
|
|
||||||
if (this.enterpriseTokenPromise != null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
this.enterpriseTokenPromise = this.apiService.getEnterprisePortalSignInToken();
|
|
||||||
const token = await this.enterpriseTokenPromise;
|
|
||||||
if (token != null) {
|
|
||||||
const userId = await this.userService.getUserId();
|
|
||||||
this.platformUtilsService.launchUri(this.enterpriseUrl + '/login?userId=' + userId +
|
|
||||||
'&token=' + (window as any).encodeURIComponent(token) + '&organizationId=' + this.organizationId);
|
|
||||||
}
|
|
||||||
} catch { }
|
|
||||||
this.enterpriseTokenPromise = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -102,15 +102,6 @@
|
|||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="font-weight-bold mb-0">Admin Permissions</label>
|
<label class="font-weight-bold mb-0">Admin Permissions</label>
|
||||||
<hr class="my-0 mr-2" />
|
<hr class="my-0 mr-2" />
|
||||||
<div class="form-group mb-0">
|
|
||||||
<div class="form-check mt-1 form-check-block">
|
|
||||||
<input class="form-check-input" type="checkbox" name="accessBusinessPortal"
|
|
||||||
id="accessBusinessPortal" [(ngModel)]="permissions.accessBusinessPortal">
|
|
||||||
<label class="form-check-label font-weight-normal" for="accessBusinessPortal">
|
|
||||||
{{'accessBusinessPortal' | i18n}}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group mb-0">
|
<div class="form-group mb-0">
|
||||||
<div class="form-check mt-1 form-check-block">
|
<div class="form-check mt-1 form-check-block">
|
||||||
<input class="form-check-input" type="checkbox" name="accessEventLogs"
|
<input class="form-check-input" type="checkbox" name="accessEventLogs"
|
||||||
|
@ -216,7 +216,7 @@ export class OrganizationSubscriptionComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get subscriptionDesc() {
|
get subscriptionDesc() {
|
||||||
if (this.sub.maxAutoscaleSeats == this.sub.seats && this.sub.seats != null) {
|
if (this.sub.maxAutoscaleSeats === this.sub.seats && this.sub.seats != null) {
|
||||||
return this.i18nService.t('subscriptionMaxReached', this.sub.seats.toString());
|
return this.i18nService.t('subscriptionMaxReached', this.sub.seats.toString());
|
||||||
} else if (this.sub.maxAutoscaleSeats == null) {
|
} else if (this.sub.maxAutoscaleSeats == null) {
|
||||||
return this.i18nService.t('subscriptionUserSeatsUnlimitedAutoscale');
|
return this.i18nService.t('subscriptionUserSeatsUnlimitedAutoscale');
|
||||||
|
@ -443,7 +443,6 @@ const routes: Routes = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{ path: '**', redirectTo: '' },
|
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
@ -18,7 +18,6 @@ export class OrganizationTypeGuardService implements CanActivate {
|
|||||||
const permissions = route.data == null ? null : route.data.permissions as Permissions[];
|
const permissions = route.data == null ? null : route.data.permissions as Permissions[];
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(permissions.indexOf(Permissions.AccessBusinessPortal) !== -1 && org.canAccessBusinessPortal) ||
|
|
||||||
(permissions.indexOf(Permissions.AccessEventLogs) !== -1 && org.canAccessEventLogs) ||
|
(permissions.indexOf(Permissions.AccessEventLogs) !== -1 && org.canAccessEventLogs) ||
|
||||||
(permissions.indexOf(Permissions.AccessImportExport) !== -1 && org.canAccessImportExport) ||
|
(permissions.indexOf(Permissions.AccessImportExport) !== -1 && org.canAccessImportExport) ||
|
||||||
(permissions.indexOf(Permissions.AccessReports) !== -1 && org.canAccessReports) ||
|
(permissions.indexOf(Permissions.AccessReports) !== -1 && org.canAccessReports) ||
|
||||||
@ -31,7 +30,8 @@ export class OrganizationTypeGuardService implements CanActivate {
|
|||||||
(permissions.indexOf(Permissions.ManageOrganization) !== -1 && org.isOwner) ||
|
(permissions.indexOf(Permissions.ManageOrganization) !== -1 && org.isOwner) ||
|
||||||
(permissions.indexOf(Permissions.ManagePolicies) !== -1 && org.canManagePolicies) ||
|
(permissions.indexOf(Permissions.ManagePolicies) !== -1 && org.canManagePolicies) ||
|
||||||
(permissions.indexOf(Permissions.ManageUsers) !== -1 && org.canManageUsers) ||
|
(permissions.indexOf(Permissions.ManageUsers) !== -1 && org.canManageUsers) ||
|
||||||
(permissions.indexOf(Permissions.ManageUsersPassword) !== -1 && org.canManageUsersPassword)
|
(permissions.indexOf(Permissions.ManageUsersPassword) !== -1 && org.canManageUsersPassword) ||
|
||||||
|
(permissions.indexOf(Permissions.ManageSso) !== -1 && org.canManageSso)
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
12
src/app/wildcard-routing.module.ts
Normal file
12
src/app/wildcard-routing.module.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
|
||||||
|
const routes: Routes = [
|
||||||
|
{ path: '**', redirectTo: '' },
|
||||||
|
];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [RouterModule.forChild(routes)],
|
||||||
|
exports: [RouterModule],
|
||||||
|
})
|
||||||
|
export class WildcardRoutingModule { }
|
@ -2154,6 +2154,9 @@
|
|||||||
"policies": {
|
"policies": {
|
||||||
"message": "Policies"
|
"message": "Policies"
|
||||||
},
|
},
|
||||||
|
"singleSignOn": {
|
||||||
|
"message": "Single Sign-On"
|
||||||
|
},
|
||||||
"editPolicy": {
|
"editPolicy": {
|
||||||
"message": "Edit Policy"
|
"message": "Edit Policy"
|
||||||
},
|
},
|
||||||
@ -3396,10 +3399,6 @@
|
|||||||
"ssoHandOff": {
|
"ssoHandOff": {
|
||||||
"message": "You may now close this tab and continue in the extension."
|
"message": "You may now close this tab and continue in the extension."
|
||||||
},
|
},
|
||||||
"businessPortal": {
|
|
||||||
"message": "Business Portal",
|
|
||||||
"description": "The web portal used by business organizations for configuring certain features."
|
|
||||||
},
|
|
||||||
"includeAllTeamsFeatures": {
|
"includeAllTeamsFeatures": {
|
||||||
"message": "All Teams features, plus:"
|
"message": "All Teams features, plus:"
|
||||||
},
|
},
|
||||||
@ -3809,9 +3808,6 @@
|
|||||||
"permissions": {
|
"permissions": {
|
||||||
"message": "Permissions"
|
"message": "Permissions"
|
||||||
},
|
},
|
||||||
"accessBusinessPortal": {
|
|
||||||
"message": "Access Business Portal"
|
|
||||||
},
|
|
||||||
"accessEventLogs": {
|
"accessEventLogs": {
|
||||||
"message": "Access Event Logs"
|
"message": "Access Event Logs"
|
||||||
},
|
},
|
||||||
@ -4329,5 +4325,122 @@
|
|||||||
},
|
},
|
||||||
"personalVaultExportPolicyInEffect": {
|
"personalVaultExportPolicyInEffect": {
|
||||||
"message": "One or more organization policies prevents you from exporting your personal vault."
|
"message": "One or more organization policies prevents you from exporting your personal vault."
|
||||||
|
},
|
||||||
|
"selectType": {
|
||||||
|
"message": "Select SSO Type"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"message": "Type"
|
||||||
|
},
|
||||||
|
"openIdConnectConfig": {
|
||||||
|
"message": "OpenID Connect Configuration"
|
||||||
|
},
|
||||||
|
"samlSpConfig": {
|
||||||
|
"message": "SAML Service Provider Configuration"
|
||||||
|
},
|
||||||
|
"samlIdpConfig": {
|
||||||
|
"message": "SAML Identity Provider Configuration"
|
||||||
|
},
|
||||||
|
"callbackPath": {
|
||||||
|
"message": "Callback Path"
|
||||||
|
},
|
||||||
|
"signedOutCallbackPath": {
|
||||||
|
"message": "Signed Out Callback Path"
|
||||||
|
},
|
||||||
|
"authority": {
|
||||||
|
"message": "Authority"
|
||||||
|
},
|
||||||
|
"clientId": {
|
||||||
|
"message": "Client ID"
|
||||||
|
},
|
||||||
|
"clientSecret": {
|
||||||
|
"message": "Client Secret"
|
||||||
|
},
|
||||||
|
"metadataAddress": {
|
||||||
|
"message": "Metadata Address"
|
||||||
|
},
|
||||||
|
"oidcRedirectBehavior": {
|
||||||
|
"message": "OIDC Redirect Behavior"
|
||||||
|
},
|
||||||
|
"getClaimsFromUserInfoEndpoint": {
|
||||||
|
"message": "Get Claims From User Info Endpoint"
|
||||||
|
},
|
||||||
|
"additionalScopes": {
|
||||||
|
"message": "Additional/Custom Scopes (comma delimited)"
|
||||||
|
},
|
||||||
|
"additionalUserIdClaimTypes": {
|
||||||
|
"message": "Additional/Custom User ID Claim Types (comma delimited)"
|
||||||
|
},
|
||||||
|
"additionalEmailClaimTypes": {
|
||||||
|
"message": "Additional/Custom Email Claim Types (comma delimited)"
|
||||||
|
},
|
||||||
|
"additionalNameClaimTypes": {
|
||||||
|
"message": "Additional/Custom Name Claim Types (comma delimited)"
|
||||||
|
},
|
||||||
|
"acrValues": {
|
||||||
|
"message": "Requested Authentication Context Class Reference values (acr_values)"
|
||||||
|
},
|
||||||
|
"expectedReturnAcrValue": {
|
||||||
|
"message": "Expected \"acr\" Claim Value In Response (acr validation)"
|
||||||
|
},
|
||||||
|
"spEntityId": {
|
||||||
|
"message": "SP Entity ID"
|
||||||
|
},
|
||||||
|
"spMetadataUrl": {
|
||||||
|
"message": "SAML 2.0 Metadata URL"
|
||||||
|
},
|
||||||
|
"spAcsUrl": {
|
||||||
|
"message": "Assertion Consumer Service (ACS) URL"
|
||||||
|
},
|
||||||
|
"spNameIdFormat": {
|
||||||
|
"message": "Name ID Format"
|
||||||
|
},
|
||||||
|
"spOutboundSigningAlgorithm": {
|
||||||
|
"message": "Outbound Signing Algorithm"
|
||||||
|
},
|
||||||
|
"spSigningBehavior": {
|
||||||
|
"message": "Signing Behavior"
|
||||||
|
},
|
||||||
|
"spMinIncomingSigningAlgorithm": {
|
||||||
|
"message": "Minimum Incoming Signing Algorithm"
|
||||||
|
},
|
||||||
|
"spWantAssertionsSigned": {
|
||||||
|
"message": "Want Assertions Signed"
|
||||||
|
},
|
||||||
|
"spValidateCertificates": {
|
||||||
|
"message": "Validate Certificates"
|
||||||
|
},
|
||||||
|
"idpEntityId": {
|
||||||
|
"message": "Entity ID"
|
||||||
|
},
|
||||||
|
"idpBindingType": {
|
||||||
|
"message": "Binding Type"
|
||||||
|
},
|
||||||
|
"idpSingleSignOnServiceUrl": {
|
||||||
|
"message": "Single Sign On Service URL"
|
||||||
|
},
|
||||||
|
"idpSingleLogoutServiceUrl": {
|
||||||
|
"message": "Single Log Out Service URL"
|
||||||
|
},
|
||||||
|
"idpArtifactResolutionServiceUrl": {
|
||||||
|
"message": "Artifact Resolution Service URL"
|
||||||
|
},
|
||||||
|
"idpX509PublicCert": {
|
||||||
|
"message": "X509 Public Certificate"
|
||||||
|
},
|
||||||
|
"idpOutboundSigningAlgorithm": {
|
||||||
|
"message": "Outbound Signing Algorithm"
|
||||||
|
},
|
||||||
|
"idpAllowUnsolicitedAuthnResponse": {
|
||||||
|
"message": "Allow Unsolicited Authentication Response"
|
||||||
|
},
|
||||||
|
"idpDisableOutboundLogoutRequests": {
|
||||||
|
"message": "Disable Outbound Logout Requests"
|
||||||
|
},
|
||||||
|
"idpWantAuthnRequestsSigned": {
|
||||||
|
"message": "Want Authentication Requests Signed"
|
||||||
|
},
|
||||||
|
"ssoSettingsSaved": {
|
||||||
|
"message": "Single Sign-On configuration was saved."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,12 +200,6 @@ const devServer = ENV !== 'development' ? {} : {
|
|||||||
secure: false,
|
secure: false,
|
||||||
changeOrigin: true
|
changeOrigin: true
|
||||||
},
|
},
|
||||||
'/portal': {
|
|
||||||
target: envConfig['proxyEnterprise'],
|
|
||||||
pathRewrite: {'^/portal' : ''},
|
|
||||||
secure: false,
|
|
||||||
changeOrigin: true
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
hot: false,
|
hot: false,
|
||||||
allowedHosts: envConfig['allowedHosts']
|
allowedHosts: envConfig['allowedHosts']
|
||||||
|
Loading…
Reference in New Issue
Block a user