mirror of
https://github.com/bitwarden/browser
synced 2025-12-13 06:43:35 +00:00
Merge branch 'autofill/pm-8869-regression-autofill-broken-safari' into autofill/pm-8027-inline-menu-appears-within-input-fields-that-do-not-relate-to-user-login
This commit is contained in:
@@ -21,6 +21,7 @@ import {
|
||||
nodeIsFormElement,
|
||||
nodeIsInputElement,
|
||||
sendExtensionMessage,
|
||||
requestIdleCallbackPolyfill,
|
||||
} from "../utils";
|
||||
|
||||
import { AutofillOverlayContentService } from "./abstractions/autofill-overlay-content.service";
|
||||
@@ -1055,7 +1056,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
}
|
||||
|
||||
if (!this.mutationsQueue.length) {
|
||||
globalThis.requestIdleCallback(this.processMutations, { timeout: 500 });
|
||||
requestIdleCallbackPolyfill(this.processMutations, { timeout: 500 });
|
||||
}
|
||||
this.mutationsQueue.push(mutations);
|
||||
};
|
||||
@@ -1192,7 +1193,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
continue;
|
||||
}
|
||||
|
||||
globalThis.requestIdleCallback(
|
||||
requestIdleCallbackPolyfill(
|
||||
// We are setting this item to a -1 index because we do not know its position in the DOM.
|
||||
// This value should be updated with the next call to collect page details.
|
||||
() => void this.buildAutofillFieldItem(node as ElementWithOpId<FormFieldElement>, -1),
|
||||
|
||||
@@ -1,6 +1,20 @@
|
||||
import { AutofillPort } from "../enums/autofill-port.enums";
|
||||
import { FillableFormFieldElement, FormFieldElement } from "../types";
|
||||
|
||||
/**
|
||||
* Polyfills the requestIdleCallback API with a setTimeout fallback.
|
||||
*
|
||||
* @param callback - The callback function to run when the browser is idle.
|
||||
* @param options - The options to pass to the requestIdleCallback function.
|
||||
*/
|
||||
export function requestIdleCallbackPolyfill(callback: () => void, options?: Record<string, any>) {
|
||||
if ("requestIdleCallback" in globalThis) {
|
||||
return globalThis.requestIdleCallback(() => callback(), options);
|
||||
}
|
||||
|
||||
return globalThis.setTimeout(() => callback(), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random string of characters that formatted as a custom element name.
|
||||
*/
|
||||
|
||||
@@ -938,7 +938,6 @@ export default class MainBackground {
|
||||
logoutCallback,
|
||||
this.stateService,
|
||||
this.authService,
|
||||
this.authRequestService,
|
||||
this.messagingService,
|
||||
);
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@ import { Injectable } from "@angular/core";
|
||||
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||
import { FormBuilder } from "@angular/forms";
|
||||
import {
|
||||
Observable,
|
||||
combineLatest,
|
||||
distinctUntilChanged,
|
||||
map,
|
||||
Observable,
|
||||
startWith,
|
||||
switchMap,
|
||||
tap,
|
||||
@@ -104,6 +104,11 @@ export class VaultPopupListFiltersService {
|
||||
map(
|
||||
(filters) => (ciphers: CipherView[]) =>
|
||||
ciphers.filter((cipher) => {
|
||||
// Vault popup lists never shows deleted ciphers
|
||||
if (cipher.isDeleted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (filters.cipherType !== null && cipher.type !== filters.cipherType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -166,20 +166,6 @@
|
||||
"recommendedForSecurity" | i18n
|
||||
}}</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<label for="approveLoginRequests">
|
||||
<input
|
||||
id="approveLoginRequests"
|
||||
type="checkbox"
|
||||
formControlName="approveLoginRequests"
|
||||
(change)="updateApproveLoginRequests()"
|
||||
/>
|
||||
{{ "approveLoginRequests" | i18n }}
|
||||
</label>
|
||||
</div>
|
||||
<small class="help-block">{{ "approveLoginRequestDesc" | i18n }}</small>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { FormBuilder } from "@angular/forms";
|
||||
import { BehaviorSubject, Observable, Subject, firstValueFrom } from "rxjs";
|
||||
import { concatMap, debounceTime, filter, map, switchMap, takeUntil, tap } from "rxjs/operators";
|
||||
|
||||
import { AuthRequestServiceAbstraction, PinServiceAbstraction } from "@bitwarden/auth/common";
|
||||
import { PinServiceAbstraction } from "@bitwarden/auth/common";
|
||||
import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout-settings.service";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
@@ -90,7 +90,6 @@ export class SettingsComponent implements OnInit {
|
||||
biometric: false,
|
||||
autoPromptBiometrics: false,
|
||||
requirePasswordOnStart: false,
|
||||
approveLoginRequests: false,
|
||||
// Account Preferences
|
||||
clearClipboard: [null],
|
||||
minimizeOnCopyToClipboard: false,
|
||||
@@ -135,7 +134,6 @@ export class SettingsComponent implements OnInit {
|
||||
private biometricStateService: BiometricStateService,
|
||||
private desktopAutofillSettingsService: DesktopAutofillSettingsService,
|
||||
private pinService: PinServiceAbstraction,
|
||||
private authRequestService: AuthRequestServiceAbstraction,
|
||||
private logService: LogService,
|
||||
private nativeMessagingManifestService: NativeMessagingManifestService,
|
||||
) {
|
||||
@@ -275,8 +273,6 @@ export class SettingsComponent implements OnInit {
|
||||
requirePasswordOnStart: await firstValueFrom(
|
||||
this.biometricStateService.requirePasswordOnStart$,
|
||||
),
|
||||
approveLoginRequests:
|
||||
(await this.authRequestService.getAcceptAuthRequests(this.currentUserId)) ?? false,
|
||||
clearClipboard: await firstValueFrom(this.autofillSettingsService.clearClipboardDelay$),
|
||||
minimizeOnCopyToClipboard: await firstValueFrom(this.desktopSettingsService.minimizeOnCopy$),
|
||||
enableFavicons: await firstValueFrom(this.domainSettingsService.showFavicons$),
|
||||
@@ -722,13 +718,6 @@ export class SettingsComponent implements OnInit {
|
||||
);
|
||||
}
|
||||
|
||||
async updateApproveLoginRequests() {
|
||||
await this.authRequestService.setAcceptAuthRequests(
|
||||
this.form.value.approveLoginRequests,
|
||||
this.currentUserId,
|
||||
);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
|
||||
@@ -2401,9 +2401,6 @@
|
||||
"denyLogIn": {
|
||||
"message": "Deny login"
|
||||
},
|
||||
"approveLoginRequests": {
|
||||
"message": "Approve login requests"
|
||||
},
|
||||
"logInConfirmedForEmailOnDevice": {
|
||||
"message": "Login confirmed for $EMAIL$ on $DEVICE$",
|
||||
"placeholders": {
|
||||
@@ -2438,9 +2435,6 @@
|
||||
"thisRequestIsNoLongerValid": {
|
||||
"message": "This request is no longer valid."
|
||||
},
|
||||
"approveLoginRequestDesc": {
|
||||
"message": "Use this device to approve login requests made from other devices."
|
||||
},
|
||||
"confirmLoginAtemptForMail": {
|
||||
"message": "Confirm login attempt for $EMAIL$",
|
||||
"placeholders": {
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
ViewContainerRef,
|
||||
} from "@angular/core";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
import { firstValueFrom, Subject, takeUntil } from "rxjs";
|
||||
import { Subject, takeUntil } from "rxjs";
|
||||
import { first } from "rxjs/operators";
|
||||
|
||||
import { ModalRef } from "@bitwarden/angular/components/modal/modal.ref";
|
||||
@@ -16,7 +16,6 @@ import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||
import { VaultFilter } from "@bitwarden/angular/vault/vault-filter/models/vault-filter.model";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||
import { EventType } from "@bitwarden/common/enums";
|
||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||
@@ -32,7 +31,6 @@ import { FolderView } from "@bitwarden/common/vault/models/view/folder.view";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
import { PasswordRepromptService } from "@bitwarden/vault";
|
||||
|
||||
import { AuthRequestServiceAbstraction } from "../../../../../../libs/auth/src/common/abstractions";
|
||||
import { SearchBarService } from "../../../app/layout/search/search-bar.service";
|
||||
import { GeneratorComponent } from "../../../app/tools/generator.component";
|
||||
import { invokeMenu, RendererMenuItem } from "../../../utils";
|
||||
@@ -107,8 +105,6 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
private apiService: ApiService,
|
||||
private dialogService: DialogService,
|
||||
private billingAccountProfileStateService: BillingAccountProfileStateService,
|
||||
private authRequestService: AuthRequestServiceAbstraction,
|
||||
private accountService: AccountService,
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
@@ -226,15 +222,11 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
this.searchBarService.setEnabled(true);
|
||||
this.searchBarService.setPlaceholderText(this.i18nService.t("searchVault"));
|
||||
|
||||
const userId = (await firstValueFrom(this.accountService.activeAccount$)).id;
|
||||
const approveLoginRequests = await this.authRequestService.getAcceptAuthRequests(userId);
|
||||
if (approveLoginRequests) {
|
||||
const authRequest = await this.apiService.getLastAuthRequest();
|
||||
if (authRequest != null) {
|
||||
this.messagingService.send("openLoginApproval", {
|
||||
notificationId: authRequest.id,
|
||||
});
|
||||
}
|
||||
const authRequest = await this.apiService.getLastAuthRequest();
|
||||
if (authRequest != null) {
|
||||
this.messagingService.send("openLoginApproval", {
|
||||
notificationId: authRequest.id,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@bitwarden/web-vault",
|
||||
"version": "2024.6.0",
|
||||
"version": "2024.6.1",
|
||||
"scripts": {
|
||||
"build:oss": "webpack",
|
||||
"build:bit": "webpack -c ../../bitwarden_license/bit-web/webpack.config.js",
|
||||
|
||||
@@ -69,9 +69,9 @@ export class VaultCollectionRowComponent {
|
||||
if (this.collection instanceof CollectionAdminView) {
|
||||
// Only show AddAccess if unmanaged and allowAdminAccessToAllCollectionItems is disabled
|
||||
return (
|
||||
!this.organization.allowAdminAccessToAllCollectionItems &&
|
||||
!this.organization?.allowAdminAccessToAllCollectionItems &&
|
||||
this.collection.unmanaged &&
|
||||
this.organization.canEditUnmanagedCollections()
|
||||
this.organization?.canEditUnmanagedCollections()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
</ng-container>
|
||||
|
||||
<bit-search
|
||||
*ngIf="organization?.isProviderUser"
|
||||
*ngIf="restrictProviderAccessFlag && organization?.isProviderUser && !organization?.isMember"
|
||||
class="tw-grow"
|
||||
[ngModel]="searchText"
|
||||
(ngModelChange)="onSearchTextChanged($event)"
|
||||
|
||||
@@ -68,7 +68,7 @@ export class VaultHeaderComponent implements OnInit {
|
||||
protected organizations$ = this.organizationService.organizations$;
|
||||
|
||||
protected flexibleCollectionsV1Enabled = false;
|
||||
private restrictProviderAccessFlag = false;
|
||||
protected restrictProviderAccessFlag = false;
|
||||
|
||||
constructor(
|
||||
private organizationService: OrganizationService,
|
||||
@@ -220,7 +220,11 @@ export class VaultHeaderComponent implements OnInit {
|
||||
}
|
||||
|
||||
get canCreateCipher(): boolean {
|
||||
if (this.organization?.isProviderUser && this.restrictProviderAccessFlag) {
|
||||
if (
|
||||
this.organization?.isProviderUser &&
|
||||
this.restrictProviderAccessFlag &&
|
||||
!this.organization?.isMember
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -166,7 +166,11 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
protected get hideVaultFilters(): boolean {
|
||||
return this.restrictProviderAccessEnabled && this.organization?.isProviderUser;
|
||||
return (
|
||||
this.restrictProviderAccessEnabled &&
|
||||
this.organization?.isProviderUser &&
|
||||
!this.organization?.isMember
|
||||
);
|
||||
}
|
||||
|
||||
private searchText$ = new Subject<string>();
|
||||
@@ -352,6 +356,16 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
let ciphers;
|
||||
|
||||
// Restricted providers (who are not members) do not have access org cipher endpoint below
|
||||
// Return early to avoid 404 response
|
||||
if (
|
||||
this.restrictProviderAccessEnabled &&
|
||||
!organization.isMember &&
|
||||
organization.isProviderUser
|
||||
) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (this.flexibleCollectionsV1Enabled) {
|
||||
// Flexible collections V1 logic.
|
||||
// If the user can edit all ciphers for the organization then fetch them ALL.
|
||||
|
||||
Reference in New Issue
Block a user