diff --git a/apps/browser/src/autofill/services/collect-autofill-content.service.ts b/apps/browser/src/autofill/services/collect-autofill-content.service.ts index 55737636de8..ea1f74eeaff 100644 --- a/apps/browser/src/autofill/services/collect-autofill-content.service.ts +++ b/apps/browser/src/autofill/services/collect-autofill-content.service.ts @@ -18,6 +18,7 @@ import { sendExtensionMessage, getAttributeBoolean, getPropertyOrAttribute, + requestIdleCallbackPolyfill, } from "../utils"; import { AutofillOverlayContentService } from "./abstractions/autofill-overlay-content.service"; @@ -1024,7 +1025,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte } if (!this.mutationsQueue.length) { - globalThis.requestIdleCallback(this.processMutations, { timeout: 500 }); + requestIdleCallbackPolyfill(this.processMutations, { timeout: 500 }); } this.mutationsQueue.push(mutations); }; @@ -1161,7 +1162,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, -1), diff --git a/apps/browser/src/autofill/utils/index.ts b/apps/browser/src/autofill/utils/index.ts index ffbcc995b2a..3785e2a3c12 100644 --- a/apps/browser/src/autofill/utils/index.ts +++ b/apps/browser/src/autofill/utils/index.ts @@ -15,6 +15,20 @@ export function generateRandomChars(length: number): string { return randomChars.join(""); } +/** + * 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) { + 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. */ diff --git a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts index 66e264dd6de..8242637d5de 100644 --- a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts +++ b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts @@ -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; } diff --git a/apps/web/package.json b/apps/web/package.json index 286811dd5c6..b56a3e03d03 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -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", diff --git a/apps/web/src/app/vault/components/vault-items/vault-collection-row.component.ts b/apps/web/src/app/vault/components/vault-items/vault-collection-row.component.ts index 8909c3e8bd9..873bdd3e1a0 100644 --- a/apps/web/src/app/vault/components/vault-items/vault-collection-row.component.ts +++ b/apps/web/src/app/vault/components/vault-items/vault-collection-row.component.ts @@ -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() ); } diff --git a/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.html b/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.html index ee45f5921e5..75ea3fd050b 100644 --- a/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.html +++ b/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.html @@ -93,7 +93,7 @@ (); @@ -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. diff --git a/package-lock.json b/package-lock.json index ab127c10058..5c5d17352cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -251,7 +251,7 @@ }, "apps/web": { "name": "@bitwarden/web-vault", - "version": "2024.6.0" + "version": "2024.6.1" }, "libs/admin-console": { "name": "@bitwarden/admin-console",