mirror of
https://github.com/bitwarden/browser
synced 2025-12-19 01:33:33 +00:00
Merge branch 'main' into auth/pm-14369/hide-account-switcher-if-on-login-page-and-not-logged-in
This commit is contained in:
4
.github/renovate.json
vendored
4
.github/renovate.json
vendored
@@ -73,7 +73,7 @@
|
|||||||
"reviewers": ["team:team-admin-console-dev"]
|
"reviewers": ["team:team-admin-console-dev"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"matchPackageNames": ["@types/node-ipc", "node-ipc", "qrious", "regedit"],
|
"matchPackageNames": ["@types/node-ipc", "node-ipc", "qrious"],
|
||||||
"description": "Auth owned dependencies",
|
"description": "Auth owned dependencies",
|
||||||
"commitMessagePrefix": "[deps] Auth:",
|
"commitMessagePrefix": "[deps] Auth:",
|
||||||
"reviewers": ["team:team-auth-dev"]
|
"reviewers": ["team:team-auth-dev"]
|
||||||
@@ -258,5 +258,5 @@
|
|||||||
"reviewers": ["team:team-vault-dev"]
|
"reviewers": ["team:team-vault-dev"]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ignoreDeps": ["@types/koa-bodyparser", "bootstrap", "node-ipc", "node", "npm", "regedit"]
|
"ignoreDeps": ["@types/koa-bodyparser", "bootstrap", "node-ipc", "node", "npm"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,10 +128,10 @@
|
|||||||
"builder": "@angular-devkit/build-angular:dev-server",
|
"builder": "@angular-devkit/build-angular:dev-server",
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"production": {
|
"production": {
|
||||||
"browserTarget": "test-storybook:build:production"
|
"buildTarget": "test-storybook:build:production"
|
||||||
},
|
},
|
||||||
"development": {
|
"development": {
|
||||||
"browserTarget": "test-storybook:build:development"
|
"buildTarget": "test-storybook:build:development"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"defaultConfiguration": "development"
|
"defaultConfiguration": "development"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@bitwarden/browser",
|
"name": "@bitwarden/browser",
|
||||||
"version": "2024.10.1",
|
"version": "2024.11.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "cross-env MANIFEST_VERSION=3 webpack",
|
"build": "cross-env MANIFEST_VERSION=3 webpack",
|
||||||
"build:mv2": "webpack",
|
"build:mv2": "webpack",
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import {
|
|||||||
} from "@bitwarden/common/spec";
|
} from "@bitwarden/common/spec";
|
||||||
import { UserId } from "@bitwarden/common/types/guid";
|
import { UserId } from "@bitwarden/common/types/guid";
|
||||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||||
|
import { TotpService } from "@bitwarden/common/vault/abstractions/totp.service";
|
||||||
import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service";
|
import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service";
|
||||||
import { CipherRepromptType, CipherType } from "@bitwarden/common/vault/enums";
|
import { CipherRepromptType, CipherType } from "@bitwarden/common/vault/enums";
|
||||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||||
@@ -106,6 +107,7 @@ describe("OverlayBackground", () => {
|
|||||||
let selectedThemeMock$: BehaviorSubject<ThemeType>;
|
let selectedThemeMock$: BehaviorSubject<ThemeType>;
|
||||||
let inlineMenuFieldQualificationService: InlineMenuFieldQualificationService;
|
let inlineMenuFieldQualificationService: InlineMenuFieldQualificationService;
|
||||||
let themeStateService: MockProxy<ThemeStateService>;
|
let themeStateService: MockProxy<ThemeStateService>;
|
||||||
|
let totpService: MockProxy<TotpService>;
|
||||||
let overlayBackground: OverlayBackground;
|
let overlayBackground: OverlayBackground;
|
||||||
let portKeyForTabSpy: Record<number, string>;
|
let portKeyForTabSpy: Record<number, string>;
|
||||||
let pageDetailsForTabSpy: PageDetailsForTab;
|
let pageDetailsForTabSpy: PageDetailsForTab;
|
||||||
@@ -184,6 +186,7 @@ describe("OverlayBackground", () => {
|
|||||||
inlineMenuFieldQualificationService = new InlineMenuFieldQualificationService();
|
inlineMenuFieldQualificationService = new InlineMenuFieldQualificationService();
|
||||||
themeStateService = mock<ThemeStateService>();
|
themeStateService = mock<ThemeStateService>();
|
||||||
themeStateService.selectedTheme$ = selectedThemeMock$;
|
themeStateService.selectedTheme$ = selectedThemeMock$;
|
||||||
|
totpService = mock<TotpService>();
|
||||||
overlayBackground = new OverlayBackground(
|
overlayBackground = new OverlayBackground(
|
||||||
logService,
|
logService,
|
||||||
cipherService,
|
cipherService,
|
||||||
@@ -198,6 +201,7 @@ describe("OverlayBackground", () => {
|
|||||||
fido2ActiveRequestManager,
|
fido2ActiveRequestManager,
|
||||||
inlineMenuFieldQualificationService,
|
inlineMenuFieldQualificationService,
|
||||||
themeStateService,
|
themeStateService,
|
||||||
|
totpService,
|
||||||
generatedPasswordCallbackMock,
|
generatedPasswordCallbackMock,
|
||||||
addPasswordCallbackMock,
|
addPasswordCallbackMock,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
|
|||||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||||
import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service";
|
import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service";
|
||||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||||
|
import { TotpService } from "@bitwarden/common/vault/abstractions/totp.service";
|
||||||
import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service";
|
import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service";
|
||||||
import { CipherType } from "@bitwarden/common/vault/enums";
|
import { CipherType } from "@bitwarden/common/vault/enums";
|
||||||
import { buildCipherIcon } from "@bitwarden/common/vault/icon/build-cipher-icon";
|
import { buildCipherIcon } from "@bitwarden/common/vault/icon/build-cipher-icon";
|
||||||
@@ -217,6 +218,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
private fido2ActiveRequestManager: Fido2ActiveRequestManager,
|
private fido2ActiveRequestManager: Fido2ActiveRequestManager,
|
||||||
private inlineMenuFieldQualificationService: InlineMenuFieldQualificationService,
|
private inlineMenuFieldQualificationService: InlineMenuFieldQualificationService,
|
||||||
private themeStateService: ThemeStateService,
|
private themeStateService: ThemeStateService,
|
||||||
|
private totpService: TotpService,
|
||||||
private generatePasswordCallback: () => Promise<string>,
|
private generatePasswordCallback: () => Promise<string>,
|
||||||
private addPasswordCallback: (password: string) => Promise<void>,
|
private addPasswordCallback: (password: string) => Promise<void>,
|
||||||
) {
|
) {
|
||||||
@@ -1058,7 +1060,6 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cipher = this.inlineMenuCiphers.get(inlineMenuCipherId);
|
const cipher = this.inlineMenuCiphers.get(inlineMenuCipherId);
|
||||||
|
|
||||||
if (usePasskey && cipher.login?.hasFido2Credentials) {
|
if (usePasskey && cipher.login?.hasFido2Credentials) {
|
||||||
await this.authenticatePasskeyCredential(
|
await this.authenticatePasskeyCredential(
|
||||||
sender,
|
sender,
|
||||||
@@ -1066,6 +1067,11 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
);
|
);
|
||||||
this.updateLastUsedInlineMenuCipher(inlineMenuCipherId, cipher);
|
this.updateLastUsedInlineMenuCipher(inlineMenuCipherId, cipher);
|
||||||
|
|
||||||
|
if (cipher.login?.totp) {
|
||||||
|
this.platformUtilsService.copyToClipboard(
|
||||||
|
await this.totpService.getCode(cipher.login.totp),
|
||||||
|
);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1678,6 +1678,7 @@ export default class MainBackground {
|
|||||||
this.fido2ActiveRequestManager,
|
this.fido2ActiveRequestManager,
|
||||||
inlineMenuFieldQualificationService,
|
inlineMenuFieldQualificationService,
|
||||||
this.themeStateService,
|
this.themeStateService,
|
||||||
|
this.totpService,
|
||||||
() => this.generatePassword(),
|
() => this.generatePassword(),
|
||||||
(password) => this.addPasswordToHistory(password),
|
(password) => this.addPasswordToHistory(password),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "__MSG_extName__",
|
"name": "__MSG_extName__",
|
||||||
"short_name": "__MSG_appName__",
|
"short_name": "__MSG_appName__",
|
||||||
"version": "2024.10.1",
|
"version": "2024.11.0",
|
||||||
"description": "__MSG_extDesc__",
|
"description": "__MSG_extDesc__",
|
||||||
"default_locale": "en",
|
"default_locale": "en",
|
||||||
"author": "Bitwarden Inc.",
|
"author": "Bitwarden Inc.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"minimum_chrome_version": "102.0",
|
"minimum_chrome_version": "102.0",
|
||||||
"name": "__MSG_extName__",
|
"name": "__MSG_extName__",
|
||||||
"short_name": "__MSG_appName__",
|
"short_name": "__MSG_appName__",
|
||||||
"version": "2024.10.1",
|
"version": "2024.11.0",
|
||||||
"description": "__MSG_extDesc__",
|
"description": "__MSG_extDesc__",
|
||||||
"default_locale": "en",
|
"default_locale": "en",
|
||||||
"author": "Bitwarden Inc.",
|
"author": "Bitwarden Inc.",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@bitwarden/cli",
|
"name": "@bitwarden/cli",
|
||||||
"description": "A secure and free password manager for all of your devices.",
|
"description": "A secure and free password manager for all of your devices.",
|
||||||
"version": "2024.10.0",
|
"version": "2024.11.0",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"bitwarden",
|
"bitwarden",
|
||||||
"password",
|
"password",
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
"papaparse": "5.4.1",
|
"papaparse": "5.4.1",
|
||||||
"proper-lockfile": "4.1.2",
|
"proper-lockfile": "4.1.2",
|
||||||
"rxjs": "7.8.1",
|
"rxjs": "7.8.1",
|
||||||
"tldts": "6.1.56",
|
"tldts": "6.1.58",
|
||||||
"zxcvbn": "4.4.2"
|
"zxcvbn": "4.4.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
32
apps/desktop/desktop_native/Cargo.lock
generated
32
apps/desktop/desktop_native/Cargo.lock
generated
@@ -546,6 +546,7 @@ dependencies = [
|
|||||||
"napi-derive",
|
"napi-derive",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
|
"windows-registry",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2226,7 +2227,7 @@ checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-implement",
|
"windows-implement",
|
||||||
"windows-interface",
|
"windows-interface",
|
||||||
"windows-result",
|
"windows-result 0.1.2",
|
||||||
"windows-targets 0.52.6",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2252,6 +2253,17 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-registry"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bafa604f2104cf5ae2cc2db1dee84b7e6a5d11b05f737b60def0ffdc398cbc0a"
|
||||||
|
dependencies = [
|
||||||
|
"windows-result 0.2.0",
|
||||||
|
"windows-strings",
|
||||||
|
"windows-targets 0.52.6",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-result"
|
name = "windows-result"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
@@ -2261,6 +2273,24 @@ dependencies = [
|
|||||||
"windows-targets 0.52.6",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-result"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets 0.52.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-strings"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "978d65aedf914c664c510d9de43c8fd85ca745eaff1ed53edf409b479e441663"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets 0.52.6",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
|
|||||||
@@ -21,5 +21,8 @@ napi-derive = "=2.16.12"
|
|||||||
tokio = { version = "1.38.0" }
|
tokio = { version = "1.38.0" }
|
||||||
tokio-util = "0.7.11"
|
tokio-util = "0.7.11"
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
windows-registry = "=0.3.0"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
napi-build = "=2.1.3"
|
napi-build = "=2.1.3"
|
||||||
|
|||||||
4
apps/desktop/desktop_native/napi/index.d.ts
vendored
4
apps/desktop/desktop_native/napi/index.d.ts
vendored
@@ -51,6 +51,10 @@ export declare namespace powermonitors {
|
|||||||
export function onLock(callback: (err: Error | null, ) => any): Promise<void>
|
export function onLock(callback: (err: Error | null, ) => any): Promise<void>
|
||||||
export function isLockMonitorAvailable(): Promise<boolean>
|
export function isLockMonitorAvailable(): Promise<boolean>
|
||||||
}
|
}
|
||||||
|
export declare namespace windows_registry {
|
||||||
|
export function createKey(key: string, subkey: string, value: string): Promise<void>
|
||||||
|
export function deleteKey(key: string, subkey: string): Promise<void>
|
||||||
|
}
|
||||||
export declare namespace ipc {
|
export declare namespace ipc {
|
||||||
export interface IpcMessage {
|
export interface IpcMessage {
|
||||||
clientId: number
|
clientId: number
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate napi_derive;
|
extern crate napi_derive;
|
||||||
|
|
||||||
|
mod registry;
|
||||||
|
|
||||||
#[napi]
|
#[napi]
|
||||||
pub mod passwords {
|
pub mod passwords {
|
||||||
/// Fetch the stored password from the keychain.
|
/// Fetch the stored password from the keychain.
|
||||||
@@ -190,6 +193,21 @@ pub mod powermonitors {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[napi]
|
||||||
|
pub mod windows_registry {
|
||||||
|
#[napi]
|
||||||
|
pub async fn create_key(key: String, subkey: String, value: String) -> napi::Result<()> {
|
||||||
|
crate::registry::create_key(&key, &subkey, &value)
|
||||||
|
.map_err(|e| napi::Error::from_reason(e.to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[napi]
|
||||||
|
pub async fn delete_key(key: String, subkey: String) -> napi::Result<()> {
|
||||||
|
crate::registry::delete_key(&key, &subkey)
|
||||||
|
.map_err(|e| napi::Error::from_reason(e.to_string()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[napi]
|
#[napi]
|
||||||
pub mod ipc {
|
pub mod ipc {
|
||||||
use desktop_core::ipc::server::{Message, MessageType};
|
use desktop_core::ipc::server::{Message, MessageType};
|
||||||
|
|||||||
9
apps/desktop/desktop_native/napi/src/registry/dummy.rs
Normal file
9
apps/desktop/desktop_native/napi/src/registry/dummy.rs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
use anyhow::{bail, Result};
|
||||||
|
|
||||||
|
pub fn create_key(_key: &str, _subkey: &str, _value: &str) -> Result<()> {
|
||||||
|
bail!("Not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete_key(_key: &str, _subkey: &str) -> Result<()> {
|
||||||
|
bail!("Not implemented")
|
||||||
|
}
|
||||||
4
apps/desktop/desktop_native/napi/src/registry/mod.rs
Normal file
4
apps/desktop/desktop_native/napi/src/registry/mod.rs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#[cfg_attr(target_os = "windows", path = "windows.rs")]
|
||||||
|
#[cfg_attr(not(target_os = "windows"), path = "dummy.rs")]
|
||||||
|
mod internal;
|
||||||
|
pub use internal::*;
|
||||||
29
apps/desktop/desktop_native/napi/src/registry/windows.rs
Normal file
29
apps/desktop/desktop_native/napi/src/registry/windows.rs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
use anyhow::{bail, Result};
|
||||||
|
|
||||||
|
fn convert_key(key: &str) -> Result<&'static windows_registry::Key> {
|
||||||
|
Ok(match key.to_uppercase().as_str() {
|
||||||
|
"HKEY_CURRENT_USER" | "HKCU" => windows_registry::CURRENT_USER,
|
||||||
|
"HKEY_LOCAL_MACHINE" | "HKLM" => windows_registry::LOCAL_MACHINE,
|
||||||
|
"HKEY_CLASSES_ROOT" | "HKCR" => windows_registry::CLASSES_ROOT,
|
||||||
|
_ => bail!("Invalid key"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_key(key: &str, subkey: &str, value: &str) -> Result<()> {
|
||||||
|
let key = convert_key(key)?;
|
||||||
|
|
||||||
|
let subkey = key.create(subkey)?;
|
||||||
|
|
||||||
|
const DEFAULT: &str = "";
|
||||||
|
subkey.set_string(DEFAULT, value)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete_key(key: &str, subkey: &str) -> Result<()> {
|
||||||
|
let key = convert_key(key)?;
|
||||||
|
|
||||||
|
key.remove_tree(subkey)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -90,13 +90,6 @@
|
|||||||
"electronUpdaterCompatibility": ">=0.0.1",
|
"electronUpdaterCompatibility": ">=0.0.1",
|
||||||
"target": ["portable", "nsis-web", "appx"],
|
"target": ["portable", "nsis-web", "appx"],
|
||||||
"sign": "./sign.js",
|
"sign": "./sign.js",
|
||||||
"extraResources": [
|
|
||||||
{
|
|
||||||
"from": "../../node_modules/regedit/vbs",
|
|
||||||
"to": "regedit/vbs",
|
|
||||||
"filter": ["**/*"]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"extraFiles": [
|
"extraFiles": [
|
||||||
{
|
{
|
||||||
"from": "desktop_native/dist/desktop_proxy.${platform}-${arch}.exe",
|
"from": "desktop_native/dist/desktop_proxy.${platform}-${arch}.exe",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@bitwarden/desktop",
|
"name": "@bitwarden/desktop",
|
||||||
"description": "A secure and free password manager for all of your devices.",
|
"description": "A secure and free password manager for all of your devices.",
|
||||||
"version": "2024.10.3",
|
"version": "2024.11.0",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"bitwarden",
|
"bitwarden",
|
||||||
"password",
|
"password",
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
import { existsSync, promises as fs } from "fs";
|
import { existsSync, promises as fs } from "fs";
|
||||||
import { homedir, userInfo } from "os";
|
import { homedir, userInfo } from "os";
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
import * as util from "util";
|
|
||||||
|
|
||||||
import { ipcMain } from "electron";
|
import { ipcMain } from "electron";
|
||||||
|
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
import { ipc } from "@bitwarden/desktop-napi";
|
import { ipc, windows_registry } from "@bitwarden/desktop-napi";
|
||||||
|
|
||||||
import { isDev } from "../utils";
|
import { isDev } from "../utils";
|
||||||
|
|
||||||
@@ -142,12 +141,12 @@ export class NativeMessagingMain {
|
|||||||
await this.writeManifest(path.join(destination, "chrome.json"), chromeJson);
|
await this.writeManifest(path.join(destination, "chrome.json"), chromeJson);
|
||||||
|
|
||||||
const nmhs = this.getWindowsNMHS();
|
const nmhs = this.getWindowsNMHS();
|
||||||
for (const [key, value] of Object.entries(nmhs)) {
|
for (const [name, [key, subkey]] of Object.entries(nmhs)) {
|
||||||
let manifestPath = path.join(destination, "chrome.json");
|
let manifestPath = path.join(destination, "chrome.json");
|
||||||
if (key === "Firefox") {
|
if (name === "Firefox") {
|
||||||
manifestPath = path.join(destination, "firefox.json");
|
manifestPath = path.join(destination, "firefox.json");
|
||||||
}
|
}
|
||||||
await this.createWindowsRegistry(value, manifestPath);
|
await windows_registry.createKey(key, subkey, manifestPath);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -225,8 +224,8 @@ export class NativeMessagingMain {
|
|||||||
await this.removeIfExists(path.join(this.userPath, "browsers", "chrome.json"));
|
await this.removeIfExists(path.join(this.userPath, "browsers", "chrome.json"));
|
||||||
|
|
||||||
const nmhs = this.getWindowsNMHS();
|
const nmhs = this.getWindowsNMHS();
|
||||||
for (const [, value] of Object.entries(nmhs)) {
|
for (const [, [key, subkey]] of Object.entries(nmhs)) {
|
||||||
await this.deleteWindowsRegistry(value);
|
await windows_registry.deleteKey(key, subkey);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -274,11 +273,14 @@ export class NativeMessagingMain {
|
|||||||
|
|
||||||
private getWindowsNMHS() {
|
private getWindowsNMHS() {
|
||||||
return {
|
return {
|
||||||
Firefox: "HKCU\\SOFTWARE\\Mozilla\\NativeMessagingHosts\\com.8bit.bitwarden",
|
Firefox: ["HKCU", "SOFTWARE\\Mozilla\\NativeMessagingHosts\\com.8bit.bitwarden"],
|
||||||
Chrome: "HKCU\\SOFTWARE\\Google\\Chrome\\NativeMessagingHosts\\com.8bit.bitwarden",
|
Chrome: ["HKCU", "SOFTWARE\\Google\\Chrome\\NativeMessagingHosts\\com.8bit.bitwarden"],
|
||||||
Chromium: "HKCU\\SOFTWARE\\Chromium\\NativeMessagingHosts\\com.8bit.bitwarden",
|
Chromium: ["HKCU", "SOFTWARE\\Chromium\\NativeMessagingHosts\\com.8bit.bitwarden"],
|
||||||
// Edge uses the same registry key as Chrome as a fallback, but it's has its own separate key as well.
|
// Edge uses the same registry key as Chrome as a fallback, but it's has its own separate key as well.
|
||||||
"Microsoft Edge": "HKCU\\SOFTWARE\\Microsoft\\Edge\\NativeMessagingHosts\\com.8bit.bitwarden",
|
"Microsoft Edge": [
|
||||||
|
"HKCU",
|
||||||
|
"SOFTWARE\\Microsoft\\Edge\\NativeMessagingHosts\\com.8bit.bitwarden",
|
||||||
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,52 +421,6 @@ export class NativeMessagingMain {
|
|||||||
return path.join(path.dirname(this.exePath), `desktop_proxy${ext}`);
|
return path.join(path.dirname(this.exePath), `desktop_proxy${ext}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
private getRegeditInstance() {
|
|
||||||
// eslint-disable-next-line
|
|
||||||
const regedit = require("regedit");
|
|
||||||
regedit.setExternalVBSLocation(path.join(path.dirname(this.exePath), "resources/regedit/vbs"));
|
|
||||||
|
|
||||||
return regedit;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async createWindowsRegistry(location: string, jsonFile: string) {
|
|
||||||
const regedit = this.getRegeditInstance();
|
|
||||||
|
|
||||||
const createKey = util.promisify(regedit.createKey);
|
|
||||||
const putValue = util.promisify(regedit.putValue);
|
|
||||||
|
|
||||||
this.logService.debug(`Adding registry: ${location}`);
|
|
||||||
|
|
||||||
await createKey(location);
|
|
||||||
|
|
||||||
// Insert path to manifest
|
|
||||||
const obj: any = {};
|
|
||||||
obj[location] = {
|
|
||||||
default: {
|
|
||||||
value: jsonFile,
|
|
||||||
type: "REG_DEFAULT",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return putValue(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async deleteWindowsRegistry(key: string) {
|
|
||||||
const regedit = this.getRegeditInstance();
|
|
||||||
|
|
||||||
const list = util.promisify(regedit.list);
|
|
||||||
const deleteKey = util.promisify(regedit.deleteKey);
|
|
||||||
|
|
||||||
this.logService.debug(`Removing registry: ${key}`);
|
|
||||||
|
|
||||||
try {
|
|
||||||
await list(key);
|
|
||||||
await deleteKey(key);
|
|
||||||
} catch {
|
|
||||||
this.logService.error(`Unable to delete registry key: ${key}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private homedir() {
|
private homedir() {
|
||||||
if (process.platform === "darwin") {
|
if (process.platform === "darwin") {
|
||||||
return userInfo().homedir;
|
return userInfo().homedir;
|
||||||
|
|||||||
4
apps/desktop/src/package-lock.json
generated
4
apps/desktop/src/package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@bitwarden/desktop",
|
"name": "@bitwarden/desktop",
|
||||||
"version": "2024.10.3",
|
"version": "2024.11.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@bitwarden/desktop",
|
"name": "@bitwarden/desktop",
|
||||||
"version": "2024.10.3",
|
"version": "2024.11.0",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@bitwarden/desktop-napi": "file:../desktop_native/napi",
|
"@bitwarden/desktop-napi": "file:../desktop_native/napi",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "@bitwarden/desktop",
|
"name": "@bitwarden/desktop",
|
||||||
"productName": "Bitwarden",
|
"productName": "Bitwarden",
|
||||||
"description": "A secure and free password manager for all of your devices.",
|
"description": "A secure and free password manager for all of your devices.",
|
||||||
"version": "2024.10.3",
|
"version": "2024.11.0",
|
||||||
"author": "Bitwarden Inc. <hello@bitwarden.com> (https://bitwarden.com)",
|
"author": "Bitwarden Inc. <hello@bitwarden.com> (https://bitwarden.com)",
|
||||||
"homepage": "https://bitwarden.com",
|
"homepage": "https://bitwarden.com",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@bitwarden/web-vault",
|
"name": "@bitwarden/web-vault",
|
||||||
"version": "2024.10.5",
|
"version": "2024.11.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:oss": "webpack",
|
"build:oss": "webpack",
|
||||||
"build:bit": "webpack -c ../../bitwarden_license/bit-web/webpack.config.js",
|
"build:bit": "webpack -c ../../bitwarden_license/bit-web/webpack.config.js",
|
||||||
|
|||||||
@@ -23,15 +23,14 @@
|
|||||||
<bit-tab [label]="'role' | i18n">
|
<bit-tab [label]="'role' | i18n">
|
||||||
<ng-container *ngIf="!editMode">
|
<ng-container *ngIf="!editMode">
|
||||||
<p bitTypography="body1">{{ "inviteUserDesc" | i18n }}</p>
|
<p bitTypography="body1">{{ "inviteUserDesc" | i18n }}</p>
|
||||||
<bit-form-field *ngIf="remainingSeats$ | async as remainingSeats">
|
<bit-form-field>
|
||||||
<bit-label>{{ "email" | i18n }}</bit-label>
|
<bit-label>{{ "email" | i18n }}</bit-label>
|
||||||
<input id="emails" type="text" appAutoFocus bitInput formControlName="emails" />
|
<input id="emails" type="text" appAutoFocus bitInput formControlName="emails" />
|
||||||
<bit-hint *ngIf="remainingSeats > 1; else singleSeat">{{
|
<bit-hint>{{
|
||||||
"inviteMultipleEmailDesc" | i18n: remainingSeats
|
"inviteMultipleEmailDesc"
|
||||||
|
| i18n
|
||||||
|
: (organization.productTierType === ProductTierType.TeamsStarter ? "10" : "20")
|
||||||
}}</bit-hint>
|
}}</bit-hint>
|
||||||
<ng-template #singleSeat>
|
|
||||||
<bit-hint>{{ "inviteSingleEmailDesc" | i18n: remainingSeats }}</bit-hint>
|
|
||||||
</ng-template>
|
|
||||||
</bit-form-field>
|
</bit-form-field>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<bit-radio-group formControlName="type">
|
<bit-radio-group formControlName="type">
|
||||||
@@ -265,6 +264,16 @@
|
|||||||
<button
|
<button
|
||||||
*ngIf="editMode"
|
*ngIf="editMode"
|
||||||
type="button"
|
type="button"
|
||||||
|
bitIconButton="bwi-close"
|
||||||
|
buttonType="danger"
|
||||||
|
bitFormButton
|
||||||
|
[appA11yTitle]="'remove' | i18n"
|
||||||
|
[bitAction]="remove"
|
||||||
|
[disabled]="loading"
|
||||||
|
></button>
|
||||||
|
<button
|
||||||
|
*ngIf="editMode && params.managedByOrganization === true"
|
||||||
|
type="button"
|
||||||
bitIconButton="bwi-trash"
|
bitIconButton="bwi-trash"
|
||||||
buttonType="danger"
|
buttonType="danger"
|
||||||
bitFormButton
|
bitFormButton
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ export interface MemberDialogParams {
|
|||||||
isOnSecretsManagerStandalone: boolean;
|
isOnSecretsManagerStandalone: boolean;
|
||||||
initialTab?: MemberDialogTab;
|
initialTab?: MemberDialogTab;
|
||||||
numConfirmedMembers: number;
|
numConfirmedMembers: number;
|
||||||
|
managedByOrganization?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum MemberDialogResult {
|
export enum MemberDialogResult {
|
||||||
@@ -89,7 +90,6 @@ export class MemberDialogComponent implements OnDestroy {
|
|||||||
PermissionMode = PermissionMode;
|
PermissionMode = PermissionMode;
|
||||||
showNoMasterPasswordWarning = false;
|
showNoMasterPasswordWarning = false;
|
||||||
isOnSecretsManagerStandalone: boolean;
|
isOnSecretsManagerStandalone: boolean;
|
||||||
remainingSeats$: Observable<number>;
|
|
||||||
|
|
||||||
protected organization$: Observable<Organization>;
|
protected organization$: Observable<Organization>;
|
||||||
protected collectionAccessItems: AccessItemView[] = [];
|
protected collectionAccessItems: AccessItemView[] = [];
|
||||||
@@ -251,10 +251,6 @@ export class MemberDialogComponent implements OnDestroy {
|
|||||||
|
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.remainingSeats$ = this.organization$.pipe(
|
|
||||||
map((organization) => organization.seats - this.params.numConfirmedMembers),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private setFormValidators(organization: Organization) {
|
private setFormValidators(organization: Organization) {
|
||||||
@@ -469,7 +465,7 @@ export class MemberDialogComponent implements OnDestroy {
|
|||||||
this.close(MemberDialogResult.Saved);
|
this.close(MemberDialogResult.Saved);
|
||||||
};
|
};
|
||||||
|
|
||||||
delete = async () => {
|
remove = async () => {
|
||||||
if (!this.editMode) {
|
if (!this.editMode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -566,6 +562,39 @@ export class MemberDialogComponent implements OnDestroy {
|
|||||||
this.close(MemberDialogResult.Restored);
|
this.close(MemberDialogResult.Restored);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
delete = async () => {
|
||||||
|
if (!this.editMode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirmed = await this.dialogService.openSimpleDialog({
|
||||||
|
title: {
|
||||||
|
key: "deleteOrganizationUser",
|
||||||
|
placeholders: [this.params.name],
|
||||||
|
},
|
||||||
|
content: { key: "deleteOrganizationUserWarning" },
|
||||||
|
type: "warning",
|
||||||
|
acceptButtonText: { key: "delete" },
|
||||||
|
cancelButtonText: { key: "cancel" },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!confirmed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.organizationUserApiService.deleteOrganizationUser(
|
||||||
|
this.params.organizationId,
|
||||||
|
this.params.organizationUserId,
|
||||||
|
);
|
||||||
|
|
||||||
|
this.toastService.showToast({
|
||||||
|
variant: "success",
|
||||||
|
title: null,
|
||||||
|
message: this.i18nService.t("organizationUserDeleted", this.params.name),
|
||||||
|
});
|
||||||
|
this.close(MemberDialogResult.Deleted);
|
||||||
|
};
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.destroy$.next();
|
this.destroy$.next();
|
||||||
this.destroy$.complete();
|
this.destroy$.complete();
|
||||||
|
|||||||
@@ -320,6 +320,17 @@
|
|||||||
<i aria-hidden="true" class="bwi bwi-close"></i> {{ "remove" | i18n }}
|
<i aria-hidden="true" class="bwi bwi-close"></i> {{ "remove" | i18n }}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
*ngIf="u.managedByOrganization === true"
|
||||||
|
type="button"
|
||||||
|
bitMenuItem
|
||||||
|
(click)="deleteUser(u)"
|
||||||
|
>
|
||||||
|
<span class="tw-text-danger">
|
||||||
|
<i class="bwi bwi-fw bwi-trash" aria-hidden="true"></i>
|
||||||
|
{{ "delete" | i18n }}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
</bit-menu>
|
</bit-menu>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -518,6 +518,7 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView>
|
|||||||
isOnSecretsManagerStandalone: this.orgIsOnSecretsManagerStandalone,
|
isOnSecretsManagerStandalone: this.orgIsOnSecretsManagerStandalone,
|
||||||
initialTab: initialTab,
|
initialTab: initialTab,
|
||||||
numConfirmedMembers: this.dataSource.confirmedUserCount,
|
numConfirmedMembers: this.dataSource.confirmedUserCount,
|
||||||
|
managedByOrganization: user?.managedByOrganization,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -725,6 +726,40 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteUser(user: OrganizationUserView) {
|
||||||
|
const confirmed = await this.dialogService.openSimpleDialog({
|
||||||
|
title: {
|
||||||
|
key: "deleteOrganizationUser",
|
||||||
|
placeholders: [this.userNamePipe.transform(user)],
|
||||||
|
},
|
||||||
|
content: { key: "deleteOrganizationUserWarning" },
|
||||||
|
type: "warning",
|
||||||
|
acceptButtonText: { key: "delete" },
|
||||||
|
cancelButtonText: { key: "cancel" },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!confirmed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.actionPromise = this.organizationUserApiService.deleteOrganizationUser(
|
||||||
|
this.organization.id,
|
||||||
|
user.id,
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
await this.actionPromise;
|
||||||
|
this.toastService.showToast({
|
||||||
|
variant: "success",
|
||||||
|
title: null,
|
||||||
|
message: this.i18nService.t("organizationUserDeleted", this.userNamePipe.transform(user)),
|
||||||
|
});
|
||||||
|
this.dataSource.removeUser(user);
|
||||||
|
} catch (e) {
|
||||||
|
this.validationService.showError(e);
|
||||||
|
}
|
||||||
|
this.actionPromise = null;
|
||||||
|
}
|
||||||
|
|
||||||
private async noMasterPasswordConfirmationDialog(user: OrganizationUserView) {
|
private async noMasterPasswordConfirmationDialog(user: OrganizationUserView) {
|
||||||
return this.dialogService.openSimpleDialog({
|
return this.dialogService.openSimpleDialog({
|
||||||
title: {
|
title: {
|
||||||
|
|||||||
@@ -21,7 +21,13 @@
|
|||||||
>
|
>
|
||||||
{{ "purgeVault" | i18n }}
|
{{ "purgeVault" | i18n }}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" bitButton buttonType="danger" [bitAction]="deleteAccount">
|
<button
|
||||||
|
*ngIf="showDeleteAccount$ | async"
|
||||||
|
type="button"
|
||||||
|
bitButton
|
||||||
|
buttonType="danger"
|
||||||
|
[bitAction]="deleteAccount"
|
||||||
|
>
|
||||||
{{ "deleteAccount" | i18n }}
|
{{ "deleteAccount" | i18n }}
|
||||||
</button>
|
</button>
|
||||||
</app-danger-zone>
|
</app-danger-zone>
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export class AccountComponent implements OnInit {
|
|||||||
|
|
||||||
showChangeEmail$: Observable<boolean>;
|
showChangeEmail$: Observable<boolean>;
|
||||||
showPurgeVault$: Observable<boolean>;
|
showPurgeVault$: Observable<boolean>;
|
||||||
|
showDeleteAccount$: Observable<boolean>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private modalService: ModalService,
|
private modalService: ModalService,
|
||||||
@@ -63,6 +64,16 @@ export class AccountComponent implements OnInit {
|
|||||||
!isAccountDeprovisioningEnabled || !userIsManagedByOrganization,
|
!isAccountDeprovisioningEnabled || !userIsManagedByOrganization,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.showDeleteAccount$ = combineLatest([
|
||||||
|
isAccountDeprovisioningEnabled$,
|
||||||
|
userIsManagedByOrganization$,
|
||||||
|
]).pipe(
|
||||||
|
map(
|
||||||
|
([isAccountDeprovisioningEnabled, userIsManagedByOrganization]) =>
|
||||||
|
!isAccountDeprovisioningEnabled || !userIsManagedByOrganization,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async deauthorizeSessions() {
|
async deauthorizeSessions() {
|
||||||
|
|||||||
@@ -3218,9 +3218,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"inviteSingleEmailDesc": {
|
|
||||||
"message": "You have 1 invite remaining."
|
|
||||||
},
|
|
||||||
"userUsingTwoStep": {
|
"userUsingTwoStep": {
|
||||||
"message": "This user is using two-step login to protect their account."
|
"message": "This user is using two-step login to protect their account."
|
||||||
},
|
},
|
||||||
@@ -9557,5 +9554,31 @@
|
|||||||
},
|
},
|
||||||
"single-org-revoked-user-warning": {
|
"single-org-revoked-user-warning": {
|
||||||
"message": "Non-compliant members will be revoked. Administrators can restore members once they leave all other organizations."
|
"message": "Non-compliant members will be revoked. Administrators can restore members once they leave all other organizations."
|
||||||
|
},
|
||||||
|
"deleteOrganizationUser": {
|
||||||
|
"message": "Delete $NAME$",
|
||||||
|
"placeholders": {
|
||||||
|
"name": {
|
||||||
|
"content": "$1",
|
||||||
|
"example": "John Doe"
|
||||||
|
},
|
||||||
|
"description": "Title for the delete organization user dialog"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deleteOrganizationUserWarning": {
|
||||||
|
"message": "When a member is deleted, their Bitwarden account and individual vault data will be permanently deleted. Collection data will remain in the organization. To reinstate them they must create an account and be onboarded again.",
|
||||||
|
"description": "Warning for the delete organization user dialog"
|
||||||
|
},
|
||||||
|
"organizationUserDeleted": {
|
||||||
|
"message": "Deleted $NAME$",
|
||||||
|
"placeholders": {
|
||||||
|
"name": {
|
||||||
|
"content": "$1",
|
||||||
|
"example": "John Doe"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"organizationUserDeletedDesc": {
|
||||||
|
"message": "The user was removed from the organization and all associated user data has been deleted."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import "core-js/stable";
|
import "core-js/stable";
|
||||||
require("zone.js/dist/zone");
|
import "zone.js";
|
||||||
|
|
||||||
if (process.env.NODE_ENV === "production") {
|
if (process.env.NODE_ENV === "production") {
|
||||||
// Production
|
// Production
|
||||||
} else {
|
} else {
|
||||||
// Development and test
|
// Development and test
|
||||||
Error["stackTraceLimit"] = Infinity;
|
Error["stackTraceLimit"] = Infinity;
|
||||||
require("zone.js/dist/long-stack-trace-zone");
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -275,4 +275,11 @@ export abstract class OrganizationUserApiService {
|
|||||||
organizationId: string,
|
organizationId: string,
|
||||||
ids: string[],
|
ids: string[],
|
||||||
): Promise<ListResponse<OrganizationUserBulkResponse>>;
|
): Promise<ListResponse<OrganizationUserBulkResponse>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an organization user's access to the organization and delete their account data
|
||||||
|
* @param organizationId - Identifier for the organization the user belongs to
|
||||||
|
* @param id - Organization user identifier
|
||||||
|
*/
|
||||||
|
abstract deleteOrganizationUser(organizationId: string, id: string): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -359,4 +359,14 @@ export class DefaultOrganizationUserApiService implements OrganizationUserApiSer
|
|||||||
);
|
);
|
||||||
return new ListResponse(r, OrganizationUserBulkResponse);
|
return new ListResponse(r, OrganizationUserBulkResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteOrganizationUser(organizationId: string, id: string): Promise<void> {
|
||||||
|
return this.apiService.send(
|
||||||
|
"DELETE",
|
||||||
|
"/organizations/" + organizationId + "/users/" + id + "/delete-account",
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,7 +220,8 @@ describe("DefaultActiveUserState", () => {
|
|||||||
it("should not emit a previous users value if that user is no longer active", async () => {
|
it("should not emit a previous users value if that user is no longer active", async () => {
|
||||||
const user1Data: Jsonify<TestState> = {
|
const user1Data: Jsonify<TestState> = {
|
||||||
date: "2020-09-21T13:14:17.648Z",
|
date: "2020-09-21T13:14:17.648Z",
|
||||||
array: ["value"],
|
// NOTE: `as any` is here until we migrate to Nx: https://bitwarden.atlassian.net/browse/PM-6493
|
||||||
|
array: ["value"] as any,
|
||||||
};
|
};
|
||||||
const user2Data: Jsonify<TestState> = {
|
const user2Data: Jsonify<TestState> = {
|
||||||
date: "2020-09-21T13:14:17.648Z",
|
date: "2020-09-21T13:14:17.648Z",
|
||||||
|
|||||||
@@ -192,7 +192,8 @@ describe("KeyDefinition", () => {
|
|||||||
expect(arrayDefinition).toBeTruthy();
|
expect(arrayDefinition).toBeTruthy();
|
||||||
expect(arrayDefinition.deserializer).toBeTruthy();
|
expect(arrayDefinition.deserializer).toBeTruthy();
|
||||||
|
|
||||||
const deserializedValue = arrayDefinition.deserializer([false, true]);
|
// NOTE: `as any` is here until we migrate to Nx: https://bitwarden.atlassian.net/browse/PM-6493
|
||||||
|
const deserializedValue = arrayDefinition.deserializer([false, true] as any);
|
||||||
|
|
||||||
expect(deserializedValue).toBeTruthy();
|
expect(deserializedValue).toBeTruthy();
|
||||||
expect(deserializedValue).toHaveLength(2);
|
expect(deserializedValue).toHaveLength(2);
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ describe("Login DTO", () => {
|
|||||||
password: "myPassword" as EncryptedString,
|
password: "myPassword" as EncryptedString,
|
||||||
passwordRevisionDate: passwordRevisionDate.toISOString(),
|
passwordRevisionDate: passwordRevisionDate.toISOString(),
|
||||||
totp: "myTotp" as EncryptedString,
|
totp: "myTotp" as EncryptedString,
|
||||||
|
// NOTE: `as any` is here until we migrate to Nx: https://bitwarden.atlassian.net/browse/PM-6493
|
||||||
fido2Credentials: [
|
fido2Credentials: [
|
||||||
{
|
{
|
||||||
credentialId: "keyId" as EncryptedString,
|
credentialId: "keyId" as EncryptedString,
|
||||||
@@ -167,7 +168,7 @@ describe("Login DTO", () => {
|
|||||||
discoverable: "discoverable" as EncryptedString,
|
discoverable: "discoverable" as EncryptedString,
|
||||||
creationDate: fido2CreationDate.toISOString(),
|
creationDate: fido2CreationDate.toISOString(),
|
||||||
},
|
},
|
||||||
],
|
] as any,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(actual).toEqual({
|
expect(actual).toEqual({
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ The content can be a button, anchor, or static container.
|
|||||||
<bit-item>
|
<bit-item>
|
||||||
<button bit-item-content type="button">
|
<button bit-item-content type="button">
|
||||||
<bit-avatar slot="start" text="Foo"></bit-avatar>
|
<bit-avatar slot="start" text="Foo"></bit-avatar>
|
||||||
foo@bitwarden.com
|
foo@bitwarden.com
|
||||||
<span bitBadge variant="primary" slot="default-trailing">Auto-fill</span>
|
<span bitBadge variant="primary" slot="default-trailing">Auto-fill</span>
|
||||||
<ng-container slot="secondary">
|
<ng-container slot="secondary">
|
||||||
<div>Bitwarden.com</div>
|
<div>Bitwarden.com</div>
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ export const ContentSlots: Story = {
|
|||||||
slot="start"
|
slot="start"
|
||||||
[text]="'Foo'"
|
[text]="'Foo'"
|
||||||
></bit-avatar>
|
></bit-avatar>
|
||||||
foo@bitwarden.com
|
foo@bitwarden.com
|
||||||
<ng-container slot="secondary">
|
<ng-container slot="secondary">
|
||||||
<div>Bitwarden.com</div>
|
<div>Bitwarden.com</div>
|
||||||
<div><em>locked</em></div>
|
<div><em>locked</em></div>
|
||||||
|
|||||||
11511
package-lock.json
generated
11511
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
50
package.json
50
package.json
@@ -35,19 +35,20 @@
|
|||||||
"libs/*"
|
"libs/*"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "16.2.14",
|
"@angular-devkit/build-angular": "17.3.9",
|
||||||
"@angular-eslint/eslint-plugin": "16.3.1",
|
"@angular-eslint/eslint-plugin": "17.5.3",
|
||||||
"@angular-eslint/eslint-plugin-template": "16.3.1",
|
"@angular-eslint/eslint-plugin-template": "17.5.3",
|
||||||
"@angular-eslint/template-parser": "16.3.1",
|
"@angular-eslint/schematics": "17.5.3",
|
||||||
"@angular/cli": "16.2.14",
|
"@angular-eslint/template-parser": "17.5.3",
|
||||||
"@angular/compiler-cli": "16.2.12",
|
"@angular/cli": "17.3.9",
|
||||||
"@angular/elements": "16.2.12",
|
"@angular/compiler-cli": "17.3.12",
|
||||||
|
"@angular/elements": "17.3.12",
|
||||||
"@babel/core": "7.24.9",
|
"@babel/core": "7.24.9",
|
||||||
"@babel/preset-env": "7.24.8",
|
"@babel/preset-env": "7.24.8",
|
||||||
"@compodoc/compodoc": "1.1.25",
|
"@compodoc/compodoc": "1.1.25",
|
||||||
"@electron/notarize": "2.5.0",
|
"@electron/notarize": "2.5.0",
|
||||||
"@electron/rebuild": "3.7.0",
|
"@electron/rebuild": "3.7.0",
|
||||||
"@ngtools/webpack": "16.2.14",
|
"@ngtools/webpack": "17.3.9",
|
||||||
"@storybook/addon-a11y": "8.2.9",
|
"@storybook/addon-a11y": "8.2.9",
|
||||||
"@storybook/addon-actions": "8.2.9",
|
"@storybook/addon-actions": "8.2.9",
|
||||||
"@storybook/addon-designs": "8.0.3",
|
"@storybook/addon-designs": "8.0.3",
|
||||||
@@ -58,7 +59,7 @@
|
|||||||
"@storybook/manager-api": "8.2.9",
|
"@storybook/manager-api": "8.2.9",
|
||||||
"@storybook/theming": "8.2.9",
|
"@storybook/theming": "8.2.9",
|
||||||
"@types/argon2-browser": "1.18.4",
|
"@types/argon2-browser": "1.18.4",
|
||||||
"@types/chrome": "0.0.272",
|
"@types/chrome": "0.0.280",
|
||||||
"@types/firefox-webext-browser": "120.0.4",
|
"@types/firefox-webext-browser": "120.0.4",
|
||||||
"@types/inquirer": "8.2.10",
|
"@types/inquirer": "8.2.10",
|
||||||
"@types/jest": "29.5.12",
|
"@types/jest": "29.5.12",
|
||||||
@@ -127,7 +128,6 @@
|
|||||||
"prettier": "3.3.3",
|
"prettier": "3.3.3",
|
||||||
"prettier-plugin-tailwindcss": "0.6.8",
|
"prettier-plugin-tailwindcss": "0.6.8",
|
||||||
"process": "0.11.10",
|
"process": "0.11.10",
|
||||||
"regedit": "3.0.3",
|
|
||||||
"remark-gfm": "4.0.0",
|
"remark-gfm": "4.0.0",
|
||||||
"rimraf": "6.0.1",
|
"rimraf": "6.0.1",
|
||||||
"sass": "1.74.1",
|
"sass": "1.74.1",
|
||||||
@@ -139,7 +139,7 @@
|
|||||||
"ts-loader": "9.5.1",
|
"ts-loader": "9.5.1",
|
||||||
"tsconfig-paths-webpack-plugin": "4.1.0",
|
"tsconfig-paths-webpack-plugin": "4.1.0",
|
||||||
"type-fest": "2.19.0",
|
"type-fest": "2.19.0",
|
||||||
"typescript": "5.1.6",
|
"typescript": "5.4.2",
|
||||||
"url": "0.11.4",
|
"url": "0.11.4",
|
||||||
"util": "0.12.5",
|
"util": "0.12.5",
|
||||||
"wait-on": "8.0.1",
|
"wait-on": "8.0.1",
|
||||||
@@ -149,22 +149,22 @@
|
|||||||
"webpack-node-externals": "3.0.0"
|
"webpack-node-externals": "3.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "16.2.12",
|
"@angular/animations": "17.3.12",
|
||||||
"@angular/cdk": "16.2.14",
|
"@angular/cdk": "17.3.10",
|
||||||
"@angular/common": "16.2.12",
|
"@angular/common": "17.3.12",
|
||||||
"@angular/compiler": "16.2.12",
|
"@angular/compiler": "17.3.12",
|
||||||
"@angular/core": "16.2.12",
|
"@angular/core": "17.3.12",
|
||||||
"@angular/forms": "16.2.12",
|
"@angular/forms": "17.3.12",
|
||||||
"@angular/platform-browser": "16.2.12",
|
"@angular/platform-browser": "17.3.12",
|
||||||
"@angular/platform-browser-dynamic": "16.2.12",
|
"@angular/platform-browser-dynamic": "17.3.12",
|
||||||
"@angular/router": "16.2.12",
|
"@angular/router": "17.3.12",
|
||||||
"@bitwarden/sdk-internal": "0.1.7",
|
"@bitwarden/sdk-internal": "0.1.7",
|
||||||
"@electron/fuses": "1.8.0",
|
"@electron/fuses": "1.8.0",
|
||||||
"@koa/multer": "3.0.2",
|
"@koa/multer": "3.0.2",
|
||||||
"@koa/router": "13.1.0",
|
"@koa/router": "13.1.0",
|
||||||
"@microsoft/signalr": "8.0.7",
|
"@microsoft/signalr": "8.0.7",
|
||||||
"@microsoft/signalr-protocol-msgpack": "8.0.7",
|
"@microsoft/signalr-protocol-msgpack": "8.0.7",
|
||||||
"@ng-select/ng-select": "11.2.0",
|
"@ng-select/ng-select": "12.0.7",
|
||||||
"argon2": "0.41.1",
|
"argon2": "0.41.1",
|
||||||
"argon2-browser": "1.18.0",
|
"argon2-browser": "1.18.0",
|
||||||
"big-integer": "1.6.52",
|
"big-integer": "1.6.52",
|
||||||
@@ -187,8 +187,8 @@
|
|||||||
"lowdb": "1.0.0",
|
"lowdb": "1.0.0",
|
||||||
"lunr": "2.3.9",
|
"lunr": "2.3.9",
|
||||||
"multer": "1.4.5-lts.1",
|
"multer": "1.4.5-lts.1",
|
||||||
"ngx-infinite-scroll": "16.0.0",
|
"ngx-infinite-scroll": "17.0.1",
|
||||||
"ngx-toastr": "17.0.2",
|
"ngx-toastr": "18.0.0",
|
||||||
"node-fetch": "2.6.12",
|
"node-fetch": "2.6.12",
|
||||||
"node-forge": "1.3.1",
|
"node-forge": "1.3.1",
|
||||||
"nord": "0.2.1",
|
"nord": "0.2.1",
|
||||||
@@ -202,9 +202,9 @@
|
|||||||
"qrious": "4.0.2",
|
"qrious": "4.0.2",
|
||||||
"rxjs": "7.8.1",
|
"rxjs": "7.8.1",
|
||||||
"tabbable": "6.2.0",
|
"tabbable": "6.2.0",
|
||||||
"tldts": "6.1.56",
|
"tldts": "6.1.58",
|
||||||
"utf-8-validate": "6.0.4",
|
"utf-8-validate": "6.0.4",
|
||||||
"zone.js": "0.13.3",
|
"zone.js": "0.14.10",
|
||||||
"zxcvbn": "4.4.2"
|
"zxcvbn": "4.4.2"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
|
|||||||
Reference in New Issue
Block a user