mirror of
https://github.com/bitwarden/browser
synced 2026-02-09 13:10:17 +00:00
Merge branch 'main' into auth/pm-9115/implement-view-data-persistence-in-2FA-flows
This commit is contained in:
5
.github/workflows/build-cli.yml
vendored
5
.github/workflows/build-cli.yml
vendored
@@ -87,6 +87,7 @@ jobs:
|
||||
os:
|
||||
[
|
||||
{ base: "linux", distro: "ubuntu-22.04", target_suffix: "" },
|
||||
{ base: "linux", distro: "ubuntu-22.04-arm", target_suffix: "-arm64" },
|
||||
{ base: "mac", distro: "macos-13", target_suffix: "" },
|
||||
{ base: "mac", distro: "macos-14", target_suffix: "-arm64" }
|
||||
]
|
||||
@@ -130,7 +131,7 @@ jobs:
|
||||
if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
with:
|
||||
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
workflow: build-wasm-internal.yml
|
||||
workflow_conclusion: success
|
||||
branch: ${{ inputs.sdk_branch }}
|
||||
@@ -306,7 +307,7 @@ jobs:
|
||||
if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
with:
|
||||
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
workflow: build-wasm-internal.yml
|
||||
workflow_conclusion: success
|
||||
branch: ${{ inputs.sdk_branch }}
|
||||
|
||||
111
.github/workflows/build-desktop.yml
vendored
111
.github/workflows/build-desktop.yml
vendored
@@ -201,7 +201,7 @@ jobs:
|
||||
if: ${{ inputs.sdk_branch != '' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
with:
|
||||
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
workflow: build-wasm-internal.yml
|
||||
workflow_conclusion: success
|
||||
branch: ${{ inputs.sdk_branch }}
|
||||
@@ -237,7 +237,7 @@ jobs:
|
||||
TARGET: musl
|
||||
run: |
|
||||
rustup target add x86_64-unknown-linux-musl
|
||||
node build.js cross-platform
|
||||
node build.js --target=x86_64-unknown-linux-musl --release
|
||||
|
||||
- name: Build application
|
||||
run: npm run dist:lin
|
||||
@@ -298,6 +298,103 @@ jobs:
|
||||
if-no-files-found: error
|
||||
|
||||
|
||||
linux-arm64:
|
||||
name: Linux ARM64 Build
|
||||
# Note, before updating the ubuntu version of the workflow, ensure the snap base image
|
||||
# is equal or greater than the new version. Otherwise there might be GLIBC version issues.
|
||||
# The snap base for desktop is defined in `apps/desktop/electron-builder.json`
|
||||
# We intentionally keep this runner on the oldest supported OS in GitHub Actions
|
||||
# for maximum compatibility across GLIBC versions
|
||||
runs-on: ubuntu-22.04-arm
|
||||
needs: setup
|
||||
env:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
|
||||
NODE_OPTIONS: --max_old_space_size=4096
|
||||
defaults:
|
||||
run:
|
||||
working-directory: apps/desktop
|
||||
steps:
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||
with:
|
||||
cache: 'npm'
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
node-version: ${{ env._NODE_VERSION }}
|
||||
|
||||
- name: Set up environment
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install pkg-config libxss-dev rpm musl-dev musl-tools flatpak flatpak-builder
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
node --version
|
||||
npm --version
|
||||
snap --version
|
||||
snapcraft --version || echo 'snapcraft unavailable'
|
||||
|
||||
- name: Install Node dependencies
|
||||
run: npm ci
|
||||
working-directory: ./
|
||||
|
||||
- name: Download SDK Artifacts
|
||||
if: ${{ inputs.sdk_branch != '' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
workflow: build-wasm-internal.yml
|
||||
workflow_conclusion: success
|
||||
branch: ${{ inputs.sdk_branch }}
|
||||
artifacts: sdk-internal
|
||||
repo: bitwarden/sdk-internal
|
||||
path: ../sdk-internal
|
||||
if_no_artifact_found: fail
|
||||
|
||||
- name: Override SDK
|
||||
if: ${{ inputs.sdk_branch != '' }}
|
||||
working-directory: ./
|
||||
run: |
|
||||
ls -l ../
|
||||
npm link ../sdk-internal
|
||||
|
||||
- name: Cache Native Module
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
id: cache
|
||||
with:
|
||||
path: |
|
||||
apps/desktop/desktop_native/napi/*.node
|
||||
apps/desktop/desktop_native/dist/*
|
||||
${{ env.RUNNER_TEMP }}/.cargo/registry
|
||||
${{ env.RUNNER_TEMP }}/.cargo/git
|
||||
key: rust-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('apps/desktop/desktop_native/**/*') }}
|
||||
|
||||
- name: Build Native Module
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
working-directory: apps/desktop/desktop_native
|
||||
env:
|
||||
PKG_CONFIG_ALLOW_CROSS: true
|
||||
PKG_CONFIG_ALL_STATIC: true
|
||||
TARGET: musl
|
||||
run: |
|
||||
rustup target add aarch64-unknown-linux-musl
|
||||
node build.js --target=aarch64-unknown-linux-musl --release
|
||||
|
||||
- name: Build application
|
||||
run: npm run dist:lin:arm64
|
||||
|
||||
- name: Upload tar.gz artifact
|
||||
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
|
||||
with:
|
||||
name: bitwarden_${{ env._PACKAGE_VERSION }}_arm64.tar.gz
|
||||
path: apps/desktop/dist/bitwarden_desktop_arm64.tar.gz
|
||||
if-no-files-found: error
|
||||
|
||||
windows:
|
||||
name: Windows Build
|
||||
runs-on: windows-2022
|
||||
@@ -369,7 +466,7 @@ jobs:
|
||||
if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
with:
|
||||
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
workflow: build-wasm-internal.yml
|
||||
workflow_conclusion: success
|
||||
branch: ${{ inputs.sdk_branch }}
|
||||
@@ -705,7 +802,7 @@ jobs:
|
||||
if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
with:
|
||||
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
workflow: build-wasm-internal.yml
|
||||
workflow_conclusion: success
|
||||
branch: ${{ inputs.sdk_branch }}
|
||||
@@ -895,7 +992,7 @@ jobs:
|
||||
if: ${{ inputs.sdk_branch != '' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
with:
|
||||
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
workflow: build-wasm-internal.yml
|
||||
workflow_conclusion: success
|
||||
branch: ${{ inputs.sdk_branch }}
|
||||
@@ -1144,7 +1241,7 @@ jobs:
|
||||
if: ${{ inputs.sdk_branch != '' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
with:
|
||||
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
workflow: build-wasm-internal.yml
|
||||
workflow_conclusion: success
|
||||
branch: ${{ inputs.sdk_branch }}
|
||||
@@ -1425,7 +1522,7 @@ jobs:
|
||||
if: ${{ inputs.sdk_branch != '' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
with:
|
||||
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
workflow: build-wasm-internal.yml
|
||||
workflow_conclusion: success
|
||||
branch: ${{ inputs.sdk_branch }}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { html, TemplateResult } from "lit";
|
||||
import { Theme } from "@bitwarden/common/platform/enums";
|
||||
|
||||
import { themes } from "../../../content/components/constants/styles";
|
||||
import { Business, Users } from "../../../content/components/icons";
|
||||
import { Business, Family } from "../../../content/components/icons";
|
||||
|
||||
import { OrganizationCategories, OrganizationCategory } from "./types";
|
||||
|
||||
@@ -13,7 +13,7 @@ const cipherIndicatorIconsMap: Record<
|
||||
(args: { color: string; theme: Theme }) => TemplateResult
|
||||
> = {
|
||||
[OrganizationCategories.business]: Business,
|
||||
[OrganizationCategories.family]: Users,
|
||||
[OrganizationCategories.family]: Family,
|
||||
};
|
||||
|
||||
export function CipherInfoIndicatorIcons({
|
||||
|
||||
@@ -4,14 +4,14 @@ import { html } from "lit";
|
||||
import { IconProps } from "../common-types";
|
||||
import { buildIconColorRule, ruleNames, themes } from "../constants/styles";
|
||||
|
||||
export function Collection({ color, disabled, theme }: IconProps) {
|
||||
export function CollectionShared({ color, disabled, theme }: IconProps) {
|
||||
const shapeColor = disabled ? themes[theme].secondary["300"] : color || themes[theme].text.main;
|
||||
|
||||
return html`
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14" fill="none">
|
||||
<path
|
||||
class=${css(buildIconColorRule(shapeColor, ruleNames.fill))}
|
||||
d="M3.5.75A.75.75 0 0 1 4.25 0h5.5a.75.75 0 0 1 0 1.5h-5.5A.75.75 0 0 1 3.5.75ZM2.25 2a.75.75 0 0 0 0 1.5h9.5a.75.75 0 0 0 0-1.5h-9.5Z"
|
||||
d="M3.5.75A.75.75 0 0 1 4.25 0h5.5a.75.75 0 0 1 0 1.5h-5.5A.75.75 0 0 1 3.5.75ZM2.25 2a.75.75 0 0 0 0 1.5h9.5a.75.75 0 0 0 0-1.5h-9.5ZM6 8a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM10 8a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM7 11.46a1.928 1.928 0 0 0-.586-1.386 2.035 2.035 0 0 0-2.828 0A1.928 1.928 0 0 0 3 11.461c0 .298.241.539.54.539h2.92a.54.54 0 0 0 .54-.54ZM8 11.46a2.928 2.928 0 0 0-.371-1.426A2.005 2.005 0 0 1 9 9.5a2.035 2.035 0 0 1 1.414.574A1.928 1.928 0 0 1 11 11.461a.54.54 0 0 1-.54.539H7.904c.063-.168.097-.35.097-.54Z"
|
||||
/>
|
||||
<path
|
||||
class=${css(buildIconColorRule(shapeColor, ruleNames.fill))}
|
||||
19
apps/browser/src/autofill/content/components/icons/family.ts
Normal file
19
apps/browser/src/autofill/content/components/icons/family.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { css } from "@emotion/css";
|
||||
import { html } from "lit";
|
||||
|
||||
import { IconProps } from "../common-types";
|
||||
import { buildIconColorRule, ruleNames, themes } from "../constants/styles";
|
||||
|
||||
export function Family({ color, disabled, theme }: IconProps) {
|
||||
const shapeColor = disabled ? themes[theme].secondary["300"] : color || themes[theme].text.main;
|
||||
|
||||
return html`
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none">
|
||||
<path
|
||||
class=${css(buildIconColorRule(shapeColor, ruleNames.fill))}
|
||||
fill-rule="evenodd"
|
||||
d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0Zm-1.5 0a6.47 6.47 0 0 1-.932 3.356 3.732 3.732 0 0 0-1.106-.784 3.547 3.547 0 0 0-.516-.19 2 2 0 1 0-3.444-1.297c-.323-.216-.681-.4-1.069-.536a2.5 2.5 0 1 0-3.065-.155 5.405 5.405 0 0 0-1.59.674 3.912 3.912 0 0 0-.977.893A6.5 6.5 0 1 1 14.5 8ZM2.531 11.514a.75.75 0 0 0 .103-.13c.276-.436.552-.801.942-1.047a3.837 3.837 0 0 1 1.177-.492 5.243 5.243 0 0 1 .845-.095h.007l.022.001h.023c.436 0 .865.07 1.262.205.381.13.733.335 1.037.584.175.143.324.3.448.465l.164.226a4.13 4.13 0 0 0-1.035 1.565 4.407 4.407 0 0 0-.276 1.537c0 .043.004.085.01.125a6.5 6.5 0 0 1-4.729-2.944Zm10.033.964.07.08a6.481 6.481 0 0 1-3.894 1.9.757.757 0 0 0 .01-.125c0-.35.062-.694.181-1.013a2.63 2.63 0 0 1 .505-.842c.213-.237.462-.42.73-.543.267-.123.55-.185.834-.185.284 0 .567.062.835.185.267.123.516.306.729.543ZM7 6.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM11 9a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0Z"
|
||||
/>
|
||||
</svg>
|
||||
`;
|
||||
}
|
||||
@@ -3,12 +3,12 @@ export { AngleUp } from "./angle-up";
|
||||
export { BrandIconContainer } from "./brand-icon-container";
|
||||
export { Business } from "./business";
|
||||
export { Close } from "./close";
|
||||
export { Collection } from "./collection";
|
||||
export { CollectionShared } from "./collection-shared";
|
||||
export { ExclamationTriangle } from "./exclamation-triangle";
|
||||
export { ExternalLink } from "./external-link";
|
||||
export { Family } from "./family";
|
||||
export { Folder } from "./folder";
|
||||
export { Globe } from "./globe";
|
||||
export { PencilSquare } from "./pencil-square";
|
||||
export { Shield } from "./shield";
|
||||
export { User } from "./user";
|
||||
export { Users } from "./users";
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { css } from "@emotion/css";
|
||||
import { html } from "lit";
|
||||
|
||||
import { IconProps } from "../common-types";
|
||||
import { buildIconColorRule, ruleNames, themes } from "../constants/styles";
|
||||
|
||||
export function Users({ color, disabled, theme }: IconProps) {
|
||||
const shapeColor = disabled ? themes[theme].secondary["300"] : color || themes[theme].text.main;
|
||||
|
||||
return html`
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 14" fill="none">
|
||||
<path
|
||||
class=${css(buildIconColorRule(shapeColor, ruleNames.fill))}
|
||||
d="M6.5 2.5c0 .375-.082.73-.23 1.049A2.986 2.986 0 0 1 8 3c.644 0 1.241.203 1.73.549a2.5 2.5 0 1 1 3.925.825 4 4 0 0 1 1.173.846c.372.387.667.847.867 1.352.201.506.305 1.047.305 1.595 0 .46-.373.833-.833.833H11a4.987 4.987 0 0 1 1.62 2.087A5 5 0 0 1 13 13a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1 5 5 0 0 1 2-4H.833A.833.833 0 0 1 0 8.167c0-.548.103-1.09.304-1.595.202-.505.496-.965.868-1.352.339-.353.736-.64 1.173-.846A2.5 2.5 0 1 1 6.5 2.5ZM4 3.5a1 1 0 1 0 0-2 1 1 0 0 0 0 2Zm1.401 4a2.986 2.986 0 0 1-.389-1.771A2.404 2.404 0 0 0 4 5.5c-.32 0-.638.065-.936.194-.3.13-.575.32-.81.565A2.682 2.682 0 0 0 1.579 7.5h3.822Zm5.198 0h3.822a2.682 2.682 0 0 0-.674-1.24 2.493 2.493 0 0 0-.81-.566 2.362 2.362 0 0 0-1.95.035 2.987 2.987 0 0 1-.39 1.771ZM12 3.5a1 1 0 1 0 0-2 1 1 0 0 0 0 2Zm-4 4a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm3.464 5a3.5 3.5 0 0 0-6.928 0h6.928Z"
|
||||
/>
|
||||
</svg>
|
||||
`;
|
||||
}
|
||||
@@ -43,26 +43,23 @@ const createIconStory = (iconName: keyof typeof Icons): StoryObj<Args> => {
|
||||
render: (args) => Template(args, Icons[iconName]),
|
||||
} as StoryObj<Args>;
|
||||
|
||||
if (iconName !== "BrandIconContainer") {
|
||||
story.argTypes = {
|
||||
iconLink: { table: { disable: true } },
|
||||
};
|
||||
}
|
||||
story.argTypes = {
|
||||
iconLink: { table: { disable: true } },
|
||||
};
|
||||
|
||||
return story;
|
||||
};
|
||||
|
||||
export const AngleDownIcon = createIconStory("AngleDown");
|
||||
export const AngleUpIcon = createIconStory("AngleUp");
|
||||
export const BrandIcon = createIconStory("BrandIconContainer");
|
||||
export const BusinessIcon = createIconStory("Business");
|
||||
export const CloseIcon = createIconStory("Close");
|
||||
export const CollectionIcon = createIconStory("Collection");
|
||||
export const CollectionSharedIcon = createIconStory("CollectionShared");
|
||||
export const ExclamationTriangleIcon = createIconStory("ExclamationTriangle");
|
||||
export const ExternalLinkIcon = createIconStory("ExternalLink");
|
||||
export const FamilyIcon = createIconStory("Family");
|
||||
export const FolderIcon = createIconStory("Folder");
|
||||
export const GlobeIcon = createIconStory("Globe");
|
||||
export const PencilSquareIcon = createIconStory("PencilSquare");
|
||||
export const ShieldIcon = createIconStory("Shield");
|
||||
export const UserIcon = createIconStory("User");
|
||||
export const UsersIcon = createIconStory("Users");
|
||||
|
||||
@@ -4,14 +4,14 @@ import { ProductTierType } from "@bitwarden/common/billing/enums";
|
||||
import { Theme } from "@bitwarden/common/platform/enums";
|
||||
|
||||
import { Option, OrgView, FolderView } from "../common-types";
|
||||
import { Business, Users, Folder, User } from "../icons";
|
||||
import { Business, Family, Folder, User } from "../icons";
|
||||
import { ButtonRow } from "../rows/button-row";
|
||||
|
||||
function getVaultIconByProductTier(productTierType?: ProductTierType): Option["icon"] {
|
||||
switch (productTierType) {
|
||||
case ProductTierType.Free:
|
||||
case ProductTierType.Families:
|
||||
return Users;
|
||||
return Family;
|
||||
case ProductTierType.Teams:
|
||||
case ProductTierType.Enterprise:
|
||||
case ProductTierType.TeamsStarter:
|
||||
|
||||
@@ -18,7 +18,11 @@ export class BackgroundCommunicationBackend implements CommunicationBackend {
|
||||
return;
|
||||
}
|
||||
|
||||
void this.queue.enqueue({ ...message.message, source: { Web: { id: sender.tab.id } } });
|
||||
void this.queue.enqueue(
|
||||
new IncomingMessage(message.message.payload, message.message.destination, {
|
||||
Web: { id: sender.tab.id },
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -593,6 +593,7 @@ const routes: Routes = [
|
||||
path: "intro-carousel",
|
||||
component: ExtensionAnonLayoutWrapperComponent,
|
||||
canActivate: [],
|
||||
data: { elevation: 0, doNotSaveUrl: true } satisfies RouteDataProperties,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
bitButton
|
||||
buttonType="secondary"
|
||||
(click)="navigateToLogin()"
|
||||
class="tw-w-full tw-mt-4"
|
||||
class="tw-w-full tw-mt-2"
|
||||
>
|
||||
{{ "logIn" | i18n }}
|
||||
</button>
|
||||
|
||||
@@ -34,18 +34,22 @@
|
||||
"dist:oss:mac": "npm run build:oss:prod && npm run clean && npm run package:oss:mac",
|
||||
"dist:oss:mac-arm64": "npm run build:oss:prod && npm run clean && npm run package:oss:mac-arm64",
|
||||
"dist:oss:lin": "npm run build:oss:prod && npm run clean && npm run package:oss:lin",
|
||||
"dist:oss:lin-arm64": "npm run build:oss:prod && npm run clean && npm run package:oss:lin-arm64",
|
||||
"dist:bit:win": "npm run build:bit:prod && npm run clean && npm run package:bit:win",
|
||||
"dist:bit:mac": "npm run build:bit:prod && npm run clean && npm run package:bit:mac",
|
||||
"dist:bit:mac-arm64": "npm run build:bit:prod && npm run clean && npm run package:bit:mac-arm64",
|
||||
"dist:bit:lin": "npm run build:bit:prod && npm run clean && npm run package:bit:lin",
|
||||
"dist:bit:lin-arm64": "npm run build:bit:prod && npm run clean && npm run package:bit:lin-arm64",
|
||||
"package:oss:win": "pkg . --targets win-x64 --output ./dist/oss/windows/bw.exe",
|
||||
"package:oss:mac": "pkg . --targets macos-x64 --output ./dist/oss/macos/bw",
|
||||
"package:oss:mac-arm64": "pkg . --targets macos-arm64 --output ./dist/oss/macos-arm64/bw",
|
||||
"package:oss:lin": "pkg . --targets linux-x64 --output ./dist/oss/linux/bw",
|
||||
"package:oss:lin-arm64": "pkg . --targets linux-arm64 --output ./dist/oss/linux-arm64/bw",
|
||||
"package:bit:win": "pkg . --targets win-x64 --output ./dist/bit/windows/bw.exe",
|
||||
"package:bit:mac": "pkg . --targets macos-x64 --output ./dist/bit/macos/bw",
|
||||
"package:bit:mac-arm64": "pkg . --targets macos-arm64 --output ./dist/bit/macos-arm64/bw",
|
||||
"package:bit:lin": "pkg . --targets linux-x64 --output ./dist/bit/linux/bw",
|
||||
"package:bit:lin-arm64": "pkg . --targets linux-arm64 --output ./dist/bit/linux-arm64/bw",
|
||||
"test": "jest",
|
||||
"test:watch": "jest --watch",
|
||||
"test:watch:all": "jest --watchAll"
|
||||
@@ -72,7 +76,7 @@
|
||||
"inquirer": "8.2.6",
|
||||
"jsdom": "26.0.0",
|
||||
"jszip": "3.10.1",
|
||||
"koa": "2.15.4",
|
||||
"koa": "2.16.1",
|
||||
"koa-bodyparser": "4.4.1",
|
||||
"koa-json": "2.0.2",
|
||||
"lowdb": "1.0.0",
|
||||
|
||||
@@ -10,8 +10,6 @@ import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { EventType } from "@bitwarden/common/enums";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import {
|
||||
ExportFormat,
|
||||
@@ -30,7 +28,6 @@ export class ExportCommand {
|
||||
private policyService: PolicyService,
|
||||
private eventCollectionService: EventCollectionService,
|
||||
private accountService: AccountService,
|
||||
private configService: ConfigService,
|
||||
) {}
|
||||
|
||||
async run(options: OptionValues): Promise<Response> {
|
||||
@@ -55,13 +52,6 @@ export class ExportCommand {
|
||||
const format =
|
||||
password && options.format == "json" ? "encrypted_json" : (options.format ?? "csv");
|
||||
|
||||
if (
|
||||
format == "zip" &&
|
||||
!(await this.configService.getFeatureFlag(FeatureFlag.ExportAttachments))
|
||||
) {
|
||||
return Response.badRequest("Exporting attachments is not supported in this environment.");
|
||||
}
|
||||
|
||||
if (!this.isSupportedExportFormat(format)) {
|
||||
return Response.badRequest(
|
||||
`'${format}' is not a supported export format. Supported formats: ${EXPORT_FORMATS.join(
|
||||
|
||||
@@ -464,7 +464,7 @@ export class VaultProgram extends BaseProgram {
|
||||
|
||||
private exportCommand(): Command {
|
||||
return new Command("export")
|
||||
.description("Export vault data to a CSV or JSON file.")
|
||||
.description("Export vault data to a CSV, JSON or ZIP file.")
|
||||
.option("--output <output>", "Output directory or filename.")
|
||||
.option("--format <format>", "Export file format.")
|
||||
.option(
|
||||
@@ -476,7 +476,7 @@ export class VaultProgram extends BaseProgram {
|
||||
writeLn("\n Notes:");
|
||||
writeLn("");
|
||||
writeLn(
|
||||
" Valid formats are `csv`, `json`, and `encrypted_json`. Default format is `csv`.",
|
||||
" Valid formats are `csv`, `json`, `encrypted_json` and zip. Default format is `csv`.",
|
||||
);
|
||||
writeLn("");
|
||||
writeLn(
|
||||
@@ -504,7 +504,6 @@ export class VaultProgram extends BaseProgram {
|
||||
this.serviceContainer.policyService,
|
||||
this.serviceContainer.eventCollectionService,
|
||||
this.serviceContainer.accountService,
|
||||
this.serviceContainer.configService,
|
||||
);
|
||||
const response = await command.run(options);
|
||||
this.processResponse(response);
|
||||
|
||||
@@ -3,6 +3,10 @@ const child_process = require("child_process");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const process = require("process");
|
||||
const args = process.argv.slice(2); // Get arguments passed to the script
|
||||
const mode = args.includes("--release") ? "release" : "debug";
|
||||
const targetArg = args.find(arg => arg.startsWith("--target="));
|
||||
const target = targetArg ? targetArg.split("=")[1] : null;
|
||||
|
||||
let crossPlatform = process.argv.length > 2 && process.argv[2] === "cross-platform";
|
||||
|
||||
@@ -18,10 +22,17 @@ function buildProxyBin(target, release = true) {
|
||||
return child_process.execSync(`cargo build --bin desktop_proxy ${releaseArg} ${targetArg}`, {stdio: 'inherit', cwd: path.join(__dirname, "proxy")});
|
||||
}
|
||||
|
||||
if (!crossPlatform) {
|
||||
console.log("Building native modules in debug mode for the native architecture");
|
||||
buildNapiModule(false, false);
|
||||
buildProxyBin(false, false);
|
||||
if (!crossPlatform && !target) {
|
||||
console.log(`Building native modules in ${mode} mode for the native architecture`);
|
||||
buildNapiModule(false, mode === "release");
|
||||
buildProxyBin(false, mode === "release");
|
||||
return;
|
||||
}
|
||||
|
||||
if (target) {
|
||||
console.log(`Building for target: ${target} in ${mode} mode`);
|
||||
buildNapiModule(target, mode === "release");
|
||||
buildProxyBin(target, mode === "release");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -47,7 +58,8 @@ switch (process.platform) {
|
||||
|
||||
default:
|
||||
targets = [
|
||||
['x86_64-unknown-linux-musl', 'x64']
|
||||
['x86_64-unknown-linux-musl', 'x64'],
|
||||
['aarch64-unknown-linux-musl', 'arm64']
|
||||
];
|
||||
|
||||
process.env["PKG_CONFIG_ALLOW_CROSS"] = "1";
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"pack:dir": "npm run clean:dist && electron-builder --dir -p never",
|
||||
"pack:lin:flatpak": "npm run clean:dist && electron-builder --dir -p never && flatpak-builder --repo=build/.repo build/.flatpak ./resources/com.bitwarden.desktop.devel.yaml --install-deps-from=flathub --force-clean && flatpak build-bundle ./build/.repo/ ./dist/com.bitwarden.desktop.flatpak com.bitwarden.desktop",
|
||||
"pack:lin": "npm run clean:dist && electron-builder --linux --x64 -p never && export SNAP_FILE=$(realpath ./dist/bitwarden_*.snap) && unsquashfs -d ./dist/tmp-snap/ $SNAP_FILE && mkdir -p ./dist/tmp-snap/meta/polkit/ && cp ./resources/com.bitwarden.desktop.policy ./dist/tmp-snap/meta/polkit/polkit.com.bitwarden.desktop.policy && rm $SNAP_FILE && snapcraft pack ./dist/tmp-snap/ && mv ./*.snap ./dist/ && rm -rf ./dist/tmp-snap/",
|
||||
"pack:lin:arm64": "npm run clean:dist && electron-builder --dir -p never && tar -czvf ./dist/bitwarden_desktop_arm64.tar.gz -C ./dist/linux-arm64-unpacked/ .",
|
||||
"pack:mac": "npm run clean:dist && electron-builder --mac --universal -p never",
|
||||
"pack:mac:arm64": "npm run clean:dist && electron-builder --mac --arm64 -p never",
|
||||
"pack:mac:mas": "npm run clean:dist && electron-builder --mac mas --universal -p never",
|
||||
@@ -45,6 +46,7 @@
|
||||
"pack:win:ci": "npm run clean:dist && electron-builder --win --x64 --arm64 --ia32 -p never",
|
||||
"dist:dir": "npm run build && npm run pack:dir",
|
||||
"dist:lin": "npm run build && npm run pack:lin",
|
||||
"dist:lin:arm64": "npm run build && npm run pack:lin:arm64",
|
||||
"dist:mac": "npm run build && npm run pack:mac",
|
||||
"dist:mac:mas": "npm run build && npm run pack:mac:mas",
|
||||
"dist:mac:masdev": "npm run build && npm run pack:mac:masdev",
|
||||
|
||||
@@ -3,9 +3,10 @@ import { RouterModule, Routes } from "@angular/router";
|
||||
|
||||
import { canAccessMembersTab } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
|
||||
import { SponsoredFamiliesComponent } from "../../../billing/settings/sponsored-families.component";
|
||||
import { FreeBitwardenFamiliesComponent } from "../../../billing/members/free-bitwarden-families.component";
|
||||
import { organizationPermissionsGuard } from "../guards/org-permissions.guard";
|
||||
|
||||
import { canAccessSponsoredFamilies } from "./../../../billing/guards/can-access-sponsored-families.guard";
|
||||
import { MembersComponent } from "./members.component";
|
||||
|
||||
const routes: Routes = [
|
||||
@@ -19,8 +20,8 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: "sponsored-families",
|
||||
component: SponsoredFamiliesComponent,
|
||||
canActivate: [organizationPermissionsGuard(canAccessMembersTab)],
|
||||
component: FreeBitwardenFamiliesComponent,
|
||||
canActivate: [organizationPermissionsGuard(canAccessMembersTab), canAccessSponsoredFamilies],
|
||||
data: {
|
||||
titleId: "sponsoredFamilies",
|
||||
},
|
||||
|
||||
@@ -43,6 +43,8 @@ export class FamiliesForEnterpriseSetupComponent implements OnInit, OnDestroy {
|
||||
value.plan = PlanType.FamiliesAnnually;
|
||||
value.productTier = ProductTierType.Families;
|
||||
value.acceptingSponsorship = true;
|
||||
value.planSponsorshipType = PlanSponsorshipType.FamiliesForEnterprise;
|
||||
|
||||
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
|
||||
value.onSuccess.subscribe(this.onOrganizationCreateSuccess.bind(this));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { inject } from "@angular/core";
|
||||
import { ActivatedRouteSnapshot, CanActivateFn } from "@angular/router";
|
||||
import { firstValueFrom, switchMap, filter } from "rxjs";
|
||||
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { getById } from "@bitwarden/common/platform/misc";
|
||||
|
||||
import { FreeFamiliesPolicyService } from "../services/free-families-policy.service";
|
||||
|
||||
export const canAccessSponsoredFamilies: CanActivateFn = async (route: ActivatedRouteSnapshot) => {
|
||||
const freeFamiliesPolicyService = inject(FreeFamiliesPolicyService);
|
||||
const organizationService = inject(OrganizationService);
|
||||
const accountService = inject(AccountService);
|
||||
|
||||
const org = accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) => organizationService.organizations$(userId)),
|
||||
getById(route.params.organizationId),
|
||||
filter((org): org is Organization => org !== undefined),
|
||||
);
|
||||
|
||||
return await firstValueFrom(freeFamiliesPolicyService.showSponsoredFamiliesDropdown$(org));
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
<form>
|
||||
<bit-dialog>
|
||||
<span bitDialogTitle>{{ "addSponsorship" | i18n }}</span>
|
||||
|
||||
<div bitDialogContent>
|
||||
<form [formGroup]="sponsorshipForm">
|
||||
<div class="tw-grid tw-grid-cols-12 tw-gap-4">
|
||||
<div class="tw-col-span-12">
|
||||
<bit-form-field>
|
||||
<bit-label>{{ "email" | i18n }}:</bit-label>
|
||||
<input
|
||||
bitInput
|
||||
inputmode="email"
|
||||
formControlName="sponsorshipEmail"
|
||||
[attr.aria-invalid]="sponsorshipEmailControl.invalid"
|
||||
appInputStripSpaces
|
||||
/>
|
||||
</bit-form-field>
|
||||
</div>
|
||||
<div class="tw-col-span-12">
|
||||
<bit-form-field>
|
||||
<bit-label>{{ "notes" | i18n }}:</bit-label>
|
||||
<input
|
||||
bitInput
|
||||
inputmode="text"
|
||||
formControlName="sponsorshipNote"
|
||||
[attr.aria-invalid]="sponsorshipNoteControl.invalid"
|
||||
appInputStripSpaces
|
||||
/>
|
||||
</bit-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<ng-container bitDialogFooter>
|
||||
<button bitButton bitFormButton type="button" buttonType="primary" (click)="save()">
|
||||
{{ "save" | i18n }}
|
||||
</button>
|
||||
<button bitButton type="button" buttonType="secondary" [bitDialogClose]="false">
|
||||
{{ "cancel" | i18n }}
|
||||
</button>
|
||||
</ng-container>
|
||||
</bit-dialog>
|
||||
</form>
|
||||
@@ -0,0 +1,135 @@
|
||||
import { DialogRef } from "@angular/cdk/dialog";
|
||||
import { Component } from "@angular/core";
|
||||
import {
|
||||
AbstractControl,
|
||||
FormBuilder,
|
||||
FormControl,
|
||||
FormGroup,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
ValidationErrors,
|
||||
Validators,
|
||||
} from "@angular/forms";
|
||||
import { firstValueFrom, map } from "rxjs";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { ButtonModule, DialogModule, DialogService, FormFieldModule } from "@bitwarden/components";
|
||||
|
||||
interface RequestSponsorshipForm {
|
||||
sponsorshipEmail: FormControl<string | null>;
|
||||
sponsorshipNote: FormControl<string | null>;
|
||||
}
|
||||
|
||||
export interface AddSponsorshipDialogResult {
|
||||
action: AddSponsorshipDialogAction;
|
||||
value: Partial<AddSponsorshipFormValue> | null;
|
||||
}
|
||||
|
||||
interface AddSponsorshipFormValue {
|
||||
sponsorshipEmail: string;
|
||||
sponsorshipNote: string;
|
||||
status: string;
|
||||
}
|
||||
|
||||
enum AddSponsorshipDialogAction {
|
||||
Saved = "saved",
|
||||
Canceled = "canceled",
|
||||
}
|
||||
|
||||
@Component({
|
||||
templateUrl: "add-sponsorship-dialog.component.html",
|
||||
standalone: true,
|
||||
imports: [
|
||||
JslibModule,
|
||||
ButtonModule,
|
||||
DialogModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
FormFieldModule,
|
||||
],
|
||||
})
|
||||
export class AddSponsorshipDialogComponent {
|
||||
sponsorshipForm: FormGroup<RequestSponsorshipForm>;
|
||||
loading = false;
|
||||
|
||||
constructor(
|
||||
private dialogRef: DialogRef<AddSponsorshipDialogResult>,
|
||||
private formBuilder: FormBuilder,
|
||||
private accountService: AccountService,
|
||||
private i18nService: I18nService,
|
||||
) {
|
||||
this.sponsorshipForm = this.formBuilder.group<RequestSponsorshipForm>({
|
||||
sponsorshipEmail: new FormControl<string | null>("", {
|
||||
validators: [Validators.email, Validators.required],
|
||||
asyncValidators: [this.validateNotCurrentUserEmail.bind(this)],
|
||||
updateOn: "change",
|
||||
}),
|
||||
sponsorshipNote: new FormControl<string | null>("", {}),
|
||||
});
|
||||
}
|
||||
|
||||
static open(dialogService: DialogService): DialogRef<AddSponsorshipDialogResult> {
|
||||
return dialogService.open<AddSponsorshipDialogResult>(AddSponsorshipDialogComponent);
|
||||
}
|
||||
|
||||
protected async save() {
|
||||
if (this.sponsorshipForm.invalid) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
// TODO: This is a mockup implementation - needs to be updated with actual API integration
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000)); // Simulate API call
|
||||
|
||||
const formValue = this.sponsorshipForm.getRawValue();
|
||||
const dialogValue: Partial<AddSponsorshipFormValue> = {
|
||||
status: "Sent",
|
||||
sponsorshipEmail: formValue.sponsorshipEmail ?? "",
|
||||
sponsorshipNote: formValue.sponsorshipNote ?? "",
|
||||
};
|
||||
|
||||
this.dialogRef.close({
|
||||
action: AddSponsorshipDialogAction.Saved,
|
||||
value: dialogValue,
|
||||
});
|
||||
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
protected close = () => {
|
||||
this.dialogRef.close({ action: AddSponsorshipDialogAction.Canceled, value: null });
|
||||
};
|
||||
|
||||
get sponsorshipEmailControl() {
|
||||
return this.sponsorshipForm.controls.sponsorshipEmail;
|
||||
}
|
||||
|
||||
get sponsorshipNoteControl() {
|
||||
return this.sponsorshipForm.controls.sponsorshipNote;
|
||||
}
|
||||
|
||||
private async validateNotCurrentUserEmail(
|
||||
control: AbstractControl,
|
||||
): Promise<ValidationErrors | null> {
|
||||
const value = control.value;
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const currentUserEmail = await firstValueFrom(
|
||||
this.accountService.activeAccount$.pipe(map((a) => a?.email ?? "")),
|
||||
);
|
||||
|
||||
if (!currentUserEmail) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (value.toLowerCase() === currentUserEmail.toLowerCase()) {
|
||||
return { currentUserEmail: true };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<app-header>
|
||||
<button type="button" (click)="addSponsorship()" bitButton buttonType="primary">
|
||||
<i class="bwi bwi-plus bwi-fw" aria-hidden="true"></i>
|
||||
{{ "addSponsorship" | i18n }}
|
||||
</button>
|
||||
</app-header>
|
||||
|
||||
<bit-tab-group [(selectedIndex)]="tabIndex">
|
||||
<bit-tab [label]="'sponsoredBitwardenFamilies' | i18n">
|
||||
<app-organization-sponsored-families
|
||||
[sponsoredFamilies]="sponsoredFamilies"
|
||||
(removeSponsorshipEvent)="removeSponsorhip($event)"
|
||||
></app-organization-sponsored-families>
|
||||
</bit-tab>
|
||||
|
||||
<bit-tab [label]="'memberFamilies' | i18n">
|
||||
<app-organization-member-families
|
||||
[memberFamilies]="sponsoredFamilies"
|
||||
></app-organization-member-families>
|
||||
</bit-tab>
|
||||
</bit-tab-group>
|
||||
|
||||
<p class="tw-px-4" bitTypography="body2">{{ "sponsoredFamiliesRemoveActiveSponsorship" | i18n }}</p>
|
||||
@@ -0,0 +1,62 @@
|
||||
import { DialogRef } from "@angular/cdk/dialog";
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
|
||||
import { FreeFamiliesPolicyService } from "../services/free-families-policy.service";
|
||||
|
||||
import {
|
||||
AddSponsorshipDialogComponent,
|
||||
AddSponsorshipDialogResult,
|
||||
} from "./add-sponsorship-dialog.component";
|
||||
import { SponsoredFamily } from "./types/sponsored-family";
|
||||
|
||||
@Component({
|
||||
selector: "app-free-bitwarden-families",
|
||||
templateUrl: "free-bitwarden-families.component.html",
|
||||
})
|
||||
export class FreeBitwardenFamiliesComponent implements OnInit {
|
||||
tabIndex = 0;
|
||||
sponsoredFamilies: SponsoredFamily[] = [];
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private dialogService: DialogService,
|
||||
private freeFamiliesPolicyService: FreeFamiliesPolicyService,
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
await this.preventAccessToFreeFamiliesPage();
|
||||
}
|
||||
|
||||
async addSponsorship() {
|
||||
const addSponsorshipDialogRef: DialogRef<AddSponsorshipDialogResult> =
|
||||
AddSponsorshipDialogComponent.open(this.dialogService);
|
||||
|
||||
const dialogRef = await firstValueFrom(addSponsorshipDialogRef.closed);
|
||||
|
||||
if (dialogRef?.value) {
|
||||
this.sponsoredFamilies = [dialogRef.value, ...this.sponsoredFamilies];
|
||||
}
|
||||
}
|
||||
|
||||
removeSponsorhip(sponsorship: any) {
|
||||
const index = this.sponsoredFamilies.findIndex(
|
||||
(e) => e.sponsorshipEmail == sponsorship.sponsorshipEmail,
|
||||
);
|
||||
this.sponsoredFamilies.splice(index, 1);
|
||||
}
|
||||
|
||||
private async preventAccessToFreeFamiliesPage() {
|
||||
const showFreeFamiliesPage = await firstValueFrom(
|
||||
this.freeFamiliesPolicyService.showFreeFamilies$,
|
||||
);
|
||||
|
||||
if (!showFreeFamiliesPage) {
|
||||
await this.router.navigate(["/"]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<bit-container>
|
||||
<ng-container>
|
||||
<p bitTypography="body1">
|
||||
{{ "membersWithSponsoredFamilies" | i18n }}
|
||||
</p>
|
||||
|
||||
<h2 bitTypography="h2" class="">{{ "memberFamilies" | i18n }}</h2>
|
||||
|
||||
@if (loading) {
|
||||
<ng-container>
|
||||
<i class="bwi bwi-spinner bwi-spin tw-text-muted" title="{{ 'loading' | i18n }}"></i>
|
||||
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
@if (!loading && memberFamilies?.length > 0) {
|
||||
<ng-container>
|
||||
<bit-table>
|
||||
<ng-container header>
|
||||
<tr>
|
||||
<th bitCell>{{ "member" | i18n }}</th>
|
||||
<th bitCell>{{ "status" | i18n }}</th>
|
||||
<th bitCell></th>
|
||||
</tr>
|
||||
</ng-container>
|
||||
<ng-template body alignContent="middle">
|
||||
@for (o of memberFamilies; let i = $index; track i) {
|
||||
<ng-container>
|
||||
<tr bitRow>
|
||||
<td bitCell>{{ o.sponsorshipEmail }}</td>
|
||||
<td bitCell class="tw-text-success">{{ o.status }}</td>
|
||||
</tr>
|
||||
</ng-container>
|
||||
}
|
||||
</ng-template>
|
||||
</bit-table>
|
||||
<hr class="mt-0" />
|
||||
</ng-container>
|
||||
} @else {
|
||||
<div class="tw-my-5 tw-py-5 tw-flex tw-flex-col tw-items-center">
|
||||
<img class="tw-w-32" src="./../../../images/search.svg" alt="Search" />
|
||||
<h4 class="mt-3" bitTypography="h4">{{ "noMemberFamilies" | i18n }}</h4>
|
||||
<p bitTypography="body2">{{ "noMemberFamiliesDescription" | i18n }}</p>
|
||||
</div>
|
||||
}
|
||||
</ng-container>
|
||||
</bit-container>
|
||||
@@ -0,0 +1,34 @@
|
||||
import { Component, Input, OnDestroy, OnInit } from "@angular/core";
|
||||
import { Subject } from "rxjs";
|
||||
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
|
||||
import { SponsoredFamily } from "./types/sponsored-family";
|
||||
|
||||
@Component({
|
||||
selector: "app-organization-member-families",
|
||||
templateUrl: "organization-member-families.component.html",
|
||||
})
|
||||
export class OrganizationMemberFamiliesComponent implements OnInit, OnDestroy {
|
||||
tabIndex = 0;
|
||||
loading = false;
|
||||
|
||||
@Input() memberFamilies: SponsoredFamily[] = [];
|
||||
|
||||
private _destroy = new Subject<void>();
|
||||
|
||||
constructor(private platformUtilsService: PlatformUtilsService) {}
|
||||
|
||||
async ngOnInit() {
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this._destroy.next();
|
||||
this._destroy.complete();
|
||||
}
|
||||
|
||||
get isSelfHosted(): boolean {
|
||||
return this.platformUtilsService.isSelfHost();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<bit-container>
|
||||
<ng-container>
|
||||
<p bitTypography="body1">
|
||||
{{ "sponsorFreeBitwardenFamilies" | i18n }}
|
||||
</p>
|
||||
<div bitTypography="body1">
|
||||
{{ "sponsoredFamiliesInclude" | i18n }}:
|
||||
<ul class="tw-list-outside">
|
||||
<li>{{ "sponsoredFamiliesPremiumAccess" | i18n }}</li>
|
||||
<li>{{ "sponsoredFamiliesSharedCollections" | i18n }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h2 bitTypography="h2" class="">{{ "sponsoredBitwardenFamilies" | i18n }}</h2>
|
||||
|
||||
@if (loading) {
|
||||
<ng-container>
|
||||
<i class="bwi bwi-spinner bwi-spin tw-text-muted" title="{{ 'loading' | i18n }}"></i>
|
||||
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
@if (!loading && sponsoredFamilies?.length > 0) {
|
||||
<ng-container>
|
||||
<bit-table>
|
||||
<ng-container header>
|
||||
<tr>
|
||||
<th bitCell>{{ "recipient" | i18n }}</th>
|
||||
<th bitCell>{{ "status" | i18n }}</th>
|
||||
<th bitCell>{{ "notes" | i18n }}</th>
|
||||
<th bitCell></th>
|
||||
</tr>
|
||||
</ng-container>
|
||||
<ng-template body alignContent="middle">
|
||||
@for (o of sponsoredFamilies; let i = $index; track i) {
|
||||
<ng-container>
|
||||
<tr bitRow>
|
||||
<td bitCell>{{ o.sponsorshipEmail }}</td>
|
||||
<td bitCell class="tw-text-success">{{ o.status }}</td>
|
||||
<td bitCell>{{ o.sponsorshipNote }}</td>
|
||||
<td bitCell>
|
||||
<button
|
||||
type="button"
|
||||
bitIconButton="bwi-ellipsis-v"
|
||||
buttonType="main"
|
||||
[bitMenuTriggerFor]="appListDropdown"
|
||||
appA11yTitle="{{ 'options' | i18n }}"
|
||||
></button>
|
||||
<bit-menu #appListDropdown>
|
||||
<button
|
||||
type="button"
|
||||
bitMenuItem
|
||||
[attr.aria-label]="'resendEmailLabel' | i18n"
|
||||
>
|
||||
<i aria-hidden="true" class="bwi bwi-envelope"></i>
|
||||
{{ "resendInvitation" | i18n }}
|
||||
</button>
|
||||
|
||||
<hr class="m-0" />
|
||||
|
||||
<button
|
||||
type="button"
|
||||
bitMenuItem
|
||||
[attr.aria-label]="'revokeAccount' | i18n"
|
||||
(click)="remove(o)"
|
||||
>
|
||||
<i aria-hidden="true" class="bwi bwi-close tw-text-danger"></i>
|
||||
<span class="tw-text-danger pl-1">{{ "remove" | i18n }}</span>
|
||||
</button>
|
||||
</bit-menu>
|
||||
</td>
|
||||
</tr>
|
||||
</ng-container>
|
||||
}
|
||||
</ng-template>
|
||||
</bit-table>
|
||||
<hr class="mt-0" />
|
||||
</ng-container>
|
||||
} @else {
|
||||
<div class="tw-my-5 tw-py-5 tw-flex tw-flex-col tw-items-center">
|
||||
<img class="tw-w-32" src="./../../../images/search.svg" alt="Search" />
|
||||
<h4 class="mt-3" bitTypography="h4">{{ "noSponsoredFamilies" | i18n }}</h4>
|
||||
<p bitTypography="body2">{{ "noSponsoredFamiliesDescription" | i18n }}</p>
|
||||
</div>
|
||||
}
|
||||
</ng-container>
|
||||
</bit-container>
|
||||
@@ -0,0 +1,39 @@
|
||||
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from "@angular/core";
|
||||
import { Subject } from "rxjs";
|
||||
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
|
||||
import { SponsoredFamily } from "./types/sponsored-family";
|
||||
|
||||
@Component({
|
||||
selector: "app-organization-sponsored-families",
|
||||
templateUrl: "organization-sponsored-families.component.html",
|
||||
})
|
||||
export class OrganizationSponsoredFamiliesComponent implements OnInit, OnDestroy {
|
||||
loading = false;
|
||||
tabIndex = 0;
|
||||
|
||||
@Input() sponsoredFamilies: SponsoredFamily[] = [];
|
||||
@Output() removeSponsorshipEvent = new EventEmitter<SponsoredFamily>();
|
||||
|
||||
private _destroy = new Subject<void>();
|
||||
|
||||
constructor(private platformUtilsService: PlatformUtilsService) {}
|
||||
|
||||
async ngOnInit() {
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
get isSelfHosted(): boolean {
|
||||
return this.platformUtilsService.isSelfHost();
|
||||
}
|
||||
|
||||
remove(sponsorship: SponsoredFamily) {
|
||||
this.removeSponsorshipEvent.emit(sponsorship);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this._destroy.next();
|
||||
this._destroy.complete();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export interface SponsoredFamily {
|
||||
sponsorshipEmail?: string;
|
||||
sponsorshipNote?: string;
|
||||
status?: string;
|
||||
}
|
||||
@@ -34,7 +34,12 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions";
|
||||
import { TaxServiceAbstraction } from "@bitwarden/common/billing/abstractions/tax.service.abstraction";
|
||||
import { PaymentMethodType, PlanType, ProductTierType } from "@bitwarden/common/billing/enums";
|
||||
import {
|
||||
PaymentMethodType,
|
||||
PlanSponsorshipType,
|
||||
PlanType,
|
||||
ProductTierType,
|
||||
} from "@bitwarden/common/billing/enums";
|
||||
import { TaxInformation } from "@bitwarden/common/billing/models/domain";
|
||||
import { ExpandedTaxInfoUpdateRequest } from "@bitwarden/common/billing/models/request/expanded-tax-info-update.request";
|
||||
import { PreviewOrganizationInvoiceRequest } from "@bitwarden/common/billing/models/request/preview-organization-invoice.request";
|
||||
@@ -83,6 +88,7 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy {
|
||||
@Input() showFree = true;
|
||||
@Input() showCancel = false;
|
||||
@Input() acceptingSponsorship = false;
|
||||
@Input() planSponsorshipType?: PlanSponsorshipType;
|
||||
@Input() currentPlan: PlanResponse;
|
||||
|
||||
selectedFile: File;
|
||||
@@ -682,11 +688,6 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
private refreshSalesTax(): void {
|
||||
if (this.formGroup.controls.plan.value == PlanType.Free) {
|
||||
this.estimatedTax = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.taxComponent.validate()) {
|
||||
return;
|
||||
}
|
||||
@@ -696,6 +697,7 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy {
|
||||
passwordManager: {
|
||||
additionalStorage: this.formGroup.controls.additionalStorage.value,
|
||||
plan: this.formGroup.controls.plan.value,
|
||||
sponsoredPlan: this.planSponsorshipType,
|
||||
seats: this.formGroup.controls.additionalSeats.value,
|
||||
},
|
||||
taxInformation: {
|
||||
|
||||
@@ -19,7 +19,13 @@ export class WebCommunicationProvider implements CommunicationBackend {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.queue.enqueue({ ...message.message, source: "BrowserBackground" });
|
||||
void this.queue.enqueue(
|
||||
new IncomingMessage(
|
||||
message.message.payload,
|
||||
message.message.destination,
|
||||
"BrowserBackground",
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,9 @@ import { OrganizationBadgeModule } from "../vault/individual-vault/organization-
|
||||
import { PipesModule } from "../vault/individual-vault/pipes/pipes.module";
|
||||
import { PurgeVaultComponent } from "../vault/settings/purge-vault.component";
|
||||
|
||||
import { FreeBitwardenFamiliesComponent } from "./../billing/members/free-bitwarden-families.component";
|
||||
import { OrganizationMemberFamiliesComponent } from "./../billing/members/organization-member-families.component";
|
||||
import { OrganizationSponsoredFamiliesComponent } from "./../billing/members/organization-sponsored-families.component";
|
||||
import { EnvironmentSelectorModule } from "./../components/environment-selector/environment-selector.module";
|
||||
import { AccountFingerprintComponent } from "./components/account-fingerprint/account-fingerprint.component";
|
||||
import { SharedModule } from "./shared.module";
|
||||
@@ -128,6 +131,9 @@ import { SharedModule } from "./shared.module";
|
||||
SelectableAvatarComponent,
|
||||
SetPasswordComponent,
|
||||
SponsoredFamiliesComponent,
|
||||
OrganizationSponsoredFamiliesComponent,
|
||||
OrganizationMemberFamiliesComponent,
|
||||
FreeBitwardenFamiliesComponent,
|
||||
SponsoringOrgRowComponent,
|
||||
UpdatePasswordComponent,
|
||||
UpdateTempPasswordComponent,
|
||||
@@ -175,6 +181,9 @@ import { SharedModule } from "./shared.module";
|
||||
SelectableAvatarComponent,
|
||||
SetPasswordComponent,
|
||||
SponsoredFamiliesComponent,
|
||||
OrganizationSponsoredFamiliesComponent,
|
||||
OrganizationMemberFamiliesComponent,
|
||||
FreeBitwardenFamiliesComponent,
|
||||
SponsoringOrgRowComponent,
|
||||
UpdateTempPasswordComponent,
|
||||
UpdatePasswordComponent,
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<bit-label>{{ "username" | i18n }}</bit-label>
|
||||
<input id="username" type="text" formControlName="username" bitInput />
|
||||
</bit-form-field>
|
||||
<small class="form-text text-muted tw-mb-4">{{ "breachCheckUsernameEmail" | i18n }}</small>
|
||||
<small class="tw-mb-4 tw-block tw-text-muted">{{ "breachCheckUsernameEmail" | i18n }}</small>
|
||||
<button type="submit" buttonType="primary" bitButton [loading]="loading">
|
||||
{{ "checkBreaches" | i18n }}
|
||||
</button>
|
||||
@@ -21,32 +21,33 @@
|
||||
<bit-callout type="danger" title="{{ 'breachFound' | i18n }}" *ngIf="breachedAccounts.length">
|
||||
{{ "breachUsernameFound" | i18n: checkedUsername : breachedAccounts.length }}
|
||||
</bit-callout>
|
||||
<ul class="list-group list-group-breach" *ngIf="breachedAccounts.length">
|
||||
<li *ngFor="let a of breachedAccounts" class="list-group-item min-height-fix">
|
||||
<div class="row">
|
||||
<div class="col-2 tw-text-center">
|
||||
<img [src]="a.logoPath" alt="" class="img-fluid" />
|
||||
</div>
|
||||
<div class="col-7">
|
||||
<h3 class="tw-text-lg">{{ a.title }}</h3>
|
||||
<p [innerHTML]="a.description"></p>
|
||||
<p class="tw-mb-1">{{ "compromisedData" | i18n }}:</p>
|
||||
<ul>
|
||||
<li *ngFor="let d of a.dataClasses">{{ d }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<dl>
|
||||
<dt>{{ "website" | i18n }}</dt>
|
||||
<dd>{{ a.domain }}</dd>
|
||||
<dt>{{ "affectedUsers" | i18n }}</dt>
|
||||
<dd>{{ a.pwnCount | number }}</dd>
|
||||
<dt>{{ "breachOccurred" | i18n }}</dt>
|
||||
<dd>{{ a.breachDate | date: "mediumDate" }}</dd>
|
||||
<dt>{{ "breachReported" | i18n }}</dt>
|
||||
<dd>{{ a.addedDate | date: "mediumDate" }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<ul
|
||||
class="tw-list-none tw-flex-col tw-divide-x-0 tw-divide-y tw-divide-solid tw-divide-secondary-300 tw-rounded tw-border tw-border-solid tw-border-secondary-300 tw-p-0"
|
||||
*ngIf="breachedAccounts.length"
|
||||
>
|
||||
<li *ngFor="let a of breachedAccounts" class="tw-flex tw-gap-4 tw-p-4">
|
||||
<div class="tw-w-32 tw-flex-none">
|
||||
<img [src]="a.logoPath" alt="" class="tw-max-w-32 tw-items-stretch" />
|
||||
</div>
|
||||
<div class="tw-flex-auto">
|
||||
<h3 class="tw-text-lg">{{ a.title }}</h3>
|
||||
<p [innerHTML]="a.description"></p>
|
||||
<p class="tw-mb-1">{{ "compromisedData" | i18n }}:</p>
|
||||
<ul>
|
||||
<li *ngFor="let d of a.dataClasses">{{ d }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tw-w-48 tw-flex-none">
|
||||
<dl>
|
||||
<dt>{{ "website" | i18n }}</dt>
|
||||
<dd>{{ a.domain }}</dd>
|
||||
<dt>{{ "affectedUsers" | i18n }}</dt>
|
||||
<dd>{{ a.pwnCount | number }}</dd>
|
||||
<dt>{{ "breachOccurred" | i18n }}</dt>
|
||||
<dd>{{ a.breachDate | date: "mediumDate" }}</dd>
|
||||
<dt>{{ "breachReported" | i18n }}</dt>
|
||||
<dd>{{ a.addedDate | date: "mediumDate" }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
12
apps/web/src/images/search.svg
Normal file
12
apps/web/src/images/search.svg
Normal file
@@ -0,0 +1,12 @@
|
||||
<svg width="97" height="97" viewBox="0 0 97 97" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M62.5 12.4604C63.6046 12.4604 64.5 13.3559 64.5 14.4604L64.5 90.4604C64.5 91.565 63.6046 92.4604 62.5 92.4604L6.5 92.4604C5.39543 92.4604 4.5 91.565 4.5 90.4604L4.5 14.4604C4.5 13.3559 5.39544 12.4604 6.5 12.4604L62.5 12.4604Z" fill="#99BAF4"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M62.5 90.4604L62.5 14.4604L6.5 14.4604L6.5 90.4604L62.5 90.4604ZM64.5 14.4604C64.5 13.3559 63.6046 12.4604 62.5 12.4604L6.5 12.4604C5.39544 12.4604 4.5 13.3559 4.5 14.4604L4.5 90.4604C4.5 91.565 5.39543 92.4604 6.5 92.4604L62.5 92.4604C63.6046 92.4604 64.5 91.565 64.5 90.4604L64.5 14.4604Z" fill="#0E3781"/>
|
||||
<path d="M72.5 82.4604L72.5 6.46045C72.5 5.35588 71.6046 4.46045 70.5 4.46045L27.8284 4.46045C27.298 4.46045 26.7939 4.66655 26.4188 5.04162L13.0835 18.3769C12.7085 18.752 12.5 19.2584 12.5 19.7889L12.5 82.4604C12.5 83.565 13.3954 84.4604 14.5 84.4604L70.5 84.4604C71.6046 84.4604 72.5 83.565 72.5 82.4604Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M70.5 82.4604L70.5 6.46045L27.8284 6.46045L14.5 19.7889L14.5 82.4604L70.5 82.4604ZM27.833 6.45583C27.833 6.45583 27.8329 6.45595 27.8327 6.45617L27.833 6.45583ZM72.5 6.46045L72.5 82.4604C72.5 83.565 71.6046 84.4604 70.5 84.4604L14.5 84.4604C13.3954 84.4604 12.5 83.565 12.5 82.4604L12.5 19.7889C12.5 19.2584 12.7085 18.752 13.0835 18.3769L26.4188 5.04162C26.7939 4.66655 27.298 4.46045 27.8284 4.46045L70.5 4.46045C71.6046 4.46045 72.5 5.35588 72.5 6.46045Z" fill="#0E3781"/>
|
||||
<path d="M84.5 48.4604C84.5 59.5061 75.5457 68.4604 64.5 68.4604C53.4543 68.4604 44.5 59.5061 44.5 48.4604C44.5 37.4148 53.4543 28.4604 64.5 28.4604C75.5457 28.4604 84.5 37.4148 84.5 48.4604Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M64.5 66.4604C74.4411 66.4604 82.5 58.4016 82.5 48.4604C82.5 38.5193 74.4411 30.4604 64.5 30.4604C54.5589 30.4604 46.5 38.5193 46.5 48.4604C46.5 58.4016 54.5589 66.4604 64.5 66.4604ZM64.5 68.4604C75.5457 68.4604 84.5 59.5061 84.5 48.4604C84.5 37.4148 75.5457 28.4604 64.5 28.4604C53.4543 28.4604 44.5 37.4148 44.5 48.4604C44.5 59.5061 53.4543 68.4604 64.5 68.4604Z" fill="#0E3781"/>
|
||||
<path d="M79.5 48.4604C79.5 56.7447 72.7843 63.4604 64.5 63.4604C56.2157 63.4604 49.5 56.7447 49.5 48.4604C49.5 40.1762 56.2157 33.4604 64.5 33.4604C72.7843 33.4604 79.5 40.1762 79.5 48.4604Z" fill="#99BAF4"/>
|
||||
<path d="M95.5038 77.5474L79 61.9604L77 63.9604L92.587 80.4643C93.3607 81.2836 94.6583 81.3021 95.4552 80.5053L95.5448 80.4156C96.3417 79.6188 96.3231 78.3212 95.5038 77.5474Z" fill="#0E3781"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M28.5 5.46045C29.0523 5.46045 29.5 5.90816 29.5 6.46045V21.4604H14.5C13.9477 21.4604 13.5 21.0127 13.5 20.4604C13.5 19.9082 13.9477 19.4604 14.5 19.4604H27.5V6.46045C27.5 5.90816 27.9477 5.46045 28.5 5.46045Z" fill="#0E3781"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.5 28.4604C19.9477 28.4604 19.5 28.9082 19.5 29.4604C19.5 30.0127 19.9477 30.4604 20.5 30.4604H30.5C31.0523 30.4604 31.5 30.0127 31.5 29.4604C31.5 28.9082 31.0523 28.4604 30.5 28.4604H20.5ZM34.5 28.4604C33.9477 28.4604 33.5 28.9082 33.5 29.4604C33.5 30.0127 33.9477 30.4604 34.5 30.4604H44.5C45.0523 30.4604 45.5 30.0127 45.5 29.4604C45.5 28.9082 45.0523 28.4604 44.5 28.4604H34.5ZM51.483 33.2759C51.3964 32.8118 50.9892 32.4604 50.5 32.4604H40.5C39.9477 32.4604 39.5 32.9082 39.5 33.4604C39.5 34.0127 39.9477 34.4604 40.5 34.4604H50.2171C50.6218 34.0477 51.0441 33.6524 51.483 33.2759ZM44.5246 49.4604C44.5579 50.1365 44.6247 50.8037 44.7235 51.4604H40.5C39.9477 51.4604 39.5 51.0127 39.5 50.4604C39.5 49.9082 39.9477 49.4604 40.5 49.4604H44.5246ZM44.7235 45.4605C44.6247 46.1172 44.5579 46.7844 44.5246 47.4605L37.5 47.4604C36.9477 47.4604 36.5 47.0127 36.5 46.4604C36.5 45.9082 36.9477 45.4604 37.5 45.4604L44.7235 45.4605ZM48.4985 36.4604C48.0192 37.0986 47.5772 37.7663 47.1756 38.4604L38.5 38.4604C37.9477 38.4604 37.5 38.0127 37.5 37.4604C37.5 36.9082 37.9477 36.4604 38.5 36.4604L48.4985 36.4604ZM64.5 28.4604C61.3707 28.4604 58.4093 29.1791 55.7717 30.4604L54.5 30.4604C53.9477 30.4604 53.5 30.0127 53.5 29.4604C53.5 28.9082 53.9477 28.4604 54.5 28.4604H64.5ZM48.5 28.4604C47.9477 28.4604 47.5 28.9082 47.5 29.4604C47.5 30.0127 47.9477 30.4604 48.5 30.4604H50.5C51.0523 30.4604 51.5 30.0127 51.5 29.4604C51.5 28.9082 51.0523 28.4604 50.5 28.4604H48.5ZM37.5 33.4604C37.5 32.9082 37.0523 32.4604 36.5 32.4604H34.5C33.9477 32.4604 33.5 32.9082 33.5 33.4604C33.5 34.0127 33.9477 34.4604 34.5 34.4604H36.5C37.0523 34.4604 37.5 34.0127 37.5 33.4604ZM34.5 38.4604C35.0523 38.4604 35.5 38.0127 35.5 37.4604C35.5 36.9082 35.0523 36.4604 34.5 36.4604H30.5C29.9477 36.4604 29.5 36.9082 29.5 37.4604C29.5 38.0127 29.9477 38.4604 30.5 38.4604H34.5ZM34.5 46.4604C34.5 47.0127 34.0523 47.4604 33.5 47.4604H27.5C26.9477 47.4604 26.5 47.0127 26.5 46.4604C26.5 45.9082 26.9477 45.4604 27.5 45.4604H33.5C34.0523 45.4604 34.5 45.9082 34.5 46.4604ZM36.5 51.4604C37.0523 51.4604 37.5 51.0127 37.5 50.4604C37.5 49.9082 37.0523 49.4604 36.5 49.4604H20.5C19.9477 49.4604 19.5 49.9082 19.5 50.4604C19.5 51.0127 19.9477 51.4604 20.5 51.4604H36.5ZM31.5 33.4604C31.5 32.9082 31.0523 32.4604 30.5 32.4604L20.5 32.4605C19.9477 32.4605 19.5 32.9082 19.5 33.4605C19.5 34.0127 19.9477 34.4605 20.5 34.4605L30.5 34.4604C31.0523 34.4604 31.5 34.0127 31.5 33.4604ZM26.5 38.4604C27.0523 38.4604 27.5 38.0127 27.5 37.4604C27.5 36.9082 27.0523 36.4604 26.5 36.4604H20.5C19.9477 36.4604 19.5 36.9082 19.5 37.4604C19.5 38.0127 19.9477 38.4604 20.5 38.4604H26.5ZM24.5 46.4604C24.5 47.0127 24.0523 47.4604 23.5 47.4604H20.5C19.9477 47.4604 19.5 47.0127 19.5 46.4604C19.5 45.9082 19.9477 45.4604 20.5 45.4604H23.5C24.0523 45.4604 24.5 45.9082 24.5 46.4604Z" fill="#FFBF00"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.6 KiB |
@@ -6306,6 +6306,21 @@
|
||||
"sponsoredFamilies": {
|
||||
"message": "Free Bitwarden Families"
|
||||
},
|
||||
"sponsoredBitwardenFamilies": {
|
||||
"message": "Sponsored families"
|
||||
},
|
||||
"noSponsoredFamilies": {
|
||||
"message": "No sponsored families"
|
||||
},
|
||||
"noSponsoredFamiliesDescription": {
|
||||
"message": "Sponsored non-member families plans will display here"
|
||||
},
|
||||
"sponsorFreeBitwardenFamilies": {
|
||||
"message": "Members of your organization are eligible for Free Bitwarden Families. You can sponsor Free Bitwarden Families for employees who are not a member of your Bitwarden organization. Sponsoring a non-member requires an available seat within your organization."
|
||||
},
|
||||
"sponsoredFamiliesRemoveActiveSponsorship": {
|
||||
"message": "When you remove an active sponsorship, a seat within your organization will be available after the renewal date of the sponsored organization."
|
||||
},
|
||||
"sponsoredFamiliesEligible": {
|
||||
"message": "You and your family are eligible for Free Bitwarden Families. Redeem with your personal email to keep your data secure even when you are not at work."
|
||||
},
|
||||
@@ -6321,6 +6336,18 @@
|
||||
"sponsoredFamiliesSharedCollections": {
|
||||
"message": "Shared collections for Family secrets"
|
||||
},
|
||||
"memberFamilies": {
|
||||
"message": "Member families"
|
||||
},
|
||||
"noMemberFamilies": {
|
||||
"message": "No member families"
|
||||
},
|
||||
"noMemberFamiliesDescription": {
|
||||
"message": "Members who have redeemed family plans will display here"
|
||||
},
|
||||
"membersWithSponsoredFamilies": {
|
||||
"message": "Members of your organization are eligible for Free Bitwarden Families. Here you can see members who have sponsored a Families organization."
|
||||
},
|
||||
"badToken": {
|
||||
"message": "The link is no longer valid. Please have the sponsor resend the offer."
|
||||
},
|
||||
@@ -7984,6 +8011,9 @@
|
||||
"inviteMember": {
|
||||
"message": "Invite member"
|
||||
},
|
||||
"addSponsorship": {
|
||||
"message": "Add sponsorship"
|
||||
},
|
||||
"needsConfirmation": {
|
||||
"message": "Needs confirmation"
|
||||
},
|
||||
|
||||
@@ -536,6 +536,10 @@ export class LoginComponent implements OnInit, OnDestroy {
|
||||
if (storedEmail) {
|
||||
this.formGroup.controls.email.setValue(storedEmail);
|
||||
this.formGroup.controls.rememberEmail.setValue(true);
|
||||
// If we load an email into the form, we need to initialize it for the login process as well
|
||||
// so that other login components can use it.
|
||||
// We do this here as it's possible that a user doesn't edit the email field before submitting.
|
||||
this.loginEmailService.setLoginEmail(storedEmail);
|
||||
} else {
|
||||
this.formGroup.controls.rememberEmail.setValue(false);
|
||||
}
|
||||
|
||||
@@ -6,4 +6,5 @@ export class OrganizationSponsorshipCreateRequest {
|
||||
sponsoredEmail: string;
|
||||
planSponsorshipType: PlanSponsorshipType;
|
||||
friendlyName: string;
|
||||
notes?: string;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PlanType } from "../../enums";
|
||||
import { PlanSponsorshipType, PlanType } from "../../enums";
|
||||
|
||||
export class PreviewOrganizationInvoiceRequest {
|
||||
organizationId?: string;
|
||||
@@ -21,6 +21,7 @@ export class PreviewOrganizationInvoiceRequest {
|
||||
|
||||
class PasswordManager {
|
||||
plan: PlanType;
|
||||
sponsoredPlan?: PlanSponsorshipType;
|
||||
seats: number;
|
||||
additionalStorage: number;
|
||||
|
||||
|
||||
@@ -46,7 +46,6 @@ export enum FeatureFlag {
|
||||
CriticalApps = "pm-14466-risk-insights-critical-application",
|
||||
EnableRiskInsightsNotifications = "enable-risk-insights-notifications",
|
||||
DesktopSendUIRefresh = "desktop-send-ui-refresh",
|
||||
ExportAttachments = "export-attachments",
|
||||
|
||||
/* Vault */
|
||||
PM8851_BrowserOnboardingNudge = "pm-8851-browser-onboarding-nudge",
|
||||
@@ -98,7 +97,6 @@ export const DefaultFeatureFlagValue = {
|
||||
[FeatureFlag.CriticalApps]: FALSE,
|
||||
[FeatureFlag.EnableRiskInsightsNotifications]: FALSE,
|
||||
[FeatureFlag.DesktopSendUIRefresh]: FALSE,
|
||||
[FeatureFlag.ExportAttachments]: FALSE,
|
||||
|
||||
/* Vault */
|
||||
[FeatureFlag.PM8851_BrowserOnboardingNudge]: FALSE,
|
||||
|
||||
@@ -39,8 +39,6 @@ import { Organization } from "@bitwarden/common/admin-console/models/domain/orga
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { EventType } from "@bitwarden/common/enums";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
@@ -184,10 +182,6 @@ export class ExportComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
private onlyManagedCollections = true;
|
||||
private onGenerate$ = new Subject<GenerateRequest>();
|
||||
|
||||
private isExportAttachmentsEnabled$ = this.configService.getFeatureFlag$(
|
||||
FeatureFlag.ExportAttachments,
|
||||
);
|
||||
|
||||
constructor(
|
||||
protected i18nService: I18nService,
|
||||
protected toastService: ToastService,
|
||||
@@ -202,7 +196,6 @@ export class ExportComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
protected organizationService: OrganizationService,
|
||||
private accountService: AccountService,
|
||||
private collectionService: CollectionService,
|
||||
private configService: ConfigService,
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
@@ -225,17 +218,14 @@ export class ExportComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
),
|
||||
);
|
||||
|
||||
combineLatest([
|
||||
this.exportForm.controls.vaultSelector.valueChanges,
|
||||
this.isExportAttachmentsEnabled$,
|
||||
])
|
||||
this.exportForm.controls.vaultSelector.valueChanges
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe(([value, isExportAttachmentsEnabled]) => {
|
||||
.subscribe(([value]) => {
|
||||
this.organizationId = value !== "myVault" ? value : undefined;
|
||||
|
||||
this.formatOptions = this.formatOptions.filter((option) => option.value !== "zip");
|
||||
this.exportForm.get("format").setValue("json");
|
||||
if (value === "myVault" && isExportAttachmentsEnabled) {
|
||||
if (value === "myVault") {
|
||||
this.formatOptions.push({ name: ".zip (with attachments)", value: "zip" });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { importProvidersFrom, signal } from "@angular/core";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { action } from "@storybook/addon-actions";
|
||||
import {
|
||||
applicationConfig,
|
||||
@@ -225,6 +226,14 @@ export default {
|
||||
getFeatureFlag: () => Promise.resolve(false),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: ActivatedRoute,
|
||||
useValue: {
|
||||
snapshot: {
|
||||
queryParams: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
componentWrapperDecorator(
|
||||
|
||||
@@ -83,4 +83,24 @@ describe("AddEditCustomFieldDialogComponent", () => {
|
||||
expect.objectContaining({ value: FieldType.Linked }),
|
||||
);
|
||||
});
|
||||
|
||||
it("does not filter out 'Hidden' field type when 'disallowHiddenField' is false", () => {
|
||||
dialogData.disallowHiddenField = false;
|
||||
fixture = TestBed.createComponent(AddEditCustomFieldDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
expect(component.fieldTypeOptions).toContainEqual(
|
||||
expect.objectContaining({ value: FieldType.Hidden }),
|
||||
);
|
||||
});
|
||||
|
||||
it("filers out 'Hidden' field type when 'disallowHiddenField' is true", () => {
|
||||
dialogData.disallowHiddenField = true;
|
||||
fixture = TestBed.createComponent(AddEditCustomFieldDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
expect(component.fieldTypeOptions).not.toContainEqual(
|
||||
expect.objectContaining({ value: FieldType.Hidden }),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -25,6 +25,7 @@ export type AddEditCustomFieldDialogData = {
|
||||
cipherType: CipherType;
|
||||
/** When provided, dialog will display edit label variants */
|
||||
editLabelConfig?: { index: number; label: string };
|
||||
disallowHiddenField?: boolean;
|
||||
};
|
||||
|
||||
@Component({
|
||||
@@ -68,6 +69,9 @@ export class AddEditCustomFieldDialogComponent {
|
||||
this.variant = data.editLabelConfig ? "edit" : "add";
|
||||
|
||||
this.fieldTypeOptions = this.fieldTypeOptions.filter((option) => {
|
||||
if (this.data.disallowHiddenField && option.value === FieldType.Hidden) {
|
||||
return false;
|
||||
}
|
||||
// Filter out the Linked field type for Secure Notes
|
||||
if (this.data.cipherType === CipherType.SecureNote) {
|
||||
return option.value !== FieldType.Linked;
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
bitIconButton="bwi-pencil-square"
|
||||
class="tw-self-center tw-mt-2"
|
||||
data-testid="edit-custom-field-button"
|
||||
*ngIf="!isPartialEdit"
|
||||
*ngIf="canEdit(field.value.type)"
|
||||
></button>
|
||||
|
||||
<button
|
||||
@@ -100,7 +100,7 @@
|
||||
[appA11yTitle]="'reorderToggleButton' | i18n: field.value.name"
|
||||
(keydown)="handleKeyDown($event, field.value.name, i)"
|
||||
data-testid="reorder-toggle-button"
|
||||
*ngIf="!isPartialEdit"
|
||||
*ngIf="canEdit(field.value.type)"
|
||||
></button>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -45,7 +45,9 @@ describe("CustomFieldsComponent", () => {
|
||||
announce = jest.fn().mockResolvedValue(null);
|
||||
patchCipher = jest.fn();
|
||||
originalCipherView = new CipherView();
|
||||
config = {} as CipherFormConfig;
|
||||
config = {
|
||||
collections: [],
|
||||
} as CipherFormConfig;
|
||||
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [CustomFieldsComponent],
|
||||
@@ -463,5 +465,91 @@ describe("CustomFieldsComponent", () => {
|
||||
// "reorder boolean label to position 4 of 4"
|
||||
expect(announce).toHaveBeenCalledWith("reorderFieldDown boolean label 4 4", "assertive");
|
||||
});
|
||||
|
||||
it("hides reorder buttons when in partial edit mode", () => {
|
||||
originalCipherView.fields = mockFieldViews;
|
||||
config.mode = "partial-edit";
|
||||
|
||||
component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
|
||||
toggleItems = fixture.debugElement.queryAll(
|
||||
By.css('button[data-testid="reorder-toggle-button"]'),
|
||||
);
|
||||
|
||||
expect(toggleItems).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
it("shows all reorders button when in edit mode and viewPassword is true", () => {
|
||||
originalCipherView.fields = mockFieldViews;
|
||||
originalCipherView.viewPassword = true;
|
||||
config.mode = "edit";
|
||||
|
||||
component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
|
||||
const toggleItems = fixture.debugElement.queryAll(
|
||||
By.css('button[data-testid="reorder-toggle-button"]'),
|
||||
);
|
||||
expect(toggleItems).toHaveLength(4);
|
||||
});
|
||||
|
||||
it("shows all reorder buttons except for hidden fields when in edit mode and viewPassword is false", () => {
|
||||
originalCipherView.fields = mockFieldViews;
|
||||
originalCipherView.viewPassword = false;
|
||||
config.mode = "edit";
|
||||
|
||||
component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
|
||||
const toggleItems = fixture.debugElement.queryAll(
|
||||
By.css('button[data-testid="reorder-toggle-button"]'),
|
||||
);
|
||||
|
||||
expect(toggleItems).toHaveLength(3);
|
||||
});
|
||||
|
||||
describe("edit button", () => {
|
||||
it("hides the edit button when in partial-edit mode", () => {
|
||||
originalCipherView.fields = mockFieldViews;
|
||||
config.mode = "partial-edit";
|
||||
|
||||
component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
|
||||
const editButtons = fixture.debugElement.queryAll(
|
||||
By.css('button[data-testid="edit-custom-field-button"]'),
|
||||
);
|
||||
expect(editButtons).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("shows all the edit buttons when in edit mode and viewPassword is true", () => {
|
||||
originalCipherView.fields = mockFieldViews;
|
||||
originalCipherView.viewPassword = true;
|
||||
config.mode = "edit";
|
||||
|
||||
component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
|
||||
const editButtons = fixture.debugElement.queryAll(
|
||||
By.css('button[data-testid="edit-custom-field-button"]'),
|
||||
);
|
||||
expect(editButtons).toHaveLength(4);
|
||||
});
|
||||
|
||||
it("shows all the edit buttons except for hidden fields when in edit mode and viewPassword is false", () => {
|
||||
originalCipherView.fields = mockFieldViews;
|
||||
originalCipherView.viewPassword = false;
|
||||
config.mode = "edit";
|
||||
|
||||
component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
|
||||
const editButtons = fixture.debugElement.queryAll(
|
||||
By.css('button[data-testid="edit-custom-field-button"]'),
|
||||
);
|
||||
expect(editButtons).toHaveLength(3);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -116,6 +116,8 @@ export class CustomFieldsComponent implements OnInit, AfterViewInit {
|
||||
/** Emits when a new custom field should be focused */
|
||||
private focusOnNewInput$ = new Subject<void>();
|
||||
|
||||
disallowHiddenField?: boolean;
|
||||
|
||||
destroyed$: DestroyRef;
|
||||
FieldType = FieldType;
|
||||
|
||||
@@ -141,6 +143,13 @@ export class CustomFieldsComponent implements OnInit, AfterViewInit {
|
||||
return this.customFieldsForm.controls.fields as FormArray;
|
||||
}
|
||||
|
||||
canEdit(type: FieldType): boolean {
|
||||
return (
|
||||
!this.isPartialEdit &&
|
||||
(type !== FieldType.Hidden || this.cipherFormContainer.originalCipherView?.viewPassword)
|
||||
);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
const linkedFieldsOptionsForCipher = this.getLinkedFieldsOptionsForCipher();
|
||||
const optionsArray = Array.from(linkedFieldsOptionsForCipher?.entries() ?? []);
|
||||
@@ -210,6 +219,7 @@ export class CustomFieldsComponent implements OnInit, AfterViewInit {
|
||||
|
||||
/** Opens the add/edit custom field dialog */
|
||||
openAddEditCustomFieldDialog(editLabelConfig?: AddEditCustomFieldDialogData["editLabelConfig"]) {
|
||||
const { cipherType, mode, originalCipher } = this.cipherFormContainer.config;
|
||||
this.dialogRef = this.dialogService.open<unknown, AddEditCustomFieldDialogData>(
|
||||
AddEditCustomFieldDialogComponent,
|
||||
{
|
||||
@@ -217,8 +227,9 @@ export class CustomFieldsComponent implements OnInit, AfterViewInit {
|
||||
addField: this.addField.bind(this),
|
||||
updateLabel: this.updateLabel.bind(this),
|
||||
removeField: this.removeField.bind(this),
|
||||
cipherType: this.cipherFormContainer.config.cipherType,
|
||||
cipherType,
|
||||
editLabelConfig,
|
||||
disallowHiddenField: mode === "edit" && !originalCipher.viewPassword,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
@@ -2,10 +2,10 @@ import { svgIcon } from "@bitwarden/components";
|
||||
|
||||
export const LoginCards = svgIcon`
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="150" fill="none">
|
||||
<path class="tw-fill-background-alt4" fill-rule="evenodd" d="M134.152 32.493c0-.69.559-1.25 1.25-1.25h1.493a8.707 8.707 0 0 1 8.707 8.707v79.047a8.707 8.707 0 0 1-8.707 8.707H22.054c-4.81 0-8.707-3.906-8.707-8.713a1.25 1.25 0 1 1 2.5 0 6.212 6.212 0 0 0 6.207 6.213h114.841a6.207 6.207 0 0 0 6.207-6.207V39.95a6.207 6.207 0 0 0-6.207-6.207h-1.493a1.25 1.25 0 0 1-1.25-1.25Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-background-alt4" fill-rule="evenodd" d="M13.105 24.795a6.207 6.207 0 0 0-6.207 6.207v80.538a6.207 6.207 0 0 0 6.207 6.207h114.841a6.207 6.207 0 0 0 6.208-6.207V31.002a6.207 6.207 0 0 0-6.208-6.207H13.106Zm-8.707 6.207a8.707 8.707 0 0 1 8.707-8.707h114.841a8.708 8.708 0 0 1 8.708 8.707v80.538a8.708 8.708 0 0 1-8.708 8.707H13.106a8.707 8.707 0 0 1-8.708-8.707V31.002Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-background-alt4" fill-rule="evenodd" d="M120.964 75.915H20.766c-.819 0-1.483.664-1.483 1.483v8.949c0 .819.664 1.483 1.483 1.483h100.198c.819 0 1.483-.664 1.483-1.483v-8.95c0-.818-.664-1.482-1.483-1.482Zm-100.198-1.5a2.983 2.983 0 0 0-2.983 2.983v8.949a2.983 2.983 0 0 0 2.983 2.983h100.198a2.983 2.983 0 0 0 2.983-2.983v-8.95a2.983 2.983 0 0 0-2.983-2.982H20.766ZM120.964 96.794H20.766c-.819 0-1.483.664-1.483 1.483v8.948c0 .819.664 1.483 1.483 1.483h100.198c.819 0 1.483-.664 1.483-1.483v-8.948c0-.82-.664-1.483-1.483-1.483Zm-100.198-1.5a2.983 2.983 0 0 0-2.983 2.983v8.948a2.983 2.983 0 0 0 2.983 2.983h100.198a2.983 2.983 0 0 0 2.983-2.983v-8.948a2.983 2.983 0 0 0-2.983-2.983H20.766Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-art-primary" fill-rule="evenodd" d="M134.152 32.493c0-.69.559-1.25 1.25-1.25h1.493a8.707 8.707 0 0 1 8.707 8.707v79.047a8.707 8.707 0 0 1-8.707 8.707H22.054c-4.81 0-8.707-3.906-8.707-8.713a1.25 1.25 0 1 1 2.5 0 6.212 6.212 0 0 0 6.207 6.213h114.841a6.207 6.207 0 0 0 6.207-6.207V39.95a6.207 6.207 0 0 0-6.207-6.207h-1.493a1.25 1.25 0 0 1-1.25-1.25Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-art-primary" fill-rule="evenodd" d="M13.105 24.795a6.207 6.207 0 0 0-6.207 6.207v80.538a6.207 6.207 0 0 0 6.207 6.207h114.841a6.207 6.207 0 0 0 6.208-6.207V31.002a6.207 6.207 0 0 0-6.208-6.207H13.106Zm-8.707 6.207a8.707 8.707 0 0 1 8.707-8.707h114.841a8.708 8.708 0 0 1 8.708 8.707v80.538a8.708 8.708 0 0 1-8.708 8.707H13.106a8.707 8.707 0 0 1-8.708-8.707V31.002Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-art-primary" fill-rule="evenodd" d="M120.964 75.915H20.766c-.819 0-1.483.664-1.483 1.483v8.949c0 .819.664 1.483 1.483 1.483h100.198c.819 0 1.483-.664 1.483-1.483v-8.95c0-.818-.664-1.482-1.483-1.482Zm-100.198-1.5a2.983 2.983 0 0 0-2.983 2.983v8.949a2.983 2.983 0 0 0 2.983 2.983h100.198a2.983 2.983 0 0 0 2.983-2.983v-8.95a2.983 2.983 0 0 0-2.983-2.982H20.766ZM120.964 96.794H20.766c-.819 0-1.483.664-1.483 1.483v8.948c0 .819.664 1.483 1.483 1.483h100.198c.819 0 1.483-.664 1.483-1.483v-8.948c0-.82-.664-1.483-1.483-1.483Zm-100.198-1.5a2.983 2.983 0 0 0-2.983 2.983v8.948a2.983 2.983 0 0 0 2.983 2.983h100.198a2.983 2.983 0 0 0 2.983-2.983v-8.948a2.983 2.983 0 0 0-2.983-2.983H20.766Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-art-accent" fill-rule="evenodd" d="M22.795 81.712a.75.75 0 0 1 .75-.75H87.68a.75.75 0 0 1 0 1.5H23.545a.75.75 0 0 1-.75-.75ZM26.618 100.354a.75.75 0 0 0-1.5 0v1.426l-1.34-.439a.75.75 0 0 0-.466 1.426l1.353.443-.845 1.183a.75.75 0 0 0 1.221.872l.827-1.158.827 1.158a.75.75 0 0 0 1.22-.872l-.845-1.183 1.353-.443a.75.75 0 0 0-.466-1.426l-1.34.439v-1.426Zm9.584 0a.75.75 0 0 0-1.5 0v1.426l-1.339-.439a.75.75 0 0 0-.466 1.426l1.353.443-.845 1.183a.75.75 0 0 0 1.22.872l.827-1.158.827 1.158a.75.75 0 0 0 1.22-.872l-.844-1.183 1.353-.443a.75.75 0 0 0-.467-1.426l-1.339.439v-1.426Zm8.834-.75a.75.75 0 0 1 .75.75v1.426l1.339-.439a.75.75 0 0 1 .467 1.426l-1.353.443.845 1.183a.75.75 0 0 1-1.22.872l-.828-1.159-.827 1.159a.75.75 0 1 1-1.22-.872l.844-1.183-1.353-.443a.75.75 0 0 1 .467-1.426l1.339.439v-1.426a.75.75 0 0 1 .75-.75Zm10.334.75a.75.75 0 0 0-1.5 0v1.426l-1.339-.439a.75.75 0 0 0-.466 1.426l1.353.443-.845 1.183a.75.75 0 1 0 1.22.872l.828-1.159.827 1.159a.75.75 0 0 0 1.22-.872l-.845-1.183 1.353-.443a.75.75 0 0 0-.467-1.426l-1.339.439v-1.426Zm8.835-.75a.75.75 0 0 1 .75.75v1.426l1.338-.439a.75.75 0 0 1 .467 1.426l-1.352.443.845 1.183a.75.75 0 0 1-1.221.872l-.827-1.159-.828 1.159a.75.75 0 0 1-1.22-.872L63 103.21l-1.353-.443a.75.75 0 0 1 .467-1.426l1.34.439v-1.426a.75.75 0 0 1 .75-.75Zm10.334.75a.75.75 0 0 0-1.5 0v1.426l-1.34-.439a.75.75 0 0 0-.466 1.426l1.353.443-.845 1.183a.75.75 0 1 0 1.221.872l.827-1.158.827 1.158a.75.75 0 0 0 1.22-.872l-.844-1.183 1.352-.443a.75.75 0 0 0-.466-1.426l-1.34.439v-1.426ZM53.215 50.395c0-9.566 7.755-17.314 17.313-17.314 9.56 0 17.308 7.749 17.314 17.313 0 5.31-2.399 10.061-6.16 13.236l-.742.626-.418-.876c-1.785-3.736-5.584-6.324-9.994-6.324s-8.214 2.583-9.992 6.323l-.418.878-.743-.627c-3.761-3.175-6.16-7.92-6.16-13.236Zm13.8 5.66a12.594 12.594 0 0 0-7.373 5.801 15.759 15.759 0 0 1-4.927-11.462c0-8.736 7.083-15.813 15.813-15.813s15.808 7.077 15.814 15.814c0 4.51-1.895 8.58-4.928 11.462a12.623 12.623 0 0 0-7.373-5.802 6.659 6.659 0 0 0 3.149-5.66 6.663 6.663 0 0 0-6.662-6.662 6.663 6.663 0 0 0-6.66 6.662 6.659 6.659 0 0 0 3.147 5.66Zm3.513-10.822a5.163 5.163 0 0 0-5.16 5.162 5.163 5.163 0 0 0 5.16 5.16 5.163 5.163 0 0 0 5.162-5.16 5.163 5.163 0 0 0-5.162-5.162Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-background-alt4" fill-rule="evenodd" d="M70.528 34.57c-8.743 0-15.83 7.081-15.83 15.816s7.087 15.817 15.83 15.817c8.744 0 15.83-7.082 15.83-15.817S79.272 34.57 70.528 34.57Zm-17.33 15.816c0-9.564 7.76-17.317 17.33-17.317 9.571 0 17.33 7.753 17.33 17.317 0 9.565-7.759 17.317-17.33 17.317-9.57 0-17.33-7.752-17.33-17.317Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-art-primary" fill-rule="evenodd" d="M70.528 34.57c-8.743 0-15.83 7.081-15.83 15.816s7.087 15.817 15.83 15.817c8.744 0 15.83-7.082 15.83-15.817S79.272 34.57 70.528 34.57Zm-17.33 15.816c0-9.564 7.76-17.317 17.33-17.317 9.571 0 17.33 7.753 17.33 17.317 0 9.565-7.759 17.317-17.33 17.317-9.57 0-17.33-7.752-17.33-17.317Z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
@@ -3,14 +3,14 @@ import { svgIcon } from "@bitwarden/components";
|
||||
export const SecureDevices = svgIcon`
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="150" fill="none">
|
||||
<path class="tw-stroke-art-accent" stroke-width="1.5" d="M122.568 45.774v-3a5.176 5.176 0 0 0-5.176-5.175H34.094a5.176 5.176 0 0 0-5.176 5.176v10.432m67.636 39.392H33.378"/>
|
||||
<path class="tw-stroke-background-alt4" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M53.446 111.924h43.108"/>
|
||||
<path class="tw-stroke-background-alt4" stroke-linejoin="round" stroke-width="1.5" d="M68.118 98.72v13.204M82.96 98.72v13.204"/>
|
||||
<path class="tw-stroke-background-alt4" stroke-width="2.5" d="M127.771 45.775v-3.026c0-5.718-4.635-10.352-10.352-10.352H34.068c-5.718 0-10.352 4.634-10.352 10.352v10.459m72.838 44.595H33.378"/>
|
||||
<path class="tw-stroke-art-primary" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M53.446 111.924h43.108"/>
|
||||
<path class="tw-stroke-art-primary" stroke-linejoin="round" stroke-width="1.5" d="M68.118 98.72v13.204M82.96 98.72v13.204"/>
|
||||
<path class="tw-stroke-art-primary" stroke-width="2.5" d="M127.771 45.775v-3.026c0-5.718-4.635-10.352-10.352-10.352H34.068c-5.718 0-10.352 4.634-10.352 10.352v10.459m72.838 44.595H33.378"/>
|
||||
<path class="tw-fill-art-accent" fill-rule="evenodd" d="M71.835 59.965C72.068 57.392 73.906 55.5 76 55.5s3.932 1.892 4.165 4.465h-8.33Zm-1.005.034c.224-3.015 2.388-5.499 5.17-5.499 2.781 0 4.946 2.484 5.17 5.5 1.6.232 2.83 1.61 2.83 3.275v6.62a3.31 3.31 0 0 1-3.31 3.311h-9.38a3.31 3.31 0 0 1-3.31-3.31v-6.62a3.311 3.311 0 0 1 2.83-3.277Zm.48.966h9.38a2.31 2.31 0 0 1 2.31 2.31v6.62a2.31 2.31 0 0 1-2.31 2.311h-9.38a2.31 2.31 0 0 1-2.31-2.31v-6.62a2.31 2.31 0 0 1 2.31-2.311Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-art-accent" fill-rule="evenodd" d="M75.448 67.482a1.103 1.103 0 0 1-.551-.956v-.215a1.103 1.103 0 1 1 2.206 0v.215c0 .408-.221.765-.551.956v1.594a.552.552 0 1 1-1.104 0v-1.594Z" clip-rule="evenodd"/>
|
||||
<rect width="30.203" height="56.96" x="3.411" y="52.971" class="tw-stroke-background-alt4" stroke-width="2.5" rx="7.377"/>
|
||||
<rect width="30.203" height="56.96" x="3.411" y="52.971" class="tw-stroke-art-primary" stroke-width="2.5" rx="7.377"/>
|
||||
<path class="tw-stroke-art-accent" stroke-linecap="round" stroke-width="1.725" d="M18.164 58.148h.685"/>
|
||||
<rect width="51.284" height="71.352" x="96.554" y="45.775" class="tw-stroke-background-alt4" stroke-width="2.5" rx="6.901"/>
|
||||
<rect width="51.284" height="71.352" x="96.554" y="45.775" class="tw-stroke-art-primary" stroke-width="2.5" rx="6.901"/>
|
||||
<circle cx="122.568" cy="111.924" r="1.486" class="tw-fill-art-accent"/>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
@@ -2,8 +2,8 @@ import { svgIcon } from "@bitwarden/components";
|
||||
|
||||
export const SecureUser = svgIcon`
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="150" fill="none">
|
||||
<path class="tw-fill-background-alt4" fill-rule="evenodd" d="M96.538 35.676c-.85 0-1.538-.688-1.538-1.538v-.6a1.538 1.538 0 1 1 3.076 0v.6c0 .85-.688 1.538-1.538 1.538ZM103.737 35.676a1.538 1.538 0 0 1-1.538-1.538v-.6a1.538 1.538 0 0 1 3.076 0v.6c0 .85-.688 1.538-1.538 1.538ZM110.935 35.676a1.538 1.538 0 0 1-1.538-1.538v-.6a1.538 1.538 0 0 1 3.076 0v.6c0 .85-.689 1.538-1.538 1.538Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-background-alt4" fill-rule="evenodd" d="M12.708 26.798C7.346 26.798 3 31.145 3 36.508v58.446c0 5.362 4.347 9.71 9.71 9.71h9.567v-2.5h-9.568a7.21 7.21 0 0 1-7.209-7.21V39.451h112.272v5.666a21.936 21.936 0 0 0-8.466-1.688c-12.15 0-22 9.85-22 22 0 9.269 5.732 17.199 13.845 20.439-9.966 2.189-18.447 8.17-23.747 16.296H64.038v2.5H75.91a35.893 35.893 0 0 0-3.913 11.415c-.408 2.511.898 5.791 4.056 5.791h65.572c4.042 0 6.167-2.082 5.564-5.791-2.447-15.065-14.291-27.103-29.529-30.292 8.007-3.29 13.645-11.166 13.645-20.358 0-8.158-4.44-15.278-11.034-19.077v-9.845c0-5.362-4.347-9.71-9.71-9.71H12.708ZM117.771 37.95v-1.444a7.21 7.21 0 0 0-7.21-7.21H12.708a7.21 7.21 0 0 0-7.209 7.21v1.444h112.272Zm-38.837 66.713h-.144a33.454 33.454 0 0 0-4.326 11.816c-.118.732.03 1.578.376 2.164.292.494.65.726 1.213.726h65.572c1.649 0 2.42-.429 2.735-.751.252-.258.576-.819.361-2.139-2.662-16.39-17.328-29.024-35.128-29.024-13.09 0-24.486 6.833-30.659 16.968v.24Zm49.871-39.235c0 10.77-8.73 19.5-19.5 19.5s-19.5-8.73-19.5-19.5 8.73-19.5 19.5-19.5 19.5 8.73 19.5 19.5Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-art-primary" fill-rule="evenodd" d="M96.538 35.676c-.85 0-1.538-.688-1.538-1.538v-.6a1.538 1.538 0 1 1 3.076 0v.6c0 .85-.688 1.538-1.538 1.538ZM103.737 35.676a1.538 1.538 0 0 1-1.538-1.538v-.6a1.538 1.538 0 0 1 3.076 0v.6c0 .85-.688 1.538-1.538 1.538ZM110.935 35.676a1.538 1.538 0 0 1-1.538-1.538v-.6a1.538 1.538 0 0 1 3.076 0v.6c0 .85-.689 1.538-1.538 1.538Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-art-primary" fill-rule="evenodd" d="M12.708 26.798C7.346 26.798 3 31.145 3 36.508v58.446c0 5.362 4.347 9.71 9.71 9.71h9.567v-2.5h-9.568a7.21 7.21 0 0 1-7.209-7.21V39.451h112.272v5.666a21.936 21.936 0 0 0-8.466-1.688c-12.15 0-22 9.85-22 22 0 9.269 5.732 17.199 13.845 20.439-9.966 2.189-18.447 8.17-23.747 16.296H64.038v2.5H75.91a35.893 35.893 0 0 0-3.913 11.415c-.408 2.511.898 5.791 4.056 5.791h65.572c4.042 0 6.167-2.082 5.564-5.791-2.447-15.065-14.291-27.103-29.529-30.292 8.007-3.29 13.645-11.166 13.645-20.358 0-8.158-4.44-15.278-11.034-19.077v-9.845c0-5.362-4.347-9.71-9.71-9.71H12.708ZM117.771 37.95v-1.444a7.21 7.21 0 0 0-7.21-7.21H12.708a7.21 7.21 0 0 0-7.209 7.21v1.444h112.272Zm-38.837 66.713h-.144a33.454 33.454 0 0 0-4.326 11.816c-.118.732.03 1.578.376 2.164.292.494.65.726 1.213.726h65.572c1.649 0 2.42-.429 2.735-.751.252-.258.576-.819.361-2.139-2.662-16.39-17.328-29.024-35.128-29.024-13.09 0-24.486 6.833-30.659 16.968v.24Zm49.871-39.235c0 10.77-8.73 19.5-19.5 19.5s-19.5-8.73-19.5-19.5 8.73-19.5 19.5-19.5 19.5 8.73 19.5 19.5Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-art-accent" fill-rule="evenodd" d="M41.932 101.294a3.075 3.075 0 0 1-1.538-2.665v-.6a3.076 3.076 0 1 1 6.152 0v.6a3.075 3.075 0 0 1-1.538 2.665v4.444a1.538 1.538 0 0 1-3.076 0v-4.444Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-art-accent" fill-rule="evenodd" d="M31.715 80.342c.649-7.236 5.821-12.592 11.755-12.592 5.934 0 11.106 5.356 11.755 12.592h-23.51Zm-2.514.076C29.834 72.08 35.82 65.25 43.47 65.25c7.65 0 13.636 6.83 14.268 15.168 4.533.586 8.034 4.46 8.034 9.152v18.457a9.229 9.229 0 0 1-9.228 9.229H30.396a9.229 9.229 0 0 1-9.228-9.229V89.57c0-4.692 3.501-8.566 8.034-9.152Zm1.195 2.424h26.148a6.728 6.728 0 0 1 6.728 6.728v18.457a6.729 6.729 0 0 1-6.728 6.729H30.396a6.729 6.729 0 0 1-6.728-6.729V89.57a6.728 6.728 0 0 1 6.728-6.728Z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
|
||||
@@ -2,11 +2,11 @@ import { svgIcon } from "@bitwarden/components";
|
||||
|
||||
export const SecurityHandshake = svgIcon`
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="150" fill="none">
|
||||
<path class="tw-fill-background-alt4" fill-rule="evenodd" d="M55.54 113.815c1.794.909 3.324 1.383 4.435 1.727l.015.005c.777.24 1.185.374 1.432.507.368.197.8.234 1.196.101.178-.059.34-.136.424-.176l.015-.007c.074-.035.111-.052.145-.066l.043-.016c.091-.023.18-.054.265-.093 1.521-.703 3.915-1.763 5.936-2.033a1.508 1.508 0 1 0-.4-2.989c-2.483.331-5.207 1.549-6.698 2.235a3.936 3.936 0 0 0-.205.071 19.521 19.521 0 0 0-1.259-.415m-5.344 1.149-7.071 12.092 10.526 5.46a1.508 1.508 0 1 1-1.392 2.677l-11.297-5.861a1.438 1.438 0 0 1-.086-.048c-1.192-.72-1.31-2.134-.741-3.096l7.824-13.379.006-.011a2.254 2.254 0 0 1 2.988-.846c1.819 1.003 3.36 1.483 4.587 1.863m30.235 16.5a1.511 1.511 0 0 1 2.097.401c.607.894.98 1.89.98 2.92 0 1.046-.387 2.014-1.104 2.799-.651.739-1.616 1.204-2.55 1.384-.396 1.524-1.314 2.468-2.166 2.927-.453.29-.949.482-1.457.579a4.34 4.34 0 0 1-.753 1.255c-.778 1.183-2.122 1.69-3.26 1.717-.528.684-1.278 1.183-2.103 1.523a1.378 1.378 0 0 1-.207.068c-.479.121-.86.121-1.15.12h-.031c-1.046 0-2.113-.377-2.97-.771a17.903 17.903 0 0 1-2.326-1.316 1.507 1.507 0 0 1-.425-2.09 1.512 1.512 0 0 1 2.092-.425c.54.357 1.225.771 1.921 1.091.729.335 1.319.495 1.708.495.158 0 .232 0 .297-.005a.5.5 0 0 0 .057-.006c.642-.289.817-.592.864-.75a1.509 1.509 0 0 1 2.019-.963.34.34 0 0 0 .035.013l.006.001h.118c.425 0 .74-.204.844-.378.052-.087.112-.169.18-.244.233-.255.341-.534.351-.854a1.508 1.508 0 0 1 1.765-1.439.995.995 0 0 0 .183.016c.228 0 .45-.066.634-.19.052-.035.106-.067.162-.095.135-.068.748-.467.788-1.786a1.506 1.506 0 0 1 1.77-1.439c.056.009.122.015.19.015.46 0 .97-.241 1.148-.447l.03-.033c.233-.253.32-.506.32-.772 0-.291-.106-.707-.459-1.226a1.507 1.507 0 0 1 .402-2.095Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-background-alt4" fill-rule="evenodd" d="M72 112.173c-1.273.841-2.725 2.355-4.115 5.058l-.01.017-.008.017c-.151.275-.17.673.06 1.112.223.352.93.775 2.136.148l.002-.001c1.492-.774 2.61-1.589 3.249-2.055l.27-.196.394-.28h.483c1.04 0 1.622-.069 1.973-.127l1.176-.195.463 1.096c.27.638.738 1.674 1.75 2.722 1.003 1.039 2.605 2.153 5.227 2.823l.379.097 6.936 6.552 9.308-5.228-6.9-11.821-8.164 3.699-9.407-4.142-.055-.019a5.217 5.217 0 0 1-.143-.052 4.902 4.902 0 0 0-1.654-.284c-.92 0-2.086.225-3.35 1.059Zm-1.665-2.515c1.808-1.195 3.566-1.56 5.014-1.56a7.942 7.942 0 0 1 2.62.442h.067l8.555 3.767 7.51-3.403c.622-.295 1.275-.21 1.71-.065a2.269 2.269 0 0 1 1.288 1.069l7.663 13.128.041.102c.447 1.114-.052 2.174-.793 2.728l-.079.059-10.628 5.969-.034.017a2.14 2.14 0 0 1-.611.203c-.186.031-.36.03-.42.03h-.013a2.308 2.308 0 0 1-1.566-.644l-6.743-6.369c-2.938-.818-4.923-2.157-6.267-3.548a11.163 11.163 0 0 1-1.879-2.613c-.241.016-.51.028-.81.034a27.07 27.07 0 0 1-3.503 2.196c-2.178 1.133-4.872.843-6.142-1.31l-.013-.021-.012-.021c-.64-1.17-.807-2.672-.084-4.011 1.569-3.044 3.333-4.993 5.129-6.179ZM57.94 130.702c.891-1.069 2.069-1.933 3.664-1.8l.008.001.01.001c.935.089 1.694.495 2.265.942.338-.144.68-.255 1.02-.329.627-.138 1.35-.175 2.03.051l.01.004.01.004c.977.341 1.645 1.027 2.088 1.686.1.002.202.008.305.017 1.872.175 2.963 1.224 3.556 2.131.99.251 1.717.81 2.216 1.488.572.777.794 1.647.905 2.123.353 1.346.505 3.585.005 5.75l-.012.052-.016.052c-.523 1.697-2.08 2.624-3.747 2.624-1.286 0-2.644-.473-3.66-1.359-1.753-.177-3.254-.773-4.257-1.985a5.169 5.169 0 0 1-3.062-1.144l-.03-.025-.03-.026a4.962 4.962 0 0 1-1.3-1.834 7.301 7.301 0 0 1-1.28-.677c-.767-.513-1.61-1.319-2.011-2.519-.59-1.766-.012-3.553 1.287-5.197l.013-.016.013-.015Zm2.332 1.915c-.918 1.168-.934 1.9-.78 2.359.118.355.396.679.827.968.43.287.91.469 1.226.561l.843.246.203.853c.13.545.38.869.605 1.076.441.341.906.462 1.33.462.1 0 .185-.012.26-.028l1.153-.253.524 1.056c.026.051.053.101.083.151.305.466.902.901 2.221 1.056l.848-.401.748.917c.401.493 1.156.843 1.894.843.531 0 .763-.234.848-.457.37-1.661.23-3.382-.003-4.254l-.007-.025-.005-.025c-.098-.423-.212-.781-.402-1.039-.135-.183-.335-.366-.838-.395l-.93-.054-.37-.855c-.189-.439-.584-1.013-1.482-1.097a.998.998 0 0 0-.402.042l-1.315.417-.533-1.272a2.837 2.837 0 0 0-.41-.7c-.156-.188-.302-.291-.43-.34-.02-.003-.153-.026-.421.033a3.292 3.292 0 0 0-.967.405l-.097.065-1.137.789-.885-1.063a2.803 2.803 0 0 0-.562-.523 1.255 1.255 0 0 0-.565-.228c-.189-.014-.494.023-1.072.71Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-background-alt4" fill-rule="evenodd" d="M65.358 131.532a.754.754 0 0 1-.246 1.038l-.103.062c-.269.163-.767.464-1.28.884-.602.495-1.119 1.074-1.317 1.666-.137.411-.148.939-.064 1.485.083.542.25 1.032.4 1.333a.754.754 0 0 1-1.35.674 6.278 6.278 0 0 1-.543-1.777c-.104-.679-.116-1.471.125-2.191.334-1.002 1.12-1.804 1.79-2.355.605-.496 1.201-.855 1.463-1.012l.087-.053a.756.756 0 0 1 1.038.246ZM68.873 132.736c.19.37.044.825-.326 1.015-.456.234-1.697 1.226-2.23 3.049-.556 1.904-.188 3.039-.072 3.236a.754.754 0 1 1-1.305.76c-.38-.653-.708-2.24-.072-4.418.66-2.26 2.202-3.564 2.988-3.968a.754.754 0 0 1 1.017.326ZM72.056 135.181c.191.37.045.825-.326 1.015-.141.073-.415.314-.724.782a6.358 6.358 0 0 0-.77 1.693c-.187.637-.246 1.364-.225 1.989.01.31.04.58.077.788.034.182.065.271.074.295.002.007.002.008 0 .005a.755.755 0 0 1-1.304.76c-.132-.226-.208-.527-.255-.792a7.079 7.079 0 0 1-.1-1.006c-.025-.737.04-1.631.283-2.461a7.84 7.84 0 0 1 .96-2.102c.365-.553.814-1.046 1.294-1.292a.756.756 0 0 1 1.016.326ZM77.04 136.44l.01.008.027.025.11.101a54.371 54.371 0 0 0 1.782 1.551c1.106.921 2.391 1.905 3.282 2.35a.754.754 0 1 1-.675 1.349c-1.068-.534-2.477-1.628-3.574-2.541a57.15 57.15 0 0 1-1.833-1.595l-.114-.105-.03-.028-.012-.01.514-.553-.514.553a.754.754 0 1 1 1.027-1.105ZM78.495 132.514l.012.011.038.034.15.13a74.33 74.33 0 0 0 2.44 2.015c1.507 1.19 3.281 2.483 4.53 3.075a.753.753 0 1 1-.648 1.362c-1.422-.674-3.32-2.071-4.819-3.254-.76-.6-1.433-1.159-1.918-1.569-.242-.204-.438-.372-.572-.488l-.156-.135-.04-.036-.015-.013.499-.566-.5.566a.756.756 0 0 1 .998-1.132ZM81.422 128.595l.014.012.044.037.17.142c.15.124.366.303.635.522.54.439 1.29 1.038 2.133 1.679 1.707 1.297 3.727 2.715 5.154 3.366a.753.753 0 1 1-.627 1.372c-1.6-.73-3.742-2.247-5.441-3.538a87.058 87.058 0 0 1-2.82-2.242l-.176-.147-.046-.039-.016-.014.488-.575-.488.575a.754.754 0 1 1 .976-1.15ZM134.303 48.211a61.447 61.447 0 0 1-.856 38.597 61.76 61.76 0 0 1-23.725 30.537 1.511 1.511 0 0 1-2.096-.409 1.507 1.507 0 0 1 .408-2.093 58.736 58.736 0 0 0 22.567-29.045 58.431 58.431 0 0 0 .814-36.704 58.696 58.696 0 0 0-21.256-30.008 59.167 59.167 0 0 0-35.015-11.57 59.17 59.17 0 0 0-35.071 11.4A58.707 58.707 0 0 0 18.669 48.82a58.433 58.433 0 0 0 .634 36.708 58.733 58.733 0 0 0 22.424 29.154c.69.469.868 1.407.399 2.095a1.51 1.51 0 0 1-2.098.398 61.752 61.752 0 0 1-23.575-30.652 61.446 61.446 0 0 1-.667-38.6 61.723 61.723 0 0 1 22.502-31.44A62.192 62.192 0 0 1 75.153 4.5a62.188 62.188 0 0 1 36.803 12.161 61.714 61.714 0 0 1 22.348 31.55Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-art-primary" fill-rule="evenodd" d="M55.54 113.815c1.794.909 3.324 1.383 4.435 1.727l.015.005c.777.24 1.185.374 1.432.507.368.197.8.234 1.196.101.178-.059.34-.136.424-.176l.015-.007c.074-.035.111-.052.145-.066l.043-.016c.091-.023.18-.054.265-.093 1.521-.703 3.915-1.763 5.936-2.033a1.508 1.508 0 1 0-.4-2.989c-2.483.331-5.207 1.549-6.698 2.235a3.936 3.936 0 0 0-.205.071 19.521 19.521 0 0 0-1.259-.415m-5.344 1.149-7.071 12.092 10.526 5.46a1.508 1.508 0 1 1-1.392 2.677l-11.297-5.861a1.438 1.438 0 0 1-.086-.048c-1.192-.72-1.31-2.134-.741-3.096l7.824-13.379.006-.011a2.254 2.254 0 0 1 2.988-.846c1.819 1.003 3.36 1.483 4.587 1.863m30.235 16.5a1.511 1.511 0 0 1 2.097.401c.607.894.98 1.89.98 2.92 0 1.046-.387 2.014-1.104 2.799-.651.739-1.616 1.204-2.55 1.384-.396 1.524-1.314 2.468-2.166 2.927-.453.29-.949.482-1.457.579a4.34 4.34 0 0 1-.753 1.255c-.778 1.183-2.122 1.69-3.26 1.717-.528.684-1.278 1.183-2.103 1.523a1.378 1.378 0 0 1-.207.068c-.479.121-.86.121-1.15.12h-.031c-1.046 0-2.113-.377-2.97-.771a17.903 17.903 0 0 1-2.326-1.316 1.507 1.507 0 0 1-.425-2.09 1.512 1.512 0 0 1 2.092-.425c.54.357 1.225.771 1.921 1.091.729.335 1.319.495 1.708.495.158 0 .232 0 .297-.005a.5.5 0 0 0 .057-.006c.642-.289.817-.592.864-.75a1.509 1.509 0 0 1 2.019-.963.34.34 0 0 0 .035.013l.006.001h.118c.425 0 .74-.204.844-.378.052-.087.112-.169.18-.244.233-.255.341-.534.351-.854a1.508 1.508 0 0 1 1.765-1.439.995.995 0 0 0 .183.016c.228 0 .45-.066.634-.19.052-.035.106-.067.162-.095.135-.068.748-.467.788-1.786a1.506 1.506 0 0 1 1.77-1.439c.056.009.122.015.19.015.46 0 .97-.241 1.148-.447l.03-.033c.233-.253.32-.506.32-.772 0-.291-.106-.707-.459-1.226a1.507 1.507 0 0 1 .402-2.095Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-art-primary" fill-rule="evenodd" d="M72 112.173c-1.273.841-2.725 2.355-4.115 5.058l-.01.017-.008.017c-.151.275-.17.673.06 1.112.223.352.93.775 2.136.148l.002-.001c1.492-.774 2.61-1.589 3.249-2.055l.27-.196.394-.28h.483c1.04 0 1.622-.069 1.973-.127l1.176-.195.463 1.096c.27.638.738 1.674 1.75 2.722 1.003 1.039 2.605 2.153 5.227 2.823l.379.097 6.936 6.552 9.308-5.228-6.9-11.821-8.164 3.699-9.407-4.142-.055-.019a5.217 5.217 0 0 1-.143-.052 4.902 4.902 0 0 0-1.654-.284c-.92 0-2.086.225-3.35 1.059Zm-1.665-2.515c1.808-1.195 3.566-1.56 5.014-1.56a7.942 7.942 0 0 1 2.62.442h.067l8.555 3.767 7.51-3.403c.622-.295 1.275-.21 1.71-.065a2.269 2.269 0 0 1 1.288 1.069l7.663 13.128.041.102c.447 1.114-.052 2.174-.793 2.728l-.079.059-10.628 5.969-.034.017a2.14 2.14 0 0 1-.611.203c-.186.031-.36.03-.42.03h-.013a2.308 2.308 0 0 1-1.566-.644l-6.743-6.369c-2.938-.818-4.923-2.157-6.267-3.548a11.163 11.163 0 0 1-1.879-2.613c-.241.016-.51.028-.81.034a27.07 27.07 0 0 1-3.503 2.196c-2.178 1.133-4.872.843-6.142-1.31l-.013-.021-.012-.021c-.64-1.17-.807-2.672-.084-4.011 1.569-3.044 3.333-4.993 5.129-6.179ZM57.94 130.702c.891-1.069 2.069-1.933 3.664-1.8l.008.001.01.001c.935.089 1.694.495 2.265.942.338-.144.68-.255 1.02-.329.627-.138 1.35-.175 2.03.051l.01.004.01.004c.977.341 1.645 1.027 2.088 1.686.1.002.202.008.305.017 1.872.175 2.963 1.224 3.556 2.131.99.251 1.717.81 2.216 1.488.572.777.794 1.647.905 2.123.353 1.346.505 3.585.005 5.75l-.012.052-.016.052c-.523 1.697-2.08 2.624-3.747 2.624-1.286 0-2.644-.473-3.66-1.359-1.753-.177-3.254-.773-4.257-1.985a5.169 5.169 0 0 1-3.062-1.144l-.03-.025-.03-.026a4.962 4.962 0 0 1-1.3-1.834 7.301 7.301 0 0 1-1.28-.677c-.767-.513-1.61-1.319-2.011-2.519-.59-1.766-.012-3.553 1.287-5.197l.013-.016.013-.015Zm2.332 1.915c-.918 1.168-.934 1.9-.78 2.359.118.355.396.679.827.968.43.287.91.469 1.226.561l.843.246.203.853c.13.545.38.869.605 1.076.441.341.906.462 1.33.462.1 0 .185-.012.26-.028l1.153-.253.524 1.056c.026.051.053.101.083.151.305.466.902.901 2.221 1.056l.848-.401.748.917c.401.493 1.156.843 1.894.843.531 0 .763-.234.848-.457.37-1.661.23-3.382-.003-4.254l-.007-.025-.005-.025c-.098-.423-.212-.781-.402-1.039-.135-.183-.335-.366-.838-.395l-.93-.054-.37-.855c-.189-.439-.584-1.013-1.482-1.097a.998.998 0 0 0-.402.042l-1.315.417-.533-1.272a2.837 2.837 0 0 0-.41-.7c-.156-.188-.302-.291-.43-.34-.02-.003-.153-.026-.421.033a3.292 3.292 0 0 0-.967.405l-.097.065-1.137.789-.885-1.063a2.803 2.803 0 0 0-.562-.523 1.255 1.255 0 0 0-.565-.228c-.189-.014-.494.023-1.072.71Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-art-primary" fill-rule="evenodd" d="M65.358 131.532a.754.754 0 0 1-.246 1.038l-.103.062c-.269.163-.767.464-1.28.884-.602.495-1.119 1.074-1.317 1.666-.137.411-.148.939-.064 1.485.083.542.25 1.032.4 1.333a.754.754 0 0 1-1.35.674 6.278 6.278 0 0 1-.543-1.777c-.104-.679-.116-1.471.125-2.191.334-1.002 1.12-1.804 1.79-2.355.605-.496 1.201-.855 1.463-1.012l.087-.053a.756.756 0 0 1 1.038.246ZM68.873 132.736c.19.37.044.825-.326 1.015-.456.234-1.697 1.226-2.23 3.049-.556 1.904-.188 3.039-.072 3.236a.754.754 0 1 1-1.305.76c-.38-.653-.708-2.24-.072-4.418.66-2.26 2.202-3.564 2.988-3.968a.754.754 0 0 1 1.017.326ZM72.056 135.181c.191.37.045.825-.326 1.015-.141.073-.415.314-.724.782a6.358 6.358 0 0 0-.77 1.693c-.187.637-.246 1.364-.225 1.989.01.31.04.58.077.788.034.182.065.271.074.295.002.007.002.008 0 .005a.755.755 0 0 1-1.304.76c-.132-.226-.208-.527-.255-.792a7.079 7.079 0 0 1-.1-1.006c-.025-.737.04-1.631.283-2.461a7.84 7.84 0 0 1 .96-2.102c.365-.553.814-1.046 1.294-1.292a.756.756 0 0 1 1.016.326ZM77.04 136.44l.01.008.027.025.11.101a54.371 54.371 0 0 0 1.782 1.551c1.106.921 2.391 1.905 3.282 2.35a.754.754 0 1 1-.675 1.349c-1.068-.534-2.477-1.628-3.574-2.541a57.15 57.15 0 0 1-1.833-1.595l-.114-.105-.03-.028-.012-.01.514-.553-.514.553a.754.754 0 1 1 1.027-1.105ZM78.495 132.514l.012.011.038.034.15.13a74.33 74.33 0 0 0 2.44 2.015c1.507 1.19 3.281 2.483 4.53 3.075a.753.753 0 1 1-.648 1.362c-1.422-.674-3.32-2.071-4.819-3.254-.76-.6-1.433-1.159-1.918-1.569-.242-.204-.438-.372-.572-.488l-.156-.135-.04-.036-.015-.013.499-.566-.5.566a.756.756 0 0 1 .998-1.132ZM81.422 128.595l.014.012.044.037.17.142c.15.124.366.303.635.522.54.439 1.29 1.038 2.133 1.679 1.707 1.297 3.727 2.715 5.154 3.366a.753.753 0 1 1-.627 1.372c-1.6-.73-3.742-2.247-5.441-3.538a87.058 87.058 0 0 1-2.82-2.242l-.176-.147-.046-.039-.016-.014.488-.575-.488.575a.754.754 0 1 1 .976-1.15ZM134.303 48.211a61.447 61.447 0 0 1-.856 38.597 61.76 61.76 0 0 1-23.725 30.537 1.511 1.511 0 0 1-2.096-.409 1.507 1.507 0 0 1 .408-2.093 58.736 58.736 0 0 0 22.567-29.045 58.431 58.431 0 0 0 .814-36.704 58.696 58.696 0 0 0-21.256-30.008 59.167 59.167 0 0 0-35.015-11.57 59.17 59.17 0 0 0-35.071 11.4A58.707 58.707 0 0 0 18.669 48.82a58.433 58.433 0 0 0 .634 36.708 58.733 58.733 0 0 0 22.424 29.154c.69.469.868 1.407.399 2.095a1.51 1.51 0 0 1-2.098.398 61.752 61.752 0 0 1-23.575-30.652 61.446 61.446 0 0 1-.667-38.6 61.723 61.723 0 0 1 22.502-31.44A62.192 62.192 0 0 1 75.153 4.5a62.188 62.188 0 0 1 36.803 12.161 61.714 61.714 0 0 1 22.348 31.55Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-art-accent" fill-rule="evenodd" d="M128.53 49.913a55.343 55.343 0 0 1-.771 34.77 55.64 55.64 0 0 1-21.378 27.512.755.755 0 0 1-.844-1.25 54.131 54.131 0 0 0 20.799-26.766 53.85 53.85 0 0 0 .751-33.825 54.094 54.094 0 0 0-19.592-27.653 54.534 54.534 0 0 0-32.27-10.66 54.537 54.537 0 0 0-32.322 10.503 54.1 54.1 0 0 0-19.727 27.558 53.841 53.841 0 0 0 .585 33.828 54.125 54.125 0 0 0 20.667 26.866.754.754 0 1 1-.85 1.247 55.637 55.637 0 0 1-21.243-27.616 55.347 55.347 0 0 1-.6-34.774A55.608 55.608 0 0 1 42.01 21.328a56.05 56.05 0 0 1 33.218-10.796 56.044 56.044 0 0 1 33.164 10.957 55.597 55.597 0 0 1 20.137 28.424Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-background-alt4" fill-rule="evenodd" d="M61.17 48.3c.727-8.197 6.577-14.301 13.33-14.301 6.754 0 12.604 6.104 13.33 14.3a12.392 12.392 0 0 0-.35-.004H61.52c-.117 0-.234.002-.35.005Zm-2.53.343c.6-9.417 7.306-17.144 15.86-17.144 8.555 0 15.26 7.727 15.862 17.144 5.247 1.291 9.138 6.028 9.138 11.673v17.412c0 6.64-5.382 12.022-12.02 12.022H61.52c-6.639 0-12.02-5.383-12.02-12.022V60.316c0-5.646 3.891-10.382 9.138-11.673Zm2.881 2.152H87.48A9.521 9.521 0 0 1 97 60.316v17.412a9.521 9.521 0 0 1-9.52 9.522H61.52a9.521 9.521 0 0 1-9.52-9.522V60.316a9.521 9.521 0 0 1 9.52-9.521Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-art-primary" fill-rule="evenodd" d="M61.17 48.3c.727-8.197 6.577-14.301 13.33-14.301 6.754 0 12.604 6.104 13.33 14.3a12.392 12.392 0 0 0-.35-.004H61.52c-.117 0-.234.002-.35.005Zm-2.53.343c.6-9.417 7.306-17.144 15.86-17.144 8.555 0 15.26 7.727 15.862 17.144 5.247 1.291 9.138 6.028 9.138 11.673v17.412c0 6.64-5.382 12.022-12.02 12.022H61.52c-6.639 0-12.02-5.383-12.02-12.022V60.316c0-5.646 3.891-10.382 9.138-11.673Zm2.881 2.152H87.48A9.521 9.521 0 0 1 97 60.316v17.412a9.521 9.521 0 0 1-9.52 9.522H61.52a9.521 9.521 0 0 1-9.52-9.522V60.316a9.521 9.521 0 0 1 9.52-9.521Z" clip-rule="evenodd"/>
|
||||
<path class="tw-fill-art-accent" fill-rule="evenodd" d="M72.741 71.859a3.499 3.499 0 0 1-1.74-3.027v-.674a3.5 3.5 0 1 1 7 0v.674c0 1.292-.7 2.42-1.742 3.027v4.956a1.76 1.76 0 1 1-3.518 0V71.86Z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
18
package-lock.json
generated
18
package-lock.json
generated
@@ -24,7 +24,7 @@
|
||||
"@angular/platform-browser": "18.2.13",
|
||||
"@angular/platform-browser-dynamic": "18.2.13",
|
||||
"@angular/router": "18.2.13",
|
||||
"@bitwarden/sdk-internal": "0.2.0-main.133",
|
||||
"@bitwarden/sdk-internal": "0.2.0-main.137",
|
||||
"@electron/fuses": "1.8.0",
|
||||
"@emotion/css": "11.13.5",
|
||||
"@koa/multer": "3.0.2",
|
||||
@@ -48,7 +48,7 @@
|
||||
"jquery": "3.7.1",
|
||||
"jsdom": "26.0.0",
|
||||
"jszip": "3.10.1",
|
||||
"koa": "2.15.4",
|
||||
"koa": "2.16.1",
|
||||
"koa-bodyparser": "4.4.1",
|
||||
"koa-json": "2.0.2",
|
||||
"lit": "3.2.1",
|
||||
@@ -210,7 +210,7 @@
|
||||
"inquirer": "8.2.6",
|
||||
"jsdom": "26.0.0",
|
||||
"jszip": "3.10.1",
|
||||
"koa": "2.15.4",
|
||||
"koa": "2.16.1",
|
||||
"koa-bodyparser": "4.4.1",
|
||||
"koa-json": "2.0.2",
|
||||
"lowdb": "1.0.0",
|
||||
@@ -4700,9 +4700,9 @@
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@bitwarden/sdk-internal": {
|
||||
"version": "0.2.0-main.133",
|
||||
"resolved": "https://registry.npmjs.org/@bitwarden/sdk-internal/-/sdk-internal-0.2.0-main.133.tgz",
|
||||
"integrity": "sha512-KzKJGf9cKlcQzfRmqkAwVGBN1kDpcRFkTMm7nrphZSrjfaWJWI1lBEJ0DhnkbMMHJXhQavGyoVk5TIn/Y8ylmw==",
|
||||
"version": "0.2.0-main.137",
|
||||
"resolved": "https://registry.npmjs.org/@bitwarden/sdk-internal/-/sdk-internal-0.2.0-main.137.tgz",
|
||||
"integrity": "sha512-Df0pB5tOEc4WiMjskunTrqHulPzenFv8C61sqsBhHfy80xcf5kU5JyPd4asbf3e4uNS6QGXptd8imp09AuiFEA==",
|
||||
"license": "GPL-3.0"
|
||||
},
|
||||
"node_modules/@bitwarden/send-ui": {
|
||||
@@ -24789,9 +24789,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/koa": {
|
||||
"version": "2.15.4",
|
||||
"resolved": "https://registry.npmjs.org/koa/-/koa-2.15.4.tgz",
|
||||
"integrity": "sha512-7fNBIdrU2PEgLljXoPWoyY4r1e+ToWCmzS/wwMPbUNs7X+5MMET1ObhJBlUkF5uZG9B6QhM2zS1TsH6adegkiQ==",
|
||||
"version": "2.16.1",
|
||||
"resolved": "https://registry.npmjs.org/koa/-/koa-2.16.1.tgz",
|
||||
"integrity": "sha512-umfX9d3iuSxTQP4pnzLOz0HKnPg0FaUUIKcye2lOiz3KPu1Y3M3xlz76dISdFPQs37P9eJz1wUpcTS6KDPn9fA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"accepts": "^1.3.5",
|
||||
|
||||
@@ -156,7 +156,7 @@
|
||||
"@angular/platform-browser": "18.2.13",
|
||||
"@angular/platform-browser-dynamic": "18.2.13",
|
||||
"@angular/router": "18.2.13",
|
||||
"@bitwarden/sdk-internal": "0.2.0-main.133",
|
||||
"@bitwarden/sdk-internal": "0.2.0-main.137",
|
||||
"@electron/fuses": "1.8.0",
|
||||
"@emotion/css": "11.13.5",
|
||||
"@koa/multer": "3.0.2",
|
||||
@@ -180,7 +180,7 @@
|
||||
"jquery": "3.7.1",
|
||||
"jsdom": "26.0.0",
|
||||
"jszip": "3.10.1",
|
||||
"koa": "2.15.4",
|
||||
"koa": "2.16.1",
|
||||
"koa-bodyparser": "4.4.1",
|
||||
"koa-json": "2.0.2",
|
||||
"lit": "3.2.1",
|
||||
|
||||
Reference in New Issue
Block a user