1
0
mirror of https://github.com/bitwarden/browser synced 2026-01-08 11:33:28 +00:00

Merge branch 'master' into feature/org-admin-refresh

This commit is contained in:
Shane Melton
2022-09-28 11:48:53 -07:00
152 changed files with 1501 additions and 980 deletions

View File

@@ -1,9 +1,10 @@
import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
import { canAccessBillingTab } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PaymentMethodComponent } from "../../settings/payment-method.component";
import { OrganizationPermissionsGuard } from "../guards/org-permissions.guard";
import { canAccessBillingTab } from "../navigation-permissions";
import { OrgBillingHistoryViewComponent } from "./organization-billing-history-view.component";
import { OrganizationBillingTabComponent } from "./organization-billing-tab.component";

View File

@@ -7,8 +7,8 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/abstractions/log.service";
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/abstractions/organization/organization-api.service.abstraction";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { OrganizationApiKeyType } from "@bitwarden/common/enums/organizationApiKeyType";
import { OrganizationConnectionType } from "@bitwarden/common/enums/organizationConnectionType";
@@ -87,7 +87,7 @@ export class OrganizationSubscriptionComponent implements OnInit {
}
this.loading = true;
this.userOrg = await this.organizationService.get(this.organizationId);
this.userOrg = this.organizationService.get(this.organizationId);
if (this.userOrg.canManageBilling) {
this.sub = await this.organizationApiService.getSubscription(this.organizationId);
}

View File

