1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-17 08:43:33 +00:00

merge main, fix conflicts

This commit is contained in:
rr-bw
2024-09-05 16:53:32 -07:00
300 changed files with 5977 additions and 2162 deletions

View File

@@ -17,6 +17,7 @@ import {
take,
} from "rxjs";
import { OrganizationUserApiService } from "@bitwarden/admin-console/common";
import {
LoginEmailServiceAbstraction,
UserDecryptionOptions,
@@ -24,7 +25,6 @@ import {
} from "@bitwarden/auth/common";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction";
import { OrganizationUserService } from "@bitwarden/common/admin-console/abstractions/organization-user/organization-user.service";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { DevicesServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices/devices.service.abstraction";
@@ -95,7 +95,7 @@ export class BaseLoginDecryptionOptionsComponent implements OnInit, OnDestroy {
protected loginEmailService: LoginEmailServiceAbstraction,
protected organizationApiService: OrganizationApiServiceAbstraction,
protected cryptoService: CryptoService,
protected organizationUserService: OrganizationUserService,
protected organizationUserApiService: OrganizationUserApiService,
protected apiService: ApiService,
protected i18nService: I18nService,
protected validationService: ValidationService,
@@ -251,12 +251,12 @@ export class BaseLoginDecryptionOptionsComponent implements OnInit, OnDestroy {
return;
}
this.loginEmailService.setEmail(this.data.userEmail);
this.loginEmailService.setLoginEmail(this.data.userEmail);
await this.router.navigate(["/login-with-device"]);
}
async requestAdminApproval() {
this.loginEmailService.setEmail(this.data.userEmail);
this.loginEmailService.setLoginEmail(this.data.userEmail);
await this.router.navigate(["/admin-approval-requested"]);
}

View File

@@ -1,5 +1,6 @@
import { Directive, OnInit } from "@angular/core";
import { Router } from "@angular/router";
import { firstValueFrom } from "rxjs";
import { LoginEmailServiceAbstraction } from "@bitwarden/auth/common";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
@@ -27,8 +28,8 @@ export class HintComponent implements OnInit {
protected toastService: ToastService,
) {}
ngOnInit(): void {
this.email = this.loginEmailService.getEmail() ?? "";
async ngOnInit(): Promise<void> {
this.email = (await firstValueFrom(this.loginEmailService.loginEmail$)) ?? "";
}
async submit() {

View File

@@ -93,13 +93,6 @@ export class LoginViaAuthRequestComponent
) {
super(environmentService, i18nService, platformUtilsService, toastService);
// TODO: I don't know why this is necessary.
// Why would the existence of the email depend on the navigation?
const navigation = this.router.getCurrentNavigation();
if (navigation) {
this.email = this.loginEmailService.getEmail();
}
// Gets signalR push notification
// Only fires on approval to prevent enumeration
this.authRequestService.authRequestPushNotification$
@@ -118,6 +111,7 @@ export class LoginViaAuthRequestComponent
}
async ngOnInit() {
this.email = await firstValueFrom(this.loginEmailService.loginEmail$);
this.userAuthNStatus = await this.authService.getAuthStatus();
const matchOptions: IsActiveMatchOptions = {
@@ -165,7 +159,7 @@ export class LoginViaAuthRequestComponent
} else {
// Standard auth request
// TODO: evaluate if we can remove the setting of this.email in the constructor
this.email = this.loginEmailService.getEmail();
this.email = await firstValueFrom(this.loginEmailService.loginEmail$);
if (!this.email) {
this.toastService.showToast({
@@ -216,9 +210,10 @@ export class LoginViaAuthRequestComponent
const derivedPublicKeyArrayBuffer = await this.cryptoFunctionService.rsaExtractPublicKey(
adminAuthReqStorable.privateKey,
);
this.fingerprintPhrase = (
await this.cryptoService.getFingerprint(this.email, derivedPublicKeyArrayBuffer)
).join("-");
this.fingerprintPhrase = await this.authRequestService.getFingerprintPhrase(
this.email,
derivedPublicKeyArrayBuffer,
);
// Request denied
if (adminAuthReqResponse.isAnswered && !adminAuthReqResponse.requestApproved) {
@@ -265,9 +260,10 @@ export class LoginViaAuthRequestComponent
length: 25,
});
this.fingerprintPhrase = (
await this.cryptoService.getFingerprint(this.email, this.authRequestKeyPair.publicKey)
).join("-");
this.fingerprintPhrase = await this.authRequestService.getFingerprintPhrase(
this.email,
this.authRequestKeyPair.publicKey,
);
this.authRequest = new CreateAuthRequest(
this.email,

View File

@@ -1,8 +1,8 @@
import { Directive, ElementRef, NgZone, OnDestroy, OnInit, ViewChild } from "@angular/core";
import { FormBuilder, Validators } from "@angular/forms";
import { ActivatedRoute, Router } from "@angular/router";
import { Subject, firstValueFrom } from "rxjs";
import { take, takeUntil } from "rxjs/operators";
import { Subject, firstValueFrom, of } from "rxjs";
import { switchMap, take, takeUntil } from "rxjs/operators";
import {
LoginStrategyServiceAbstraction,
@@ -101,22 +101,31 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit,
}
async ngOnInit() {
this.route?.queryParams.pipe(takeUntil(this.destroy$)).subscribe((params) => {
if (!params) {
return;
}
this.route?.queryParams
.pipe(
switchMap((params) => {
if (!params) {
// If no params,loadEmailSettings from state
return this.loadEmailSettings();
}
const queryParamsEmail = params.email;
const queryParamsEmail = params.email;
// If there is an email in the query params, set that email as the form field value
if (queryParamsEmail != null && queryParamsEmail.indexOf("@") > -1) {
this.formGroup.controls.email.setValue(queryParamsEmail);
this.paramEmailSet = true;
}
});
if (queryParamsEmail != null && queryParamsEmail.indexOf("@") > -1) {
this.formGroup.controls.email.setValue(queryParamsEmail);
this.paramEmailSet = true;
}
// if there is no email in the query params, attempt to load email settings from loginEmailService
if (!this.paramEmailSet) {
// If paramEmailSet is false, loadEmailSettings from state
return this.paramEmailSet ? of(null) : this.loadEmailSettings();
}),
takeUntil(this.destroy$),
)
.subscribe();
// Backup check to handle unknown case where activatedRoute is not available
// This shouldn't happen under normal circumstances
if (!this.route) {
await this.loadEmailSettings();
}
}
@@ -310,7 +319,7 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit,
private async loadEmailSettings() {
// Try to load from memory first
const email = this.loginEmailService.getEmail();
const email = await firstValueFrom(this.loginEmailService.loginEmail$);
const rememberEmail = this.loginEmailService.getRememberEmail();
if (email) {
@@ -328,7 +337,7 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit,
}
protected async saveEmailSettings() {
this.loginEmailService.setEmail(this.formGroup.value.email);
this.loginEmailService.setLoginEmail(this.formGroup.value.email);
this.loginEmailService.setRememberEmail(this.formGroup.value.rememberEmail);
await this.loginEmailService.saveEmailSettings();
}

View File

@@ -3,11 +3,13 @@ import { ActivatedRoute, Router } from "@angular/router";
import { firstValueFrom, of } from "rxjs";
import { filter, first, switchMap, tap } from "rxjs/operators";
import {
OrganizationUserApiService,
OrganizationUserResetPasswordEnrollmentRequest,
} from "@bitwarden/admin-console/common";
import { InternalUserDecryptionOptionsServiceAbstraction } from "@bitwarden/auth/common";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction";
import { OrganizationUserService } from "@bitwarden/common/admin-console/abstractions/organization-user/organization-user.service";
import { OrganizationUserResetPasswordEnrollmentRequest } from "@bitwarden/common/admin-console/abstractions/organization-user/requests";
import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction";
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
@@ -68,7 +70,7 @@ export class SetPasswordComponent extends BaseChangePasswordComponent implements
private route: ActivatedRoute,
stateService: StateService,
private organizationApiService: OrganizationApiServiceAbstraction,
private organizationUserService: OrganizationUserService,
private organizationUserApiService: OrganizationUserApiService,
private userDecryptionOptionsService: InternalUserDecryptionOptionsServiceAbstraction,
private ssoLoginService: SsoLoginServiceAbstraction,
dialogService: DialogService,
@@ -219,7 +221,7 @@ export class SetPasswordComponent extends BaseChangePasswordComponent implements
resetRequest.masterPasswordHash = masterPasswordHash;
resetRequest.resetPasswordKey = encryptedUserKey.encryptedString;
return this.organizationUserService.putOrganizationUserResetPasswordEnrollment(
return this.organizationUserApiService.putOrganizationUserResetPasswordEnrollment(
this.orgId,
this.userId,
resetRequest,

View File

@@ -1,6 +1,10 @@
import { ErrorHandler, LOCALE_ID, NgModule } from "@angular/core";
import { Subject } from "rxjs";
import {
OrganizationUserApiService,
DefaultOrganizationUserApiService,
} from "@bitwarden/admin-console/common";
import {
SetPasswordJitService,
DefaultSetPasswordJitService,
@@ -45,7 +49,6 @@ import {
OrgDomainServiceAbstraction,
} from "@bitwarden/common/admin-console/abstractions/organization-domain/org-domain.service.abstraction";
import { OrganizationManagementPreferencesService } from "@bitwarden/common/admin-console/abstractions/organization-management-preferences/organization-management-preferences.service";
import { OrganizationUserService } from "@bitwarden/common/admin-console/abstractions/organization-user/organization-user.service";
import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction";
import {
InternalPolicyService,
@@ -58,7 +61,6 @@ import { OrganizationService } from "@bitwarden/common/admin-console/services/or
import { OrgDomainApiService } from "@bitwarden/common/admin-console/services/organization-domain/org-domain-api.service";
import { OrgDomainService } from "@bitwarden/common/admin-console/services/organization-domain/org-domain.service";
import { DefaultOrganizationManagementPreferencesService } from "@bitwarden/common/admin-console/services/organization-management-preferences/default-organization-management-preferences.service";
import { OrganizationUserServiceImplementation } from "@bitwarden/common/admin-console/services/organization-user/organization-user.service.implementation";
import { PolicyApiService } from "@bitwarden/common/admin-console/services/policy/policy-api.service";
import { PolicyService } from "@bitwarden/common/admin-console/services/policy/policy.service";
import { ProviderApiService } from "@bitwarden/common/admin-console/services/provider/provider-api.service";
@@ -370,7 +372,7 @@ const safeProviders: SafeProvider[] = [
safeProvider({
provide: AppIdServiceAbstraction,
useClass: AppIdService,
deps: [GlobalStateProvider],
deps: [OBSERVABLE_DISK_STORAGE, LogService],
}),
safeProvider({
provide: AuditServiceAbstraction,
@@ -936,8 +938,8 @@ const safeProviders: SafeProvider[] = [
useExisting: InternalOrganizationServiceAbstraction,
}),
safeProvider({
provide: OrganizationUserService,
useClass: OrganizationUserServiceImplementation,
provide: OrganizationUserApiService,
useClass: DefaultOrganizationUserApiService,
deps: [ApiServiceAbstraction],
}),
safeProvider({
@@ -947,7 +949,7 @@ const safeProviders: SafeProvider[] = [
OrganizationApiServiceAbstraction,
AccountServiceAbstraction,
CryptoServiceAbstraction,
OrganizationUserService,
OrganizationUserApiService,
I18nServiceAbstraction,
],
}),
@@ -1275,7 +1277,7 @@ const safeProviders: SafeProvider[] = [
KdfConfigServiceAbstraction,
InternalMasterPasswordServiceAbstraction,
OrganizationApiServiceAbstraction,
OrganizationUserService,
OrganizationUserApiService,
InternalUserDecryptionOptionsServiceAbstraction,
],
}),

View File

@@ -37,6 +37,7 @@ import { IdentityView } from "@bitwarden/common/vault/models/view/identity.view"
import { LoginUriView } from "@bitwarden/common/vault/models/view/login-uri.view";
import { LoginView } from "@bitwarden/common/vault/models/view/login.view";
import { SecureNoteView } from "@bitwarden/common/vault/models/view/secure-note.view";
import { normalizeExpiryYearFormat } from "@bitwarden/common/vault/utils";
import { DialogService } from "@bitwarden/components";
import { PasswordRepromptService } from "@bitwarden/vault";
@@ -330,6 +331,11 @@ export class AddEditComponent implements OnInit, OnDestroy {
return this.restore();
}
// normalize card expiry year on save
if (this.cipher.type === this.cipherType.Card) {
this.cipher.card.expYear = normalizeExpiryYearFormat(this.cipher.card.expYear);
}
if (this.cipher.name == null || this.cipher.name === "") {
this.platformUtilsService.showToast(
"error",