mirror of
https://github.com/bitwarden/browser
synced 2025-12-29 14:43:31 +00:00
Merge branch 'main' into ps/PM-8297-improve-updater
This commit is contained in:
@@ -5258,6 +5258,9 @@
|
||||
"secureDevicesBody": {
|
||||
"message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps."
|
||||
},
|
||||
"nudgeBadgeAria": {
|
||||
"message": "1 notification"
|
||||
},
|
||||
"emptyVaultNudgeTitle": {
|
||||
"message": "Import existing passwords"
|
||||
},
|
||||
@@ -5321,5 +5324,8 @@
|
||||
"message": "Learn more about SSH agent",
|
||||
"description": "Two part message",
|
||||
"example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent"
|
||||
},
|
||||
"noPermissionsViewPage": {
|
||||
"message": "You do not have permissions to view this page. Try logging in with a different account."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ export const RedirectFocusDirection = {
|
||||
Next: "next",
|
||||
} as const;
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum InlineMenuFillType {
|
||||
AccountCreationUsername = 5,
|
||||
PasswordGeneration = 6,
|
||||
|
||||
@@ -5,6 +5,8 @@ import {
|
||||
AssertCredentialResult,
|
||||
} from "@bitwarden/common/platform/abstractions/fido2/fido2-client.service.abstraction";
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum MessageType {
|
||||
CredentialCreationRequest,
|
||||
CredentialCreationResponse,
|
||||
|
||||
@@ -26,6 +26,8 @@ import { PopOutComponent } from "../../../platform/popup/components/pop-out.comp
|
||||
import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component";
|
||||
import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component";
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum SendState {
|
||||
Empty,
|
||||
NoResults,
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
*ngIf="!isBrowserAutofillSettingOverridden && (showAutofillBadge$ | async)"
|
||||
bitBadge
|
||||
variant="notification"
|
||||
[attr.aria-label]="'nudgeBadgeAria' | i18n"
|
||||
>1</span
|
||||
>
|
||||
</div>
|
||||
@@ -53,6 +54,7 @@
|
||||
*ngIf="!(showVaultBadge$ | async)?.hasBadgeDismissed"
|
||||
bitBadge
|
||||
variant="notification"
|
||||
[attr.aria-label]="'nudgeBadgeAria' | i18n"
|
||||
>1</span
|
||||
>
|
||||
</div>
|
||||
@@ -83,6 +85,7 @@
|
||||
*ngIf="(downloadBitwardenNudgeStatus$ | async)?.hasBadgeDismissed === false"
|
||||
bitBadge
|
||||
variant="notification"
|
||||
[attr.aria-label]="'nudgeBadgeAria' | i18n"
|
||||
>1
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { inject } from "@angular/core";
|
||||
import { CanActivateFn } from "@angular/router";
|
||||
import { switchMap, tap } from "rxjs";
|
||||
import { CanActivateFn, Router } from "@angular/router";
|
||||
import { map, switchMap } from "rxjs";
|
||||
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
@@ -13,18 +13,22 @@ export const canAccessAtRiskPasswords: CanActivateFn = () => {
|
||||
const taskService = inject(TaskService);
|
||||
const toastService = inject(ToastService);
|
||||
const i18nService = inject(I18nService);
|
||||
const router = inject(Router);
|
||||
|
||||
return accountService.activeAccount$.pipe(
|
||||
filterOutNullish(),
|
||||
switchMap((user) => taskService.tasksEnabled$(user.id)),
|
||||
tap((tasksEnabled) => {
|
||||
map((tasksEnabled) => {
|
||||
if (!tasksEnabled) {
|
||||
toastService.showToast({
|
||||
variant: "error",
|
||||
title: "",
|
||||
message: i18nService.t("accessDenied"),
|
||||
message: i18nService.t("noPermissionsViewPage"),
|
||||
});
|
||||
|
||||
return router.createUrlTree(["/tabs/vault"]);
|
||||
}
|
||||
return true;
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -10,6 +10,8 @@ import {
|
||||
import { I18nPipe } from "@bitwarden/ui-common";
|
||||
import { DarkImageSourceDirective, VaultCarouselModule } from "@bitwarden/vault";
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum AtRiskCarouselDialogResult {
|
||||
Dismissed = "dismissed",
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ export interface GeneratorDialogResult {
|
||||
generatedValue?: string;
|
||||
}
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum GeneratorDialogAction {
|
||||
Selected = "selected",
|
||||
Canceled = "canceled",
|
||||
|
||||
@@ -55,6 +55,8 @@ import { VaultPageService } from "./vault-page.service";
|
||||
|
||||
import { AutofillVaultListItemsComponent, VaultListItemsContainerComponent } from ".";
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
enum VaultState {
|
||||
Empty,
|
||||
NoResults,
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
"browser-hrtime": "1.1.8",
|
||||
"chalk": "4.1.2",
|
||||
"commander": "11.1.0",
|
||||
"core-js": "3.40.0",
|
||||
"form-data": "4.0.1",
|
||||
"https-proxy-agent": "7.0.6",
|
||||
"inquirer": "8.2.6",
|
||||
|
||||
@@ -106,6 +106,8 @@ export class LoginCommand {
|
||||
return Response.badRequest("client_secret is required.");
|
||||
}
|
||||
} else if (options.sso != null && this.canInteract) {
|
||||
// If the optional Org SSO Identifier isn't provided, the option value is `true`.
|
||||
const orgSsoIdentifier = options.sso === true ? null : options.sso;
|
||||
const passwordOptions: any = {
|
||||
type: "password",
|
||||
length: 64,
|
||||
@@ -119,7 +121,7 @@ export class LoginCommand {
|
||||
const codeVerifierHash = await this.cryptoFunctionService.hash(ssoCodeVerifier, "sha256");
|
||||
const codeChallenge = Utils.fromBufferToUrlB64(codeVerifierHash);
|
||||
try {
|
||||
const ssoParams = await this.openSsoPrompt(codeChallenge, state);
|
||||
const ssoParams = await this.openSsoPrompt(codeChallenge, state, orgSsoIdentifier);
|
||||
ssoCode = ssoParams.ssoCode;
|
||||
orgIdentifier = ssoParams.orgIdentifier;
|
||||
} catch {
|
||||
@@ -664,6 +666,7 @@ export class LoginCommand {
|
||||
private async openSsoPrompt(
|
||||
codeChallenge: string,
|
||||
state: string,
|
||||
orgSsoIdentifier: string,
|
||||
): Promise<{ ssoCode: string; orgIdentifier: string }> {
|
||||
const env = await firstValueFrom(this.environmentService.environment$);
|
||||
|
||||
@@ -712,6 +715,8 @@ export class LoginCommand {
|
||||
this.ssoRedirectUri,
|
||||
state,
|
||||
codeChallenge,
|
||||
null,
|
||||
orgSsoIdentifier,
|
||||
);
|
||||
this.platformUtilsService.launchUri(webAppSsoUrl);
|
||||
});
|
||||
|
||||
@@ -118,7 +118,10 @@ export class Program extends BaseProgram {
|
||||
.description("Log into a user account.")
|
||||
.option("--method <method>", "Two-step login method.")
|
||||
.option("--code <code>", "Two-step login code.")
|
||||
.option("--sso", "Log in with Single-Sign On.")
|
||||
.option(
|
||||
"--sso [identifier]",
|
||||
"Log in with Single-Sign On with optional organization identifier.",
|
||||
)
|
||||
.option("--apikey", "Log in with an Api Key.")
|
||||
.option("--passwordenv <passwordenv>", "Environment variable storing your password")
|
||||
.option(
|
||||
|
||||
@@ -15,6 +15,8 @@ const DEFAULT_MESSAGE_TIMEOUT = 10 * 1000; // 10 seconds
|
||||
|
||||
export type MessageHandler = (MessageCommon) => void;
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum IPCConnectionState {
|
||||
Disconnected = "disconnected",
|
||||
Connecting = "connecting",
|
||||
|
||||
@@ -25,6 +25,8 @@ import { SearchBarService } from "../../layout/search/search-bar.service";
|
||||
|
||||
import { AddEditComponent } from "./add-edit.component";
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
enum Action {
|
||||
None = "",
|
||||
Add = "add",
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum SshAgentPromptType {
|
||||
Always = "always",
|
||||
Never = "never",
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum BiometricAction {
|
||||
Authenticate = "authenticate",
|
||||
GetStatus = "status",
|
||||
|
||||
@@ -31,6 +31,8 @@ export interface CredentialGeneratorDialogResult {
|
||||
generatedValue?: string;
|
||||
}
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum CredentialGeneratorDialogAction {
|
||||
Selected = "selected",
|
||||
Canceled = "canceled",
|
||||
|
||||
@@ -43,6 +43,8 @@ export interface BulkCollectionsDialogParams {
|
||||
collections: CollectionView[];
|
||||
}
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum BulkCollectionsDialogResult {
|
||||
Saved = "saved",
|
||||
Canceled = "canceled",
|
||||
|
||||
@@ -132,6 +132,8 @@ import { VaultHeaderComponent } from "./vault-header/vault-header.component";
|
||||
const BroadcasterSubscriptionId = "OrgVaultComponent";
|
||||
const SearchTextDebounceInterval = 200;
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
enum AddAccessStatusType {
|
||||
All = 0,
|
||||
AddAccess = 1,
|
||||
|
||||
@@ -58,6 +58,8 @@ import { AddEditGroupDetail } from "./../core/views/add-edit-group-detail";
|
||||
/**
|
||||
* Indices for the available tabs in the dialog
|
||||
*/
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum GroupAddEditTabType {
|
||||
Info = 0,
|
||||
Members = 1,
|
||||
@@ -82,6 +84,8 @@ export interface GroupAddEditDialogParams {
|
||||
initialTab?: GroupAddEditTabType;
|
||||
}
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum GroupAddEditDialogResultType {
|
||||
Saved = "saved",
|
||||
Canceled = "canceled",
|
||||
|
||||
@@ -64,6 +64,8 @@ import { commaSeparatedEmails } from "./validators/comma-separated-emails.valida
|
||||
import { inputEmailLimitValidator } from "./validators/input-email-limit.validator";
|
||||
import { orgSeatLimitReachedValidator } from "./validators/org-seat-limit-reached.validator";
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum MemberDialogTab {
|
||||
Role = 0,
|
||||
Groups = 1,
|
||||
@@ -92,6 +94,8 @@ export interface EditMemberDialogParams extends CommonMemberDialogParams {
|
||||
|
||||
export type MemberDialogParams = EditMemberDialogParams | AddMemberDialogParams;
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum MemberDialogResult {
|
||||
Saved = "saved",
|
||||
Canceled = "canceled",
|
||||
|
||||
@@ -50,6 +50,8 @@ export type ResetPasswordDialogData = {
|
||||
organizationId: string;
|
||||
};
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum ResetPasswordDialogResult {
|
||||
Ok = "ok",
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ export class OrganizationUserResetPasswordService
|
||||
if (orgSymKey == null) {
|
||||
throw new Error("No org key found");
|
||||
}
|
||||
const decPrivateKey = await this.encryptService.decryptToBytes(
|
||||
const decPrivateKey = await this.encryptService.unwrapDecapsulationKey(
|
||||
new EncString(response.encryptedPrivateKey),
|
||||
orgSymKey,
|
||||
);
|
||||
|
||||
@@ -41,6 +41,8 @@ export type PolicyEditDialogData = {
|
||||
organizationId: string;
|
||||
};
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum PolicyEditDialogResult {
|
||||
Saved = "saved",
|
||||
UpgradePlan = "upgrade-plan",
|
||||
|
||||
@@ -71,6 +71,8 @@ export interface DeleteOrganizationDialogParams {
|
||||
requestType: "InvalidFamiliesForEnterprise" | "RegularDelete";
|
||||
}
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum DeleteOrganizationDialogResult {
|
||||
Deleted = "deleted",
|
||||
Canceled = "canceled",
|
||||
|
||||
@@ -26,6 +26,8 @@ import {
|
||||
Permission,
|
||||
} from "./access-selector.models";
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum PermissionMode {
|
||||
/**
|
||||
* No permission controls or column present. No permission values are emitted.
|
||||
|
||||
@@ -15,6 +15,8 @@ import { GroupView } from "../../../core";
|
||||
/**
|
||||
* Permission options that replace/correspond with manage, readOnly, and hidePassword server fields.
|
||||
*/
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum CollectionPermission {
|
||||
View = "view",
|
||||
ViewExceptPass = "viewExceptPass",
|
||||
@@ -23,6 +25,8 @@ export enum CollectionPermission {
|
||||
Manage = "manage",
|
||||
}
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum AccessItemType {
|
||||
Collection,
|
||||
Group,
|
||||
|
||||
@@ -65,6 +65,8 @@ import {
|
||||
} from "../access-selector/access-selector.models";
|
||||
import { AccessSelectorModule } from "../access-selector/access-selector.module";
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum CollectionDialogTabType {
|
||||
Info = 0,
|
||||
Access = 1,
|
||||
@@ -76,6 +78,8 @@ export enum CollectionDialogTabType {
|
||||
* @readonly
|
||||
* @enum {string}
|
||||
*/
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
enum ButtonType {
|
||||
/** Displayed when the user has reached the maximum number of collections allowed for the organization. */
|
||||
Upgrade = "upgrade",
|
||||
@@ -103,6 +107,8 @@ export interface CollectionDialogResult {
|
||||
collection: CollectionResponse | CollectionView;
|
||||
}
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum CollectionDialogAction {
|
||||
Saved = "saved",
|
||||
Canceled = "canceled",
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum WebauthnLoginCredentialPrfStatus {
|
||||
Enabled = 0,
|
||||
Supported = 1,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum EmergencyAccessStatusType {
|
||||
Invited = 0,
|
||||
Accepted = 1,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum EmergencyAccessType {
|
||||
View = 0,
|
||||
Takeover = 1,
|
||||
|
||||
@@ -8,6 +8,8 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service"
|
||||
import { DialogConfig, DialogRef, DIALOG_DATA, DialogService } from "@bitwarden/components";
|
||||
import { KeyService } from "@bitwarden/key-management";
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum EmergencyAccessConfirmDialogResult {
|
||||
Confirmed = "confirmed",
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ export type EmergencyAccessAddEditDialogData = {
|
||||
readOnly: boolean;
|
||||
};
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum EmergencyAccessAddEditDialogResult {
|
||||
Saved = "saved",
|
||||
Canceled = "canceled",
|
||||
|
||||
@@ -24,6 +24,8 @@ import { KdfType, KdfConfigService, KeyService } from "@bitwarden/key-management
|
||||
|
||||
import { EmergencyAccessService } from "../../../emergency-access";
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum EmergencyAccessTakeoverResultType {
|
||||
Done = "done",
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ import { PendingWebauthnLoginCredentialView } from "../../../core/views/pending-
|
||||
import { CreatePasskeyFailedIcon } from "./create-passkey-failed.icon";
|
||||
import { CreatePasskeyIcon } from "./create-passkey.icon";
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum CreateCredentialDialogResult {
|
||||
Success,
|
||||
}
|
||||
|
||||
@@ -51,8 +51,38 @@
|
||||
<h2 class="tw-mb-3 tw-text-base tw-font-semibold">{{ "paymentType" | i18n }}</h2>
|
||||
<app-payment [showAccountCredit]="false"></app-payment>
|
||||
<app-manage-tax-information
|
||||
(taxInformationChanged)="changedCountry()"
|
||||
(taxInformationChanged)="onTaxInformationChanged()"
|
||||
></app-manage-tax-information>
|
||||
|
||||
@if (trialLength === 0) {
|
||||
@let priceLabel =
|
||||
subscriptionProduct === SubscriptionProduct.PasswordManager
|
||||
? "passwordManagerPlanPrice"
|
||||
: "secretsManagerPlanPrice";
|
||||
|
||||
<div id="price" class="tw-my-4">
|
||||
<div class="tw-text-muted tw-text-base">
|
||||
{{ priceLabel | i18n }}: {{ getPriceFor(formGroup.value.cadence) | currency: "USD $" }}
|
||||
<div>
|
||||
{{ "estimatedTax" | i18n }}:
|
||||
@if (fetchingTaxAmount) {
|
||||
<ng-container *ngTemplateOutlet="loadingSpinner" />
|
||||
} @else {
|
||||
{{ taxAmount | currency: "USD $" }}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<hr class="tw-my-1 tw-grid tw-grid-cols-3 tw-ml-0" />
|
||||
<p class="tw-text-lg">
|
||||
<strong>{{ "total" | i18n }}: </strong>
|
||||
@if (fetchingTaxAmount) {
|
||||
<ng-container *ngTemplateOutlet="loadingSpinner" />
|
||||
} @else {
|
||||
{{ total | currency: "USD $" }}/{{ interval | i18n }}
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="tw-flex tw-space-x-2">
|
||||
<button type="submit" buttonType="primary" bitButton [loading]="form.loading">
|
||||
@@ -62,3 +92,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<ng-template #loadingSpinner>
|
||||
<i
|
||||
class="bwi bwi-spinner bwi-spin tw-text-muted"
|
||||
title="{{ 'loading' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
|
||||
</ng-template>
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from "@angular/core";
|
||||
import {
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
Output,
|
||||
ViewChild,
|
||||
} from "@angular/core";
|
||||
import { FormBuilder, Validators } from "@angular/forms";
|
||||
import { from, Subject, switchMap, takeUntil } from "rxjs";
|
||||
|
||||
import { ManageTaxInformationComponent } from "@bitwarden/angular/billing/components";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
@@ -12,7 +21,14 @@ import {
|
||||
PaymentInformation,
|
||||
PlanInformation,
|
||||
} from "@bitwarden/common/billing/abstractions/organization-billing.service";
|
||||
import { PaymentMethodType, PlanType, ProductTierType } from "@bitwarden/common/billing/enums";
|
||||
import { TaxServiceAbstraction } from "@bitwarden/common/billing/abstractions/tax.service.abstraction";
|
||||
import {
|
||||
PaymentMethodType,
|
||||
PlanType,
|
||||
ProductTierType,
|
||||
ProductType,
|
||||
} from "@bitwarden/common/billing/enums";
|
||||
import { PreviewTaxAmountForOrganizationTrialRequest } from "@bitwarden/common/billing/models/request/tax";
|
||||
import { PlanResponse } from "@bitwarden/common/billing/models/response/plan.response";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
@@ -34,11 +50,15 @@ export interface OrganizationCreatedEvent {
|
||||
planDescription: string;
|
||||
}
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
enum SubscriptionCadence {
|
||||
Annual,
|
||||
Monthly,
|
||||
}
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum SubscriptionProduct {
|
||||
PasswordManager,
|
||||
SecretsManager,
|
||||
@@ -50,7 +70,7 @@ export enum SubscriptionProduct {
|
||||
imports: [BillingSharedModule],
|
||||
standalone: true,
|
||||
})
|
||||
export class TrialBillingStepComponent implements OnInit {
|
||||
export class TrialBillingStepComponent implements OnInit, OnDestroy {
|
||||
@ViewChild(PaymentComponent) paymentComponent: PaymentComponent;
|
||||
@ViewChild(ManageTaxInformationComponent) taxInfoComponent: ManageTaxInformationComponent;
|
||||
@Input() organizationInfo: OrganizationInfo;
|
||||
@@ -60,6 +80,7 @@ export class TrialBillingStepComponent implements OnInit {
|
||||
@Output() organizationCreated = new EventEmitter<OrganizationCreatedEvent>();
|
||||
|
||||
loading = true;
|
||||
fetchingTaxAmount = false;
|
||||
|
||||
annualCadence = SubscriptionCadence.Annual;
|
||||
monthlyCadence = SubscriptionCadence.Monthly;
|
||||
@@ -73,6 +94,12 @@ export class TrialBillingStepComponent implements OnInit {
|
||||
annualPlan?: PlanResponse;
|
||||
monthlyPlan?: PlanResponse;
|
||||
|
||||
taxAmount = 0;
|
||||
|
||||
private destroy$ = new Subject<void>();
|
||||
|
||||
protected readonly SubscriptionProduct = SubscriptionProduct;
|
||||
|
||||
constructor(
|
||||
private apiService: ApiService,
|
||||
private i18nService: I18nService,
|
||||
@@ -80,6 +107,7 @@ export class TrialBillingStepComponent implements OnInit {
|
||||
private messagingService: MessagingService,
|
||||
private organizationBillingService: OrganizationBillingService,
|
||||
private toastService: ToastService,
|
||||
private taxService: TaxServiceAbstraction,
|
||||
) {}
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
@@ -87,9 +115,26 @@ export class TrialBillingStepComponent implements OnInit {
|
||||
this.applicablePlans = plans.data.filter(this.isApplicable);
|
||||
this.annualPlan = this.findPlanFor(SubscriptionCadence.Annual);
|
||||
this.monthlyPlan = this.findPlanFor(SubscriptionCadence.Monthly);
|
||||
|
||||
if (this.trialLength === 0) {
|
||||
this.formGroup.controls.cadence.valueChanges
|
||||
.pipe(
|
||||
switchMap((cadence) => from(this.previewTaxAmount(cadence))),
|
||||
takeUntil(this.destroy$),
|
||||
)
|
||||
.subscribe((taxAmount) => {
|
||||
this.taxAmount = taxAmount;
|
||||
});
|
||||
}
|
||||
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
|
||||
async submit(): Promise<void> {
|
||||
if (!this.taxInfoComponent.validate()) {
|
||||
return;
|
||||
@@ -115,7 +160,11 @@ export class TrialBillingStepComponent implements OnInit {
|
||||
this.messagingService.send("organizationCreated", { organizationId });
|
||||
}
|
||||
|
||||
protected changedCountry() {
|
||||
async onTaxInformationChanged() {
|
||||
if (this.trialLength === 0) {
|
||||
this.taxAmount = await this.previewTaxAmount(this.formGroup.value.cadence);
|
||||
}
|
||||
|
||||
this.paymentComponent.showBankAccount =
|
||||
this.taxInfoComponent.getTaxInformation().country === "US";
|
||||
if (
|
||||
@@ -170,6 +219,7 @@ export class TrialBillingStepComponent implements OnInit {
|
||||
const payment: PaymentInformation = {
|
||||
paymentMethod,
|
||||
billing: this.getBillingInformationFromTaxInfoComponent(),
|
||||
skipTrial: this.trialLength === 0,
|
||||
};
|
||||
|
||||
const response = await this.organizationBillingService.purchaseSubscription({
|
||||
@@ -250,4 +300,45 @@ export class TrialBillingStepComponent implements OnInit {
|
||||
const notDisabledOrLegacy = !plan.disabled && !plan.legacyYear;
|
||||
return hasCorrectProductType && notDisabledOrLegacy;
|
||||
}
|
||||
|
||||
private previewTaxAmount = async (cadence: SubscriptionCadence): Promise<number> => {
|
||||
this.fetchingTaxAmount = true;
|
||||
|
||||
if (!this.taxInfoComponent.validate()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const plan = this.findPlanFor(cadence);
|
||||
|
||||
const productType =
|
||||
this.subscriptionProduct === SubscriptionProduct.PasswordManager
|
||||
? ProductType.PasswordManager
|
||||
: ProductType.SecretsManager;
|
||||
|
||||
const taxInformation = this.taxInfoComponent.getTaxInformation();
|
||||
|
||||
const request: PreviewTaxAmountForOrganizationTrialRequest = {
|
||||
planType: plan.type,
|
||||
productType,
|
||||
taxInformation: {
|
||||
...taxInformation,
|
||||
},
|
||||
};
|
||||
|
||||
const response = await this.taxService.previewTaxAmountForOrganizationTrial(request);
|
||||
this.fetchingTaxAmount = false;
|
||||
return response.taxAmount;
|
||||
};
|
||||
|
||||
get price() {
|
||||
return this.getPriceFor(this.formGroup.value.cadence);
|
||||
}
|
||||
|
||||
get total() {
|
||||
return this.price + this.taxAmount;
|
||||
}
|
||||
|
||||
get interval() {
|
||||
return this.formGroup.value.cadence === SubscriptionCadence.Annual ? "year" : "month";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ export class FreeBitwardenFamiliesComponent implements OnInit {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.apiService.deleteRevokeSponsorship(this.organizationId);
|
||||
await this.organizationSponsorshipApiService.deleteRevokeSponsorship(this.organizationId, true);
|
||||
|
||||
this.toastService.showToast({
|
||||
variant: "success",
|
||||
|
||||
@@ -74,11 +74,15 @@ type ChangePlanDialogParams = {
|
||||
productTierType: ProductTierType;
|
||||
};
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum ChangePlanDialogResultType {
|
||||
Closed = "closed",
|
||||
Submitted = "submitted",
|
||||
}
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum PlanCardState {
|
||||
Selected = "selected",
|
||||
NotSelected = "not_selected",
|
||||
|
||||
@@ -7,6 +7,8 @@ import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-conso
|
||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||
import { DialogConfig, DIALOG_DATA, DialogRef, DialogService } from "@bitwarden/components";
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum DownloadLicenseDialogResult {
|
||||
Cancelled = "cancelled",
|
||||
Downloaded = "downloaded",
|
||||
|
||||
@@ -27,6 +27,8 @@ import { DialogService, ToastService } from "@bitwarden/components";
|
||||
|
||||
import { BillingSyncKeyComponent } from "./billing-sync-key.component";
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
enum LicenseOptions {
|
||||
SYNC = 0,
|
||||
UPLOAD = 1,
|
||||
|
||||
@@ -109,7 +109,7 @@ export class SponsoringOrgRowComponent implements OnInit {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.apiService.deleteRevokeSponsorship(this.sponsoringOrg.id);
|
||||
await this.organizationSponsorshipApiService.deleteRevokeSponsorship(this.sponsoringOrg.id);
|
||||
this.toastService.showToast({
|
||||
variant: "success",
|
||||
title: null,
|
||||
|
||||
@@ -21,6 +21,8 @@ export interface AddCreditDialogData {
|
||||
organizationId: string;
|
||||
}
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum AddCreditDialogResult {
|
||||
Added = "added",
|
||||
Cancelled = "cancelled",
|
||||
|
||||
@@ -30,6 +30,8 @@ export interface AdjustPaymentDialogParams {
|
||||
providerId?: string;
|
||||
}
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum AdjustPaymentDialogResultType {
|
||||
Closed = "closed",
|
||||
Submitted = "submitted",
|
||||
|
||||
@@ -22,6 +22,8 @@ export interface AdjustStorageDialogParams {
|
||||
organizationId?: string;
|
||||
}
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum AdjustStorageDialogResultType {
|
||||
Submitted = "submitted",
|
||||
Closed = "closed",
|
||||
|
||||
@@ -25,6 +25,8 @@ type OrganizationOffboardingParams = {
|
||||
|
||||
export type OffboardingSurveyDialogParams = UserOffboardingParams | OrganizationOffboardingParams;
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum OffboardingSurveyDialogResultType {
|
||||
Closed = "closed",
|
||||
Submitted = "submitted",
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum UpdateLicenseDialogResult {
|
||||
Updated = "updated",
|
||||
Cancelled = "cancelled",
|
||||
|
||||
@@ -7,6 +7,8 @@ import { ReportUnsecuredWebsites } from "./icons/report-unsecured-websites.icon"
|
||||
import { ReportWeakPasswords } from "./icons/report-weak-passwords.icon";
|
||||
import { ReportEntry } from "./shared";
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum ReportType {
|
||||
ExposedPasswords = "exposedPasswords",
|
||||
ReusedPasswords = "reusedPasswords",
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum ReportVariant {
|
||||
Enabled = "Enabled",
|
||||
RequiresPremium = "RequiresPremium",
|
||||
|
||||
@@ -95,6 +95,8 @@ export interface VaultItemDialogParams {
|
||||
restore?: (c: CipherView) => Promise<boolean>;
|
||||
}
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum VaultItemDialogResult {
|
||||
/**
|
||||
* A cipher was saved (created or updated).
|
||||
|
||||
@@ -26,6 +26,8 @@ export interface WebVaultGeneratorDialogResult {
|
||||
generatedValue?: string;
|
||||
}
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum WebVaultGeneratorDialogAction {
|
||||
Selected = "selected",
|
||||
Canceled = "canceled",
|
||||
|
||||
@@ -35,6 +35,8 @@ import { WebCipherFormGenerationService } from "../services/web-cipher-form-gene
|
||||
/**
|
||||
* The result of the AddEditCipherDialogV2 component.
|
||||
*/
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum AddEditCipherDialogResult {
|
||||
Edited = "edited",
|
||||
Added = "added",
|
||||
|
||||
@@ -29,6 +29,8 @@ export interface BulkDeleteDialogParams {
|
||||
unassignedCiphers?: string[];
|
||||
}
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum BulkDeleteDialogResult {
|
||||
Deleted = "deleted",
|
||||
Canceled = "canceled",
|
||||
|
||||
@@ -23,6 +23,8 @@ export interface BulkMoveDialogParams {
|
||||
cipherIds?: string[];
|
||||
}
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum BulkMoveDialogResult {
|
||||
Moved = "moved",
|
||||
Canceled = "canceled",
|
||||
|
||||
@@ -113,6 +113,8 @@ export interface FolderAddEditDialogParams {
|
||||
folderId: string;
|
||||
}
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum FolderAddEditDialogResult {
|
||||
Deleted = "deleted",
|
||||
Canceled = "canceled",
|
||||
|
||||
@@ -17,6 +17,8 @@ import { UserId } from "@bitwarden/common/types/guid";
|
||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
||||
import { PBKDF2KdfConfig, KdfConfigService, KdfType } from "@bitwarden/key-management";
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum VisibleVaultBanner {
|
||||
KDFSettings = "kdf-settings",
|
||||
OutdatedBrowser = "outdated-browser",
|
||||
|
||||
@@ -15,6 +15,8 @@ export type VaultFilterType =
|
||||
| FolderFilter
|
||||
| CollectionFilter;
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum VaultFilterLabel {
|
||||
OrganizationFilter = "organizationFilter",
|
||||
TypeFilter = "typeFilter",
|
||||
|
||||
@@ -54,6 +54,8 @@ export interface ViewCipherDialogParams {
|
||||
disableEdit?: boolean;
|
||||
}
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum ViewCipherDialogResult {
|
||||
Edited = "edited",
|
||||
Deleted = "deleted",
|
||||
|
||||
@@ -7,6 +7,8 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { VaultMessages } from "@bitwarden/common/vault/enums/vault-messages.enum";
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum BrowserPromptState {
|
||||
Loading = "loading",
|
||||
Error = "error",
|
||||
|
||||
Reference in New Issue
Block a user