166 lines
6.3 KiB
TypeScript
166 lines
6.3 KiB
TypeScript
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 { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
|
import { SyncService } from "@bitwarden/common/abstractions/sync.service";
|
|
import { OrganizationKeysRequest } from "@bitwarden/common/models/request/organizationKeysRequest";
|
|
import { OrganizationUpdateRequest } from "@bitwarden/common/models/request/organizationUpdateRequest";
|
|
import { OrganizationResponse } from "@bitwarden/common/models/response/organizationResponse";
|
|
|
|
import { ApiKeyComponent } from "../../settings/api-key.component";
|
|
import { PurgeVaultComponent } from "../../settings/purge-vault.component";
|
|
import { TaxInfoComponent } from "../../settings/tax-info.component";
|
|
|
|
import { DeleteOrganizationComponent } from "./delete-organization.component";
|
|
|
|
@Component({
|
|
selector: "app-org-account",
|
|
templateUrl: "account.component.html",
|
|
})
|
|
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
|
|
export class AccountComponent {
|
|
@ViewChild("deleteOrganizationTemplate", { read: ViewContainerRef, static: true })
|
|
deleteModalRef: ViewContainerRef;
|
|
@ViewChild("purgeOrganizationTemplate", { read: ViewContainerRef, static: true })
|
|
purgeModalRef: ViewContainerRef;
|
|
@ViewChild("apiKeyTemplate", { read: ViewContainerRef, static: true })
|
|
apiKeyModalRef: ViewContainerRef;
|
|
@ViewChild("rotateApiKeyTemplate", { read: ViewContainerRef, static: true })
|
|
rotateApiKeyModalRef: ViewContainerRef;
|
|
@ViewChild(TaxInfoComponent) taxInfo: TaxInfoComponent;
|
|
|
|
selfHosted = false;
|
|
canManageBilling = true;
|
|
loading = true;
|
|
canUseApi = false;
|
|
org: OrganizationResponse;
|
|
formPromise: Promise<boolean>;
|
|
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,
|
|
private router: Router,
|
|
private organizationService: OrganizationService,
|
|
private organizationApiService: OrganizationApiServiceAbstraction
|
|
) {}
|
|
|
|
async ngOnInit() {
|
|
this.selfHosted = this.platformUtilsService.isSelfHost();
|
|
|
|
// 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;
|
|
try {
|
|
this.org = await this.organizationApiService.get(this.organizationId);
|
|
this.canUseApi = this.org.useApi;
|
|
} catch (e) {
|
|
this.logService.error(e);
|
|
}
|
|
});
|
|
this.loading = false;
|
|
}
|
|
|
|
async submit() {
|
|
try {
|
|
const request = new OrganizationUpdateRequest();
|
|
request.name = this.org.name;
|
|
request.businessName = this.org.businessName;
|
|
request.billingEmail = this.org.billingEmail;
|
|
request.identifier = this.org.identifier;
|
|
|
|
// Backfill pub/priv key if necessary
|
|
if (!this.org.hasPublicAndPrivateKeys) {
|
|
const orgShareKey = await this.cryptoService.getOrgKey(this.organizationId);
|
|
const orgKeys = await this.cryptoService.makeKeyPair(orgShareKey);
|
|
request.keys = new OrganizationKeysRequest(orgKeys[0], orgKeys[1].encryptedString);
|
|
}
|
|
|
|
this.formPromise = this.organizationApiService.save(this.organizationId, request).then(() => {
|
|
return this.syncService.fullSync(true);
|
|
});
|
|
await this.formPromise;
|
|
this.platformUtilsService.showToast(
|
|
"success",
|
|
null,
|
|
this.i18nService.t("organizationUpdated")
|
|
);
|
|
} catch (e) {
|
|
this.logService.error(e);
|
|
}
|
|
}
|
|
|
|
async submitTaxInfo() {
|
|
this.taxFormPromise = this.taxInfo.submitTaxInfo();
|
|
await this.taxFormPromise;
|
|
this.platformUtilsService.showToast("success", null, this.i18nService.t("taxInfoUpdated"));
|
|
}
|
|
|
|
async deleteOrganization() {
|
|
await this.modalService.openViewRef(
|
|
DeleteOrganizationComponent,
|
|
this.deleteModalRef,
|
|
(comp) => {
|
|
comp.organizationId = this.organizationId;
|
|
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
|
|
comp.onSuccess.subscribe(() => {
|
|
this.router.navigate(["/"]);
|
|
});
|
|
}
|
|
);
|
|
}
|
|
|
|
async purgeVault() {
|
|
await this.modalService.openViewRef(PurgeVaultComponent, this.purgeModalRef, (comp) => {
|
|
comp.organizationId = this.organizationId;
|
|
});
|
|
}
|
|
|
|
async viewApiKey() {
|
|
await this.modalService.openViewRef(ApiKeyComponent, this.apiKeyModalRef, (comp) => {
|
|
comp.keyType = "organization";
|
|
comp.entityId = this.organizationId;
|
|
comp.postKey = this.organizationApiService.getOrCreateApiKey.bind(
|
|
this.organizationApiService
|
|
);
|
|
comp.scope = "api.organization";
|
|
comp.grantType = "client_credentials";
|
|
comp.apiKeyTitle = "apiKey";
|
|
comp.apiKeyWarning = "apiKeyWarning";
|
|
comp.apiKeyDescription = "apiKeyDesc";
|
|
});
|
|
}
|
|
|
|
async rotateApiKey() {
|
|
await this.modalService.openViewRef(ApiKeyComponent, this.rotateApiKeyModalRef, (comp) => {
|
|
comp.keyType = "organization";
|
|
comp.isRotation = true;
|
|
comp.entityId = this.organizationId;
|
|
comp.postKey = this.organizationApiService.rotateApiKey.bind(this.organizationApiService);
|
|
comp.scope = "api.organization";
|
|
comp.grantType = "client_credentials";
|
|
comp.apiKeyTitle = "apiKey";
|
|
comp.apiKeyWarning = "apiKeyWarning";
|
|
comp.apiKeyDescription = "apiKeyRotateDesc";
|
|
});
|
|
}
|
|
}
|