handle content script host permission errors
This commit is contained in:
parent
d7f491d920
commit
4d1c54e9c2
|
@ -12,6 +12,7 @@ import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abs
|
|||
import { EventType } from "@bitwarden/common/enums";
|
||||
import { UriMatchStrategy } from "@bitwarden/common/models/domain/domain-service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { EventCollectionService } from "@bitwarden/common/services/event/event-collection.service";
|
||||
import {
|
||||
|
@ -74,9 +75,10 @@ describe("AutofillService", () => {
|
|||
const logService = mock<LogService>();
|
||||
const userVerificationService = mock<UserVerificationService>();
|
||||
const billingAccountProfileStateService = mock<BillingAccountProfileStateService>();
|
||||
const platformUtilsService = mock<PlatformUtilsService>();
|
||||
|
||||
beforeEach(() => {
|
||||
scriptInjectorService = new BrowserScriptInjectorService();
|
||||
scriptInjectorService = new BrowserScriptInjectorService(platformUtilsService, logService);
|
||||
autofillService = new AutofillService(
|
||||
cipherService,
|
||||
autofillSettingsService,
|
||||
|
|
|
@ -806,7 +806,10 @@ export default class MainBackground {
|
|||
);
|
||||
this.totpService = new TotpService(this.cryptoFunctionService, this.logService);
|
||||
|
||||
this.scriptInjectorService = new BrowserScriptInjectorService();
|
||||
this.scriptInjectorService = new BrowserScriptInjectorService(
|
||||
this.platformUtilsService,
|
||||
this.logService,
|
||||
);
|
||||
this.autofillService = new AutofillService(
|
||||
this.cipherService,
|
||||
this.autofillSettingsService,
|
||||
|
|
|
@ -51,7 +51,6 @@
|
|||
"default_popup": "popup/index.html"
|
||||
},
|
||||
"permissions": [
|
||||
"<all_urls>",
|
||||
"tabs",
|
||||
"contextMenus",
|
||||
"storage",
|
||||
|
@ -63,7 +62,7 @@
|
|||
"offscreen"
|
||||
],
|
||||
"optional_permissions": ["nativeMessaging", "privacy"],
|
||||
"host_permissions": ["<all_urls>"],
|
||||
"host_permissions": ["https://*/*", "http://*/*"],
|
||||
"content_security_policy": {
|
||||
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self'",
|
||||
"sandbox": "sandbox allow-scripts; script-src 'self'"
|
||||
|
|
|
@ -1,10 +1,20 @@
|
|||
import {
|
||||
LogServiceInitOptions,
|
||||
logServiceFactory,
|
||||
} from "../../background/service-factories/log-service.factory";
|
||||
import { BrowserScriptInjectorService } from "../../services/browser-script-injector.service";
|
||||
|
||||
import { CachedServices, FactoryOptions, factory } from "./factory-options";
|
||||
import {
|
||||
PlatformUtilsServiceInitOptions,
|
||||
platformUtilsServiceFactory,
|
||||
} from "./platform-utils-service.factory";
|
||||
|
||||
type BrowserScriptInjectorServiceOptions = FactoryOptions;
|
||||
|
||||
export type BrowserScriptInjectorServiceInitOptions = BrowserScriptInjectorServiceOptions;
|
||||
export type BrowserScriptInjectorServiceInitOptions = BrowserScriptInjectorServiceOptions &
|
||||
PlatformUtilsServiceInitOptions &
|
||||
LogServiceInitOptions;
|
||||
|
||||
export function browserScriptInjectorServiceFactory(
|
||||
cache: { browserScriptInjectorService?: BrowserScriptInjectorService } & CachedServices,
|
||||
|
@ -14,6 +24,10 @@ export function browserScriptInjectorServiceFactory(
|
|||
cache,
|
||||
"browserScriptInjectorService",
|
||||
opts,
|
||||
async () => new BrowserScriptInjectorService(),
|
||||
async () =>
|
||||
new BrowserScriptInjectorService(
|
||||
await platformUtilsServiceFactory(cache, opts),
|
||||
await logServiceFactory(cache, opts),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
import { mock } from "jest-mock-extended";
|
||||
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
|
||||
import { BrowserApi } from "../browser/browser-api";
|
||||
|
||||
import {
|
||||
|
@ -20,9 +25,11 @@ describe("ScriptInjectorService", () => {
|
|||
let scriptInjectorService: BrowserScriptInjectorService;
|
||||
jest.spyOn(BrowserApi, "executeScriptInTab").mockImplementation();
|
||||
jest.spyOn(BrowserApi, "isManifestVersion");
|
||||
const platformUtilsService = mock<PlatformUtilsService>();
|
||||
const logService = mock<LogService>();
|
||||
|
||||
beforeEach(() => {
|
||||
scriptInjectorService = new BrowserScriptInjectorService();
|
||||
scriptInjectorService = new BrowserScriptInjectorService(platformUtilsService, logService);
|
||||
});
|
||||
|
||||
describe("inject", () => {
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
|
||||
import { BrowserApi } from "../browser/browser-api";
|
||||
|
||||
import {
|
||||
|
@ -7,6 +10,13 @@ import {
|
|||
} from "./abstractions/script-injector.service";
|
||||
|
||||
export class BrowserScriptInjectorService extends ScriptInjectorService {
|
||||
constructor(
|
||||
private readonly platformUtilsService: PlatformUtilsService,
|
||||
private readonly logService: LogService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Facilitates the injection of a script into a tab context. Will adjust
|
||||
* behavior between manifest v2 and v3 based on the passed configuration.
|
||||
|
@ -23,9 +33,24 @@ export class BrowserScriptInjectorService extends ScriptInjectorService {
|
|||
const injectionDetails = this.buildInjectionDetails(injectDetails, file);
|
||||
|
||||
if (BrowserApi.isManifestVersion(3)) {
|
||||
await BrowserApi.executeScriptInTab(tabId, injectionDetails, {
|
||||
world: mv3Details?.world ?? "ISOLATED",
|
||||
});
|
||||
try {
|
||||
await BrowserApi.executeScriptInTab(tabId, injectionDetails, {
|
||||
world: mv3Details?.world ?? "ISOLATED",
|
||||
});
|
||||
} catch ({ message }) {
|
||||
// Swallow errors for host permissions, since this is believed to be a Manifest V3 Chrome bug
|
||||
// @TODO remove when the bugged behaviour is resolved
|
||||
if (
|
||||
message ===
|
||||
"Cannot access contents of the page. Extension manifest must request permission to access the respective host."
|
||||
) {
|
||||
if (this.platformUtilsService.isDev()) {
|
||||
this.logService.warning(
|
||||
`BrowserApi.executeScriptInTab exception for ${injectDetails.file} in tab ${tabId}: ${message}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -310,7 +310,7 @@ const safeProviders: SafeProvider[] = [
|
|||
safeProvider({
|
||||
provide: ScriptInjectorService,
|
||||
useClass: BrowserScriptInjectorService,
|
||||
deps: [],
|
||||
deps: [PlatformUtilsService, LogService],
|
||||
}),
|
||||
safeProvider({
|
||||
provide: KeyConnectorService,
|
||||
|
|
|
@ -5,6 +5,8 @@ import { PolicyService } from "@bitwarden/common/admin-console/services/policy/p
|
|||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||
import { AuthService } from "@bitwarden/common/auth/services/auth.service";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
||||
import { Importer, ImportResult, ImportServiceAbstraction } from "@bitwarden/importer/core";
|
||||
|
||||
|
@ -38,10 +40,12 @@ describe("FilelessImporterBackground ", () => {
|
|||
const notificationBackground = mock<NotificationBackground>();
|
||||
const importService = mock<ImportServiceAbstraction>();
|
||||
const syncService = mock<SyncService>();
|
||||
const platformUtilsService = mock<PlatformUtilsService>();
|
||||
const logService = mock<LogService>();
|
||||
let scriptInjectorService: BrowserScriptInjectorService;
|
||||
|
||||
beforeEach(() => {
|
||||
scriptInjectorService = new BrowserScriptInjectorService();
|
||||
scriptInjectorService = new BrowserScriptInjectorService(platformUtilsService, logService);
|
||||
filelessImporterBackground = new FilelessImporterBackground(
|
||||
configService,
|
||||
authService,
|
||||
|
|
Loading…
Reference in New Issue