@@ -7,7 +7,7 @@ import {
import { mock, MockProxy } from "jest-mock-extended";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { SyncService } from "@bitwarden/common/abstractions/sync/sync.service.abstraction";
import { OrganizationUserType } from "@bitwarden/common/enums/organizationUserType";
@@ -57,7 +57,7 @@ describe("Organization Permissions Guard", () => {
});
it("blocks navigation if organization does not exist", async () => {
organizationService.get.mockResolvedValue(null);
organizationService.get.mockReturnValue(null);
const actual = await organizationPermissionsGuard.canActivate(route, state);
@@ -66,7 +66,7 @@ describe("Organization Permissions Guard", () => {
it("permits navigation if no permissions are specified", async () => {
const org = orgFactory();
organizationService.get.calledWith(org.id).mockResolvedValue(org);
organizationService.get.calledWith(org.id).mockReturnValue(org);
const actual = await organizationPermissionsGuard.canActivate(route, state);
@@ -81,7 +81,7 @@ describe("Organization Permissions Guard", () => {
};
const org = orgFactory();
organizationService.get.calledWith(org.id).mockResolvedValue(org);
organizationService.get.calledWith(org.id).mockReturnValue(org);
const actual = await organizationPermissionsGuard.canActivate(route, state);
@@ -104,7 +104,7 @@ describe("Organization Permissions Guard", () => {
});
const org = orgFactory();
organizationService.get.calledWith(org.id).mockResolvedValue(org);
organizationService.get.calledWith(org.id).mockReturnValue(org);
const actual = await organizationPermissionsGuard.canActivate(route, state);
@@ -124,7 +124,7 @@ describe("Organization Permissions Guard", () => {
}),
});
const org = orgFactory();
organizationService.get.calledWith(org.id).mockResolvedValue(org);
organizationService.get.calledWith(org.id).mockReturnValue(org);
const actual = await organizationPermissionsGuard.canActivate(route, state);
@@ -141,7 +141,7 @@ describe("Organization Permissions Guard", () => {
type: OrganizationUserType.Admin,
enabled: false,
});
organizationService.get.calledWith(org.id).mockResolvedValue(org);
organizationService.get.calledWith(org.id).mockReturnValue(org);
const actual = await organizationPermissionsGuard.canActivate(route, state);
@@ -153,7 +153,7 @@ describe("Organization Permissions Guard", () => {
type: OrganizationUserType.Owner,
enabled: false,
});
organizationService.get.calledWith(org.id).mockResolvedValue(org);
organizationService.get.calledWith(org.id).mockReturnValue(org);
const actual = await organizationPermissionsGuard.canActivate(route, state);

View File

@@ -2,13 +2,14 @@ import { Injectable } from "@angular/core";
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from "@angular/router";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import {
canAccessOrgAdmin,
OrganizationService,
} from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { SyncService } from "@bitwarden/common/abstractions/sync/sync.service.abstraction";
import { Organization } from "@bitwarden/common/models/domain/organization";
import { canAccessOrgAdmin } from "../navigation-permissions";
@Injectable({
providedIn: "root",
})
@@ -27,7 +28,7 @@ export class OrganizationPermissionsGuard implements CanActivate {
await this.syncService.fullSync(false);
}
const org = await this.organizationService.get(route.params.organizationId);
const org = this.organizationService.get(route.params.organizationId);
if (org == null) {
return this.router.createUrlTree(["/"]);
}

View File

@@ -1,5 +1,5 @@
<app-navbar></app-navbar>
<div class="org-nav !tw-h-32" *ngIf="organization">
<div class="org-nav !tw-h-32" *ngIf="organization$ | async as organization">
<div class="container d-flex">
<div class="d-flex flex-column">
<app-organization-switcher
@@ -8,13 +8,21 @@
></app-organization-switcher>
<bit-tab-nav-bar class="-tw-mb-px">
<bit-tab-link route="vault">{{ "vault" | i18n }}</bit-tab-link>
<bit-tab-link *ngIf="showMembersTab" route="members">{{ "members" | i18n }}</bit-tab-link>
<bit-tab-link *ngIf="showGroupsTab" route="groups">{{ "groups" | i18n }}</bit-tab-link>
<bit-tab-link *ngIf="showReportsTab" [route]="reportRoute">{{
reportTabLabel | i18n
<bit-tab-link *ngIf="canShowMembersTab(organization)" route="members">{{
"members" | i18n
}}</bit-tab-link>
<bit-tab-link *ngIf="showBillingTab" route="billing">{{ "billing" | i18n }}</bit-tab-link>
<bit-tab-link *ngIf="showSettingsTab" route="settings">{{
<bit-tab-link *ngIf="canShowGroupsTab(organization)" route="groups">{{
"groups" | i18n
}}</bit-tab-link>
<bit-tab-link
*ngIf="canShowReportsTab(organization)"
[route]="getReportRoute(organization)"
>{{ getReportTabLabel(organization) | i18n }}</bit-tab-link
>
<bit-tab-link *ngIf="canShowBillingTab(organization)" route="billing">{{
"billing" | i18n
}}</bit-tab-link>
<bit-tab-link *ngIf="canShowSettingsTab(organization)" route="settings">{{
"settings" | i18n
}}</bit-tab-link>
</bit-tab-nav-bar>

View File

@@ -1,10 +1,6 @@
import { Component, NgZone, OnDestroy, OnInit } from "@angular/core";
import { Component, OnDestroy, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { concatMap, Subject, takeUntil } from "rxjs";
import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { Organization } from "@bitwarden/common/models/domain/organization";
import { map, mergeMap, Observable, Subject, takeUntil } from "rxjs";
import {
canAccessBillingTab,
@@ -12,85 +8,67 @@ import {
canAccessMembersTab,
canAccessReportingTab,
canAccessSettingsTab,
} from "../navigation-permissions";
const BroadcasterSubscriptionId = "OrganizationLayoutComponent";
getOrganizationById,
OrganizationService,
} from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { Organization } from "@bitwarden/common/models/domain/organization";
@Component({
selector: "app-organization-layout",
templateUrl: "organization-layout.component.html",
})
export class OrganizationLayoutComponent implements OnInit, OnDestroy {
private organizationId: string;
private destroy$ = new Subject<void>();
organization$: Observable<Organization>;
organization: Organization;
private _destroy = new Subject<void>();
constructor(
private route: ActivatedRoute,
private organizationService: OrganizationService,
private broadcasterService: BroadcasterService,
private ngZone: NgZone
) {}
constructor(private route: ActivatedRoute, private organizationService: OrganizationService) {}
ngOnInit() {
document.body.classList.remove("layout_frontend");
this.route.params
.pipe(
concatMap(async (params: any) => {
this.organizationId = params.organizationId;
await this.load();
}),
takeUntil(this.destroy$)
)
.subscribe();
this.broadcasterService.subscribe(BroadcasterSubscriptionId, (message: any) => {
this.ngZone.run(async () => {
switch (message.command) {
case "updatedOrgLicense":
await this.load();
break;
}
});
});
this.organization$ = this.route.params
.pipe(takeUntil(this._destroy))
.pipe<string>(map((p) => p.organizationId))
.pipe(
mergeMap((id) => {
return this.organizationService.organizations$
.pipe(takeUntil(this._destroy))
.pipe(getOrganizationById(id));
})
);
}
ngOnDestroy() {
this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);
this.destroy$.next();
this.destroy$.complete();
this._destroy.next();
this._destroy.complete();
}
async load() {
this.organization = await this.organizationService.get(this.organizationId);
canShowSettingsTab(organization: Organization): boolean {
return canAccessSettingsTab(organization);
}
get showSettingsTab(): boolean {
return canAccessSettingsTab(this.organization);
canShowMembersTab(organization: Organization): boolean {
return canAccessMembersTab(organization);
}
get showMembersTab(): boolean {
return canAccessMembersTab(this.organization);
canShowGroupsTab(organization: Organization): boolean {
return canAccessGroupsTab(organization);
}
get showGroupsTab(): boolean {
return canAccessGroupsTab(this.organization);
canShowReportsTab(organization: Organization): boolean {
return canAccessReportingTab(organization);
}
get showReportsTab(): boolean {
return canAccessReportingTab(this.organization);
canShowBillingTab(organization: Organization): boolean {
return canAccessBillingTab(organization);
}
get showBillingTab(): boolean {
return canAccessBillingTab(this.organization);
getReportTabLabel(organization: Organization): string {
return organization.useEvents ? "reporting" : "reports";
}
get reportTabLabel(): string {
return this.organization.useEvents ? "reporting" : "reports";
}
get reportRoute(): string {
return this.organization.useEvents ? "reporting/events" : "reporting/reports";
getReportRoute(organization: Organization): string {
return organization.useEvents ? "reporting/events" : "reporting/reports";
}
}

View File

@@ -4,7 +4,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/abstractions/log.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { Utils } from "@bitwarden/common/misc/utils";
import { EncString } from "@bitwarden/common/models/domain/encString";

View File

@@ -7,7 +7,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { CollectionService } from "@bitwarden/common/abstractions/collection.service";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/abstractions/log.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { SearchService } from "@bitwarden/common/abstractions/search.service";
import { CollectionData } from "@bitwarden/common/models/data/collectionData";

View File

@@ -7,7 +7,7 @@ import { ExportService } from "@bitwarden/common/abstractions/export.service";
import { FileDownloadService } from "@bitwarden/common/abstractions/fileDownload/fileDownload.service";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/abstractions/log.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { ProviderService } from "@bitwarden/common/abstractions/provider.service";
import { Organization } from "@bitwarden/common/models/domain/organization";

View File

@@ -1,7 +1,7 @@
import { Component, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { Organization } from "@bitwarden/common/models/domain/organization";
@Component({

View File

@@ -10,8 +10,8 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/abstractions/log.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/abstractions/organization/organization-api.service.abstraction";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { PolicyApiServiceAbstraction } from "@bitwarden/common/abstractions/policy/policy-api.service.abstraction";
import { PolicyService } from "@bitwarden/common/abstractions/policy/policy.service.abstraction";

View File

@@ -1,31 +0,0 @@
import { Organization } from "@bitwarden/common/models/domain/organization";
export function canAccessMembersTab(org: Organization): boolean {
return org.canManageUsers || org.canManageUsersPassword;
}
export function canAccessGroupsTab(org: Organization): boolean {
return org.canManageGroups;
}
export function canAccessReportingTab(org: Organization): boolean {
return org.canAccessReports || org.canAccessEventLogs;
}
export function canAccessBillingTab(org: Organization): boolean {
return org.canManageBilling;
}
export function canAccessSettingsTab(org: Organization): boolean {
return org.isOwner;
}
export function canAccessOrgAdmin(org: Organization): boolean {
return (
canAccessMembersTab(org) ||
canAccessGroupsTab(org) ||
canAccessReportingTab(org) ||
canAccessBillingTab(org) ||
canAccessSettingsTab(org)
);
}

View File

@@ -2,16 +2,16 @@ import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
import { AuthGuard } from "@bitwarden/angular/guards/auth.guard";
import {
canAccessOrgAdmin,
canAccessGroupsTab,
canAccessMembersTab,
} from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { OrganizationPermissionsGuard } from "./guards/org-permissions.guard";
import { OrganizationLayoutComponent } from "./layouts/organization-layout.component";
import { GroupsComponent } from "./manage/groups.component";
import { PeopleComponent } from "./manage/people.component";
import {
canAccessGroupsTab,
canAccessMembersTab,
canAccessOrgAdmin,
} from "./navigation-permissions";
import { VaultModule } from "./vault/vault.module";
const routes: Routes = [

View File

@@ -2,7 +2,7 @@ import { Component } from "@angular/core";
import { UntypedFormBuilder } from "@angular/forms";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PolicyType } from "@bitwarden/common/enums/policyType";
import { BasePolicy, BasePolicyComponent } from "./base-policy.component";

View File

@@ -3,7 +3,7 @@ import { ActivatedRoute, Router } from "@angular/router";
import { first } from "rxjs/operators";
import { ModalService } from "@bitwarden/angular/services/modal.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PolicyApiServiceAbstraction } from "@bitwarden/common/abstractions/policy/policy-api.service.abstraction";
import { PolicyType } from "@bitwarden/common/enums/policyType";
import { Organization } from "@bitwarden/common/models/domain/organization";

View File

@@ -1,7 +1,7 @@
import { Component } from "@angular/core";
import { UntypedFormBuilder } from "@angular/forms";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PolicyType } from "@bitwarden/common/enums/policyType";
import { Organization } from "@bitwarden/common/models/domain/organization";

View File

@@ -1,11 +1,11 @@
import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
import { canAccessReportingTab } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { Organization } from "@bitwarden/common/models/domain/organization";
import { OrganizationPermissionsGuard } from "../guards/org-permissions.guard";
import { EventsComponent } from "../manage/events.component";
import { canAccessReportingTab } from "../navigation-permissions";
import { ExposedPasswordsReportComponent } from "../tools/exposed-passwords-report.component";
import { InactiveTwoFactorReportComponent } from "../tools/inactive-two-factor-report.component";
import { ReusedPasswordsReportComponent } from "../tools/reused-passwords-report.component";

View File

@@ -2,7 +2,7 @@ import { Component, OnDestroy, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { concatMap, Subject, takeUntil } from "rxjs";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { Organization } from "@bitwarden/common/models/domain/organization";
@Component({

View File

@@ -56,9 +56,9 @@
<app-avatar data="{{ org.name }}" dynamic="true" size="75" fontSize="35"></app-avatar>
</div>
</div>
<bit-submit-button [loading]="form.loading">
<button type="submit" buttonType="primary" bitButton [loading]="form.loading">
{{ "save" | i18n }}
</bit-submit-button>
</button>
</form>
<ng-container *ngIf="canUseApi">
<div class="secondary-header border-0 mb-0">

View File

@@ -2,14 +2,12 @@ import { Component, ViewChild, ViewContainerRef } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import { ModalService } from "@bitwarden/angular/services/modal.service";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/abstractions/log.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/abstractions/organization/organization-api.service.abstraction";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { SyncService } from "@bitwarden/common/abstractions/sync/sync.service.abstraction";
import { OrganizationKeysRequest } from "@bitwarden/common/models/request/organizationKeysRequest";
import { OrganizationUpdateRequest } from "@bitwarden/common/models/request/organizationUpdateRequest";
import { OrganizationResponse } from "@bitwarden/common/models/response/organizationResponse";
@@ -39,17 +37,15 @@ export class AccountComponent {
loading = true;
canUseApi = false;
org: OrganizationResponse;
formPromise: Promise<boolean>;
formPromise: Promise<OrganizationResponse>;
taxFormPromise: Promise<unknown>;
private organizationId: string;
constructor(
private modalService: ModalService,
private apiService: ApiService,
private i18nService: I18nService,
private route: ActivatedRoute,
private syncService: SyncService,
private platformUtilsService: PlatformUtilsService,
private cryptoService: CryptoService,
private logService: LogService,
@@ -64,9 +60,7 @@ export class AccountComponent {
// eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe
this.route.parent.parent.params.subscribe(async (params) => {
this.organizationId = params.organizationId;
this.canManageBilling = (
await this.organizationService.get(this.organizationId)
).canManageBilling;
this.canManageBilling = this.organizationService.get(this.organizationId).canManageBilling;
try {
this.org = await this.organizationApiService.get(this.organizationId);
this.canUseApi = this.org.useApi;
@@ -92,9 +86,7 @@ export class AccountComponent {
request.keys = new OrganizationKeysRequest(orgKeys[0], orgKeys[1].encryptedString);
}
this.formPromise = this.organizationApiService.save(this.organizationId, request).then(() => {
return this.syncService.fullSync(true);
});
this.formPromise = this.organizationApiService.save(this.organizationId, request);
await this.formPromise;
this.platformUtilsService.showToast(
"success",

View File

@@ -3,8 +3,8 @@ import { Component, EventEmitter, OnInit, Output } from "@angular/core";
import { CipherService } from "@bitwarden/common/abstractions/cipher.service";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/abstractions/log.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/abstractions/organization/organization-api.service.abstraction";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
import { CipherType } from "@bitwarden/common/enums/cipherType";

View File

@@ -1,10 +1,10 @@
import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
import { canAccessSettingsTab } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { Organization } from "@bitwarden/common/models/domain/organization";
import { OrganizationPermissionsGuard } from "../guards/org-permissions.guard";
import { canAccessSettingsTab } from "../navigation-permissions";
import { PoliciesComponent } from "../policies";
import { AccountComponent } from "./account.component";

View File

@@ -2,7 +2,7 @@ import { Component, OnDestroy, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { Subject, switchMap, takeUntil } from "rxjs";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { Organization } from "@bitwarden/common/models/domain/organization";
@Component({

View File

@@ -34,7 +34,9 @@
>
<option value="" disabled>-- {{ "select" | i18n }} --</option>
<option value="createNew">{{ "newFamiliesOrganization" | i18n }}</option>
<option *ngFor="let o of existingFamilyOrganizations" [ngValue]="o.id">{{ o.name }}</option>
<option *ngFor="let o of existingFamilyOrganizations$ | async" [ngValue]="o.id">
{{ o.name }}
</option>
</select>
</div>
<div *ngIf="showNewOrganization" class="col-12">

View File

@@ -1,12 +1,13 @@
import { Component, OnInit, ViewChild, ViewContainerRef } from "@angular/core";
import { Component, OnDestroy, OnInit, ViewChild, ViewContainerRef } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import { first } from "rxjs/operators";
import { Observable, Subject } from "rxjs";
import { first, map, takeUntil } from "rxjs/operators";
import { ModalService } from "@bitwarden/angular/services/modal.service";
import { ValidationService } from "@bitwarden/angular/services/validation.service";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { SyncService } from "@bitwarden/common/abstractions/sync/sync.service.abstraction";
import { PlanSponsorshipType } from "@bitwarden/common/enums/planSponsorshipType";
@@ -22,8 +23,7 @@ import { OrganizationPlansComponent } from "../../settings/organization-plans.co
selector: "families-for-enterprise-setup",
templateUrl: "families-for-enterprise-setup.component.html",
})
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
export class FamiliesForEnterpriseSetupComponent implements OnInit {
export class FamiliesForEnterpriseSetupComponent implements OnInit, OnDestroy {
@ViewChild(OrganizationPlansComponent, { static: false })
set organizationPlansComponent(value: OrganizationPlansComponent) {
if (!value) {
@@ -46,11 +46,14 @@ export class FamiliesForEnterpriseSetupComponent implements OnInit {
token: string;
existingFamilyOrganizations: Organization[];
existingFamilyOrganizations$: Observable<Organization[]>;
showNewOrganization = false;
_organizationPlansComponent: OrganizationPlansComponent;
_selectedFamilyOrganizationId = "";
private _destroy = new Subject<void>();
constructor(
private router: Router,
private platformUtilsService: PlatformUtilsService,
@@ -84,17 +87,24 @@ export class FamiliesForEnterpriseSetupComponent implements OnInit {
await this.syncService.fullSync(true);
this.badToken = !(await this.apiService.postPreValidateSponsorshipToken(this.token));
this.loading = false;
});
this.existingFamilyOrganizations = (await this.organizationService.getAll()).filter(
(o) => o.planProductType === ProductType.Families
);
this.existingFamilyOrganizations$ = this.organizationService.organizations$.pipe(
map((orgs) => orgs.filter((o) => o.planProductType === ProductType.Families))
);
if (this.existingFamilyOrganizations.length === 0) {
this.existingFamilyOrganizations$.pipe(takeUntil(this._destroy)).subscribe((orgs) => {
if (orgs.length === 0) {
this.selectedFamilyOrganizationId = "createNew";
}
});
}
ngOnDestroy(): void {
this._destroy.next();
this._destroy.complete();
}
async submit() {
this.formPromise = this.doSubmit(this._selectedFamilyOrganizationId);
await this.formPromise;

View File

@@ -5,7 +5,7 @@ import { ModalService } from "@bitwarden/angular/services/modal.service";
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
import { CipherService } from "@bitwarden/common/abstractions/cipher.service";
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PasswordRepromptService } from "@bitwarden/common/abstractions/passwordReprompt.service";
import { StateService } from "@bitwarden/common/abstractions/state.service";
import { Cipher } from "@bitwarden/common/models/domain/cipher";

View File

@@ -5,7 +5,7 @@ import { ModalService } from "@bitwarden/angular/services/modal.service";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { ImportService } from "@bitwarden/common/abstractions/import.service";
import { LogService } from "@bitwarden/common/abstractions/log.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { PolicyService } from "@bitwarden/common/abstractions/policy/policy.service.abstraction";

View File

@@ -5,7 +5,7 @@ import { ModalService } from "@bitwarden/angular/services/modal.service";
import { CipherService } from "@bitwarden/common/abstractions/cipher.service";
import { LogService } from "@bitwarden/common/abstractions/log.service";
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PasswordRepromptService } from "@bitwarden/common/abstractions/passwordReprompt.service";
import { StateService } from "@bitwarden/common/abstractions/state.service";
import { CipherView } from "@bitwarden/common/models/view/cipherView";

View File

@@ -4,7 +4,7 @@ import { ActivatedRoute } from "@angular/router";
import { ModalService } from "@bitwarden/angular/services/modal.service";
import { CipherService } from "@bitwarden/common/abstractions/cipher.service";
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PasswordRepromptService } from "@bitwarden/common/abstractions/passwordReprompt.service";
import { StateService } from "@bitwarden/common/abstractions/state.service";
import { Cipher } from "@bitwarden/common/models/domain/cipher";

View File

@@ -2,7 +2,7 @@ import { Component } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { Organization } from "@bitwarden/common/models/domain/organization";
@Component({

View File

@@ -4,7 +4,7 @@ import { ActivatedRoute } from "@angular/router";
import { ModalService } from "@bitwarden/angular/services/modal.service";
import { CipherService } from "@bitwarden/common/abstractions/cipher.service";
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PasswordRepromptService } from "@bitwarden/common/abstractions/passwordReprompt.service";
import { StateService } from "@bitwarden/common/abstractions/state.service";
import { CipherView } from "@bitwarden/common/models/view/cipherView";

View File

@@ -4,7 +4,7 @@ import { ActivatedRoute } from "@angular/router";
import { ModalService } from "@bitwarden/angular/services/modal.service";
import { CipherService } from "@bitwarden/common/abstractions/cipher.service";
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PasswordGenerationService } from "@bitwarden/common/abstractions/passwordGeneration.service";
import { PasswordRepromptService } from "@bitwarden/common/abstractions/passwordReprompt.service";
import { StateService } from "@bitwarden/common/abstractions/state.service";

View File

@@ -32,9 +32,9 @@
<app-user-verification [(ngModel)]="verification" name="secret"> </app-user-verification>
</div>
<div class="modal-footer">
<bit-submit-button [loading]="form.loading">
<button type="submit" buttonType="primary" bitButton [loading]="form.loading">
{{ "submit" | i18n }}
</bit-submit-button>
</button>
<button
bitButton
buttonType="secondary"

View File

@@ -9,7 +9,7 @@ import { FolderService } from "@bitwarden/common/abstractions/folder/folder.serv
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/abstractions/log.service";
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PasswordGenerationService } from "@bitwarden/common/abstractions/passwordGeneration.service";
import { PasswordRepromptService } from "@bitwarden/common/abstractions/passwordReprompt.service";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";

View File

@@ -5,7 +5,7 @@ import { CipherService } from "@bitwarden/common/abstractions/cipher.service";
import { EventService } from "@bitwarden/common/abstractions/event.service";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/abstractions/log.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PasswordRepromptService } from "@bitwarden/common/abstractions/passwordReprompt.service";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { SearchService } from "@bitwarden/common/abstractions/search.service";

View File

@@ -16,7 +16,7 @@ import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.s
import { CipherService } from "@bitwarden/common/abstractions/cipher.service";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
import { PasswordRepromptService } from "@bitwarden/common/abstractions/passwordReprompt.service";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { SyncService } from "@bitwarden/common/abstractions/sync/sync.service.abstraction";