mirror of
https://github.com/bitwarden/browser
synced 2025-12-17 08:43:33 +00:00
Remove Business Portal and add SSO configuration (#1213)
This commit is contained in:
@@ -10,6 +10,7 @@ import { AppComponent } from './app.component';
|
||||
import { OssRoutingModule } from './oss-routing.module';
|
||||
import { OssModule } from './oss.module';
|
||||
import { ServicesModule } from './services/services.module';
|
||||
import { WildcardRoutingModule } from './wildcard-routing.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@@ -21,6 +22,7 @@ import { ServicesModule } from './services/services.module';
|
||||
InfiniteScrollModule,
|
||||
DragDropModule,
|
||||
OssRoutingModule,
|
||||
WildcardRoutingModule, // Needs to be last to catch all non-existing routes
|
||||
],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
|
||||
@@ -48,15 +48,6 @@
|
||||
</li>
|
||||
</ul>
|
||||
</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>
|
||||
<router-outlet></router-outlet>
|
||||
|
||||
@@ -9,9 +9,6 @@ import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
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 { Organization } from 'jslib-common/models/domain/organization';
|
||||
@@ -26,16 +23,11 @@ export class OrganizationLayoutComponent implements OnInit, OnDestroy {
|
||||
organization: Organization;
|
||||
businessTokenPromise: Promise<any>;
|
||||
private organizationId: string;
|
||||
private businessUrl: string;
|
||||
|
||||
constructor(private route: ActivatedRoute, private userService: UserService,
|
||||
private broadcasterService: BroadcasterService, private ngZone: NgZone,
|
||||
private apiService: ApiService, private platformUtilsService: PlatformUtilsService,
|
||||
private environmentService: EnvironmentService) { }
|
||||
private broadcasterService: BroadcasterService, private ngZone: NgZone) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.businessUrl = this.environmentService.getEnterpriseUrl();
|
||||
|
||||
document.body.classList.remove('layout_frontend');
|
||||
this.route.params.subscribe(async params => {
|
||||
this.organizationId = params.organizationId;
|
||||
@@ -60,22 +52,6 @@ export class OrganizationLayoutComponent implements OnInit, OnDestroy {
|
||||
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() {
|
||||
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;
|
||||
}
|
||||
|
||||
get showBusinessPortalButton(): boolean {
|
||||
return this.organization.useBusinessPortal && this.organization.canAccessBusinessPortal;
|
||||
}
|
||||
|
||||
get toolsRoute(): string {
|
||||
return this.organization.canAccessImportExport ?
|
||||
'tools/import' :
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
*ngIf="organization.canManagePolicies && accessPolicies">
|
||||
{{'policies' | i18n}}
|
||||
</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"
|
||||
*ngIf="organization.canAccessEventLogs && accessEvents">
|
||||
{{'eventLogs' | i18n}}
|
||||
|
||||
@@ -14,16 +14,18 @@ import { Organization } from 'jslib-common/models/domain/organization';
|
||||
})
|
||||
export class ManageComponent implements OnInit {
|
||||
organization: Organization;
|
||||
accessPolicies = false;
|
||||
accessGroups = false;
|
||||
accessEvents = false;
|
||||
accessPolicies: boolean = false;
|
||||
accessGroups: boolean = false;
|
||||
accessEvents: boolean = false;
|
||||
accessSso: boolean = false;
|
||||
|
||||
constructor(private route: ActivatedRoute, private userService: UserService) { }
|
||||
constructor(private route: ActivatedRoute, private userService: UserService) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.route.parent.params.subscribe(async params => {
|
||||
this.organization = await this.userService.getOrganization(params.organizationId);
|
||||
this.accessPolicies = this.organization.usePolicies;
|
||||
this.accessSso = this.organization.useSso;
|
||||
this.accessEvents = this.organization.useEvents;
|
||||
this.accessGroups = this.organization.useGroups;
|
||||
});
|
||||
|
||||
@@ -12,9 +12,6 @@ import {
|
||||
import { PolicyType } from 'jslib-common/enums/policyType';
|
||||
|
||||
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 { 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 { PolicyListService } from 'src/app/services/policy-list.service';
|
||||
import { PolicyListService } from '../../services/policy-list.service';
|
||||
import { BasePolicy } from '../policies/base-policy.component';
|
||||
|
||||
@Component({
|
||||
@@ -40,19 +37,12 @@ export class PoliciesComponent implements OnInit {
|
||||
policies: BasePolicy[];
|
||||
organization: Organization;
|
||||
|
||||
// Remove when removing deprecation warning
|
||||
enterpriseTokenPromise: Promise<any>;
|
||||
|
||||
private enterpriseUrl: string;
|
||||
|
||||
private orgPolicies: PolicyResponse[];
|
||||
private policiesEnabledMap: Map<PolicyType, boolean> = new Map<PolicyType, boolean>();
|
||||
|
||||
constructor(private apiService: ApiService, private route: ActivatedRoute,
|
||||
private i18nService: I18nService, private modalService: ModalService,
|
||||
private platformUtilsService: PlatformUtilsService, private userService: UserService,
|
||||
private policyListService: PolicyListService, private router: Router,
|
||||
private environmentService: EnvironmentService) { }
|
||||
private modalService: ModalService, private userService: UserService,
|
||||
private policyListService: PolicyListService, private router: Router) { }
|
||||
|
||||
async ngOnInit() {
|
||||
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() {
|
||||
@@ -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">
|
||||
<label class="font-weight-bold mb-0">Admin Permissions</label>
|
||||
<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-check mt-1 form-check-block">
|
||||
<input class="form-check-input" type="checkbox" name="accessEventLogs"
|
||||
|
||||
@@ -216,7 +216,7 @@ export class OrganizationSubscriptionComponent implements OnInit {
|
||||
}
|
||||
|
||||
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());
|
||||
} else if (this.sub.maxAutoscaleSeats == null) {
|
||||
return this.i18nService.t('subscriptionUserSeatsUnlimitedAutoscale');
|
||||
|
||||
@@ -443,7 +443,6 @@ const routes: Routes = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{ path: '**', redirectTo: '' },
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
||||
@@ -18,7 +18,6 @@ export class OrganizationTypeGuardService implements CanActivate {
|
||||
const permissions = route.data == null ? null : route.data.permissions as Permissions[];
|
||||
|
||||
if (
|
||||
(permissions.indexOf(Permissions.AccessBusinessPortal) !== -1 && org.canAccessBusinessPortal) ||
|
||||
(permissions.indexOf(Permissions.AccessEventLogs) !== -1 && org.canAccessEventLogs) ||
|
||||
(permissions.indexOf(Permissions.AccessImportExport) !== -1 && org.canAccessImportExport) ||
|
||||
(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.ManagePolicies) !== -1 && org.canManagePolicies) ||
|
||||
(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;
|
||||
}
|
||||
|
||||
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": {
|
||||
"message": "Policies"
|
||||
},
|
||||
"singleSignOn": {
|
||||
"message": "Single Sign-On"
|
||||
},
|
||||
"editPolicy": {
|
||||
"message": "Edit Policy"
|
||||
},
|
||||
@@ -3396,10 +3399,6 @@
|
||||
"ssoHandOff": {
|
||||
"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": {
|
||||
"message": "All Teams features, plus:"
|
||||
},
|
||||
@@ -3809,9 +3808,6 @@
|
||||
"permissions": {
|
||||
"message": "Permissions"
|
||||
},
|
||||
"accessBusinessPortal": {
|
||||
"message": "Access Business Portal"
|
||||
},
|
||||
"accessEventLogs": {
|
||||
"message": "Access Event Logs"
|
||||
},
|
||||
@@ -4329,5 +4325,122 @@
|
||||
},
|
||||
"personalVaultExportPolicyInEffect": {
|
||||
"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."
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user