1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-13 15:03:26 +00:00

Merge branch 'main' into ps/extension-refresh

This commit is contained in:
Will Martin
2024-05-06 16:25:41 -04:00
committed by GitHub
343 changed files with 6243 additions and 3378 deletions

View File

@@ -272,6 +272,7 @@ export class BaseLoginDecryptionOptionsComponent implements OnInit, OnDestroy {
// this.loading to support clients without async-actions-support
this.loading = true;
// errors must be caught in child components to prevent navigation
try {
const { publicKey, privateKey } = await this.cryptoService.initAccount();
const keysRequest = new KeysRequest(publicKey, privateKey.encryptedString);
@@ -288,8 +289,6 @@ export class BaseLoginDecryptionOptionsComponent implements OnInit, OnDestroy {
if (this.rememberDeviceForm.value.rememberDevice) {
await this.deviceTrustService.trustDevice(this.activeAccountId);
}
} catch (error) {
this.validationService.showError(error);
} finally {
this.loading = false;
}

View File

@@ -244,7 +244,7 @@ export class SetPasswordComponent extends BaseChangePasswordComponent {
await this.userDecryptionOptionsService.setUserDecryptionOptions(userDecryptionOpts);
await this.kdfConfigService.setKdfConfig(this.userId, this.kdfConfig);
await this.masterPasswordService.setMasterKey(masterKey, this.userId);
await this.cryptoService.setUserKey(userKey[0]);
await this.cryptoService.setUserKey(userKey[0], this.userId);
// Set private key only for new JIT provisioned users in MP encryption orgs
// Existing TDE users will have private key set on sync or on login
@@ -253,7 +253,7 @@ export class SetPasswordComponent extends BaseChangePasswordComponent {
this.forceSetPasswordReason !=
ForceSetPasswordReason.TdeUserWithoutPasswordHasPasswordResetPermission
) {
await this.cryptoService.setPrivateKey(keyPair[1].encryptedString);
await this.cryptoService.setPrivateKey(keyPair[1].encryptedString, this.userId);
}
const localMasterKeyHash = await this.cryptoService.hashMasterKey(

View File

@@ -14,7 +14,7 @@ export class LoggingErrorHandler extends ErrorHandler {
override handleError(error: any): void {
try {
const logService = this.injector.get(LogService, null);
logService.error(error);
logService.error("Unhandled error in angular", error);
} catch {
super.handleError(error);
}

View File

@@ -656,7 +656,6 @@ const safeProviders: SafeProvider[] = [
CipherServiceAbstraction,
FolderServiceAbstraction,
CollectionServiceAbstraction,
CryptoServiceAbstraction,
PlatformUtilsServiceAbstraction,
MessagingServiceAbstraction,
SearchServiceAbstraction,
@@ -968,6 +967,7 @@ const safeProviders: SafeProvider[] = [
StateProvider,
SECURE_STORAGE,
UserDecryptionOptionsServiceAbstraction,
LogService,
],
}),
safeProvider({

View File

@@ -0,0 +1,55 @@
import { Type } from "@angular/core";
import { Route, Routes } from "@angular/router";
/**
* Helper function to swap between two components based on an async condition. The async condition is evaluated
* as an `CanMatchFn` and supports Angular dependency injection via `inject()`.
*
* @example
* ```ts
* const routes = [
* ...componentRouteSwap(
* defaultComponent,
* altComponent,
* async () => {
* const configService = inject(ConfigService);
* return configService.getFeatureFlag(FeatureFlag.SomeFlag);
* },
* {
* path: 'some-path'
* }
* ),
* // Other routes...
* ];
* ```
*
* @param defaultComponent - The default component to render.
* @param altComponent - The alternate component to render when the condition is met.
* @param shouldSwapFn - The async function to determine if the alternate component should be rendered.
* @param options - The shared route options to apply to both components.
*/
export function componentRouteSwap(
defaultComponent: Type<any>,
altComponent: Type<any>,
shouldSwapFn: () => Promise<boolean>,
options: Route,
): Routes {
const defaultRoute = {
...options,
component: defaultComponent,
};
const altRoute: Route = {
...options,
component: altComponent,
canMatch: [
async () => {
return await shouldSwapFn();
},
...(options.canMatch ?? []),
],
};
// Return the alternate route first, so it is evaluated first.
return [altRoute, defaultRoute];
}

View File

@@ -289,6 +289,16 @@ export class AddEditComponent implements OnInit, OnDestroy {
});
}
}
// Only Admins can clone a cipher to different owner
if (this.cloneMode && this.cipher.organizationId != null) {
const cipherOrg = (await firstValueFrom(this.organizationService.memberOrganizations$)).find(
(o) => o.id === this.cipher.organizationId,
);
if (cipherOrg != null && !cipherOrg.isAdmin && !cipherOrg.permissions.editAnyCollection) {
this.ownershipOptions = [{ name: cipherOrg.name, value: cipherOrg.id }];
}
}
// We don't want to copy passkeys when we clone a cipher
if (this.cloneMode && this.cipher?.login?.hasFido2Credentials) {