1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-11-21 11:35:34 +01:00

Revert "[PM-14485] Remove manifest and index.html logic from gulp" (#12032)

This reverts commit c388697fdf.
This commit is contained in:
Oscar Hinton 2024-11-18 15:38:53 +01:00 committed by GitHub
parent c388697fdf
commit d875ded8fa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 5385 additions and 374 deletions

View File

@ -12,7 +12,6 @@ storybook-static
apps/browser/config/config.js
apps/browser/src/auth/scripts/duo.js
apps/browser/webpack/manifest.js
apps/desktop/desktop_native
apps/desktop/src/auth/scripts/duo.js

View File

@ -164,74 +164,16 @@ jobs:
zip -r browser-source.zip browser-source
- name: Upload browser source
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: browser-source-${{ env._BUILD_NUMBER }}.zip
path: browser-source.zip
if-no-files-found: error
- name: NPM setup
run: npm ci
working-directory: browser-source/
- name: Build Chrome
run: npm run dist:chrome
- name: Build
run: npm run dist
working-directory: browser-source/apps/browser
- name: Upload Chrome MV3 artifact
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: dist-chrome-MV3-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-chrome.zip
if-no-files-found: error
- name: Build Edge
run: npm run dist:edge
working-directory: browser-source/apps/browser
- name: Upload Edge artifact
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: dist-edge-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-edge.zip
if-no-files-found: error
- name: Build Edge (MV3)
run: npm run dist:edge:mv3
working-directory: browser-source/apps/browser
- name: Upload Edge MV3 artifact (DO NOT USE FOR PROD)
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: DO-NOT-USE-FOR-PROD-dist-edge-MV3-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-edge.zip
if-no-files-found: error
- name: Build Firefox
run: npm run dist:firefox
working-directory: browser-source/apps/browser
- name: Upload Firefox artifact
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: dist-firefox-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-firefox.zip
if-no-files-found: error
- name: Build Firefox (MV3)
run: npm run dist:firefox:mv3
working-directory: browser-source/apps/browser
- name: Upload Firefox MV3 artifact (DO NOT USE FOR PROD)
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: DO-NOT-USE-FOR-PROD-dist-firefox-MV3-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-firefox.zip
if-no-files-found: error
- name: Build Opera
run: npm run dist:opera
- name: Build Manifest v3
run: npm run dist:mv3
working-directory: browser-source/apps/browser
- name: Upload Opera artifact
@ -241,15 +183,53 @@ jobs:
path: browser-source/apps/browser/dist/dist-opera.zip
if-no-files-found: error
- name: Build Opera (MV3)
run: npm run dist:opera:mv3
working-directory: browser-source/apps/browser
- name: Upload Opera MV3 artifact (DO NOT USE FOR PROD)
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: DO-NOT-USE-FOR-PROD-dist-opera-MV3-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-opera.zip
path: browser-source/apps/browser/dist/dist-opera-mv3.zip
if-no-files-found: error
- name: Upload Chrome MV3 artifact
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: dist-chrome-MV3-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-chrome-mv3.zip
if-no-files-found: error
- name: Upload Firefox artifact
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: dist-firefox-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-firefox.zip
if-no-files-found: error
- name: Upload Firefox MV3 artifact (DO NOT USE FOR PROD)
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: DO-NOT-USE-FOR-PROD-dist-firefox-MV3-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-firefox-mv3.zip
if-no-files-found: error
- name: Upload Edge artifact
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: dist-edge-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-edge.zip
if-no-files-found: error
- name: Upload Edge MV3 artifact (DO NOT USE FOR PROD)
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: DO-NOT-USE-FOR-PROD-dist-edge-MV3-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-edge-mv3.zip
if-no-files-found: error
- name: Upload browser source
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: browser-source-${{ env._BUILD_NUMBER }}.zip
path: browser-source.zip
if-no-files-found: error
build-safari:

View File

@ -121,7 +121,7 @@ jobs:
PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }}
run: |
mv browser-source.zip browser-source-$PACKAGE_VERSION.zip
mv dist-chrome.zip dist-chrome-$PACKAGE_VERSION.zip
mv dist-chrome-mv3.zip dist-chrome-$PACKAGE_VERSION.zip
mv dist-opera.zip dist-opera-$PACKAGE_VERSION.zip
mv dist-firefox.zip dist-firefox-$PACKAGE_VERSION.zip
mv dist-edge.zip dist-edge-$PACKAGE_VERSION.zip

233
apps/browser/gulpfile.js Normal file
View File

@ -0,0 +1,233 @@
const child = require("child_process");
const fs = require("fs");
const { rimraf } = require("rimraf");
const gulp = require("gulp");
const gulpif = require("gulp-if");
const jeditor = require("gulp-json-editor");
const replace = require("gulp-replace");
const manifest = require("./src/manifest.json");
const manifestVersion = parseInt(process.env.MANIFEST_VERSION || manifest.version);
const paths = {
build: "./build/",
dist: "./dist/",
safari: "./src/safari/",
};
function buildString() {
var build = "";
if (process.env.MANIFEST_VERSION) {
build = `-mv${process.env.MANIFEST_VERSION}`;
}
if (process.env.BUILD_NUMBER && process.env.BUILD_NUMBER !== "") {
build = `-${process.env.BUILD_NUMBER}`;
}
return build;
}
function distFileName(browserName, ext) {
return `dist-${browserName}${buildString()}.${ext}`;
}
async function dist(browserName, manifest) {
const { default: zip } = await import("gulp-zip");
return gulp
.src(paths.build + "**/*")
.pipe(gulpif("popup/index.html", replace("__BROWSER__", "browser_" + browserName)))
.pipe(gulpif("manifest.json", jeditor(manifest)))
.pipe(zip(distFileName(browserName, "zip")))
.pipe(gulp.dest(paths.dist));
}
function distFirefox() {
return dist("firefox", (manifest) => {
if (manifestVersion === 3) {
const backgroundScript = manifest.background.service_worker;
delete manifest.background.service_worker;
manifest.background.scripts = [backgroundScript];
}
delete manifest.storage;
delete manifest.sandbox;
manifest.optional_permissions = manifest.optional_permissions.filter(
(permission) => permission !== "privacy",
);
return manifest;
});
}
function distOpera() {
return dist("opera", (manifest) => {
delete manifest.applications;
// Mv3 on Opera does seem to have sidebar support, however it is not working as expected.
// On install, the extension will crash the browser entirely if the sidebar_action key is set.
// We will remove the sidebar_action key for now until opera implements a fix.
if (manifestVersion === 3) {
delete manifest.sidebar_action;
delete manifest.commands._execute_sidebar_action;
}
return manifest;
});
}
function distChrome() {
return dist("chrome", (manifest) => {
delete manifest.applications;
delete manifest.sidebar_action;
delete manifest.commands._execute_sidebar_action;
return manifest;
});
}
function distEdge() {
return dist("edge", (manifest) => {
delete manifest.applications;
delete manifest.sidebar_action;
delete manifest.commands._execute_sidebar_action;
return manifest;
});
}
function distSafariMas(cb) {
return distSafariApp(cb, "mas");
}
function distSafariMasDev(cb) {
return distSafariApp(cb, "masdev");
}
function distSafariDmg(cb) {
return distSafariApp(cb, "dmg");
}
function distSafariApp(cb, subBuildPath) {
const buildPath = paths.dist + "Safari/" + subBuildPath + "/";
const builtAppexPath = buildPath + "build/Release/safari.appex";
const builtAppexFrameworkPath = buildPath + "build/Release/safari.appex/Contents/Frameworks/";
const entitlementsPath = paths.safari + "safari/safari.entitlements";
var args = [
"--verbose",
"--force",
"-o",
"runtime",
"--sign",
"Developer ID Application: 8bit Solutions LLC",
"--entitlements",
entitlementsPath,
];
if (subBuildPath !== "dmg") {
args = [
"--verbose",
"--force",
"--sign",
subBuildPath === "mas"
? "3rd Party Mac Developer Application: Bitwarden Inc"
: "E7C9978F6FBCE0553429185C405E61F5380BE8EB",
"--entitlements",
entitlementsPath,
];
}
return rimraf([buildPath + "**/*"], { glob: true })
.then(() => safariCopyAssets(paths.safari + "**/*", buildPath))
.then(() => safariCopyBuild(paths.build + "**/*", buildPath + "safari/app"))
.then(() => {
const proc = child.spawn("xcodebuild", [
"-project",
buildPath + "desktop.xcodeproj",
"-alltargets",
"-configuration",
"Release",
]);
stdOutProc(proc);
return new Promise((resolve) => proc.on("close", resolve));
})
.then(async () => {
const libs = fs
.readdirSync(builtAppexFrameworkPath)
.filter((p) => p.endsWith(".dylib"))
.map((p) => builtAppexFrameworkPath + p);
const libPromises = [];
libs.forEach((i) => {
const proc = child.spawn("codesign", args.concat([i]));
stdOutProc(proc);
libPromises.push(new Promise((resolve) => proc.on("close", resolve)));
});
return Promise.all(libPromises);
})
.then(() => {
const proc = child.spawn("codesign", args.concat([builtAppexPath]));
stdOutProc(proc);
return new Promise((resolve) => proc.on("close", resolve));
})
.then(
() => {
return cb;
},
() => {
return cb;
},
);
}
function safariCopyAssets(source, dest) {
return new Promise((resolve, reject) => {
gulp
.src(source)
.on("error", reject)
.pipe(gulpif("safari/Info.plist", replace("0.0.1", manifest.version)))
.pipe(
gulpif("safari/Info.plist", replace("0.0.2", process.env.BUILD_NUMBER || manifest.version)),
)
.pipe(gulpif("desktop.xcodeproj/project.pbxproj", replace("../../../build", "../safari/app")))
.pipe(gulp.dest(dest))
.on("end", resolve);
});
}
async function safariCopyBuild(source, dest) {
return new Promise((resolve, reject) => {
gulp
.src(source)
.on("error", reject)
.pipe(gulpif("popup/index.html", replace("__BROWSER__", "browser_safari")))
.pipe(
gulpif(
"manifest.json",
jeditor((manifest) => {
if (manifestVersion === 3) {
const backgroundScript = manifest.background.service_worker;
delete manifest.background.service_worker;
manifest.background.scripts = [backgroundScript];
}
delete manifest.sidebar_action;
delete manifest.commands._execute_sidebar_action;
delete manifest.optional_permissions;
manifest.permissions.push("nativeMessaging");
return manifest;
}),
),
)
.pipe(gulp.dest(dest))
.on("end", resolve);
});
}
function stdOutProc(proc) {
proc.stdout.on("data", (data) => console.log(data.toString()));
proc.stderr.on("data", (data) => console.error(data.toString()));
}
exports["dist:firefox"] = distFirefox;
exports["dist:chrome"] = distChrome;
exports["dist:opera"] = distOpera;
exports["dist:edge"] = distEdge;
exports["dist:safari"] = gulp.parallel(distSafariMas, distSafariMasDev, distSafariDmg);
exports["dist:safari:mas"] = distSafariMas;
exports["dist:safari:masdev"] = distSafariMasDev;
exports["dist:safari:dmg"] = distSafariDmg;
exports.dist = gulp.parallel(distFirefox, distChrome, distOpera, distEdge);

View File

@ -2,32 +2,26 @@
"name": "@bitwarden/browser",
"version": "2024.11.1",
"scripts": {
"build": "npm run build:chrome",
"build:chrome": "cross-env BROWSER=chrome MANIFEST_VERSION=3 webpack",
"build:edge": "cross-env BROWSER=edge webpack",
"build:firefox": "cross-env BROWSER=firefox webpack",
"build:opera": "cross-env BROWSER=opera webpack",
"build:safari": "cross-env BROWSER=safari webpack",
"build": "cross-env MANIFEST_VERSION=3 webpack",
"build:mv2": "webpack",
"build:watch": "npm run build:watch:chrome",
"build:watch:chrome": "npm run build:chrome -- --watch",
"build:watch:edge": "npm run build:edge -- --watch",
"build:watch:firefox": "npm run build:firefox -- --watch",
"build:watch:opera": "npm run build:opera -- --watch",
"build:watch:safari": "npm run build:safari -- --watch",
"build:prod:chrome": "cross-env NODE_ENV=production NODE_OPTIONS=\"--max-old-space-size=4096\" npm run build:chrome",
"build:prod:edge": "cross-env NODE_ENV=production NODE_OPTIONS=\"--max-old-space-size=4096\" npm run build:edge",
"build:prod:firefox": "cross-env NODE_ENV=production NODE_OPTIONS=\"--max-old-space-size=4096\" npm run build:firefox",
"build:prod:opera": "cross-env NODE_ENV=production NODE_OPTIONS=\"--max-old-space-size=4096\" npm run build:opera",
"build:prod:safari": "cross-env NODE_ENV=production NODE_OPTIONS=\"--max-old-space-size=4096\" npm run build:safari",
"dist:chrome": "npm run build:prod:chrome && mkdir -p dist && tar -C ./build -acf dist/dist-chrome.zip ./",
"dist:edge": "npm run build:prod:edge && mkdir -p dist && tar -C ./build -acf dist/dist-edge.zip ./",
"dist:firefox": "npm run build:prod:firefox && mkdir -p dist && tar -C ./build -acf dist/dist-firefox.zip ./",
"dist:opera": "npm run build:prod:opera && mkdir -p dist && tar -C ./build -acf dist/dist-opera.zip ./",
"dist:safari": "npm run build:prod:safari && ./scripts/package-safari.ps1",
"dist:edge:mv3": "cross-env MANIFEST_VERSION=3 npm run dist:edge",
"dist:firefox:mv3": "cross-env MANIFEST_VERSION=3 npm run dist:firefox",
"dist:opera:mv3": "cross-env MANIFEST_VERSION=3 npm run dist:opera",
"dist:safari:mv3": "cross-env MANIFEST_VERSION=3 npm run dist:safari",
"build:watch:chrome": "cross-env MANIFEST_VERSION=3 BROWSER=chrome webpack --watch",
"build:watch:firefox": "cross-env MANIFEST_VERSION=3 BROWSER=firefox webpack --watch",
"build:watch:safari": "cross-env MANIFEST_VERSION=3 BROWSER=safari webpack --watch",
"build:watch:mv2": "webpack --watch",
"build:prod": "cross-env NODE_ENV=production NODE_OPTIONS=\"--max-old-space-size=4096\" webpack",
"build:prod:watch": "cross-env NODE_ENV=production webpack --watch",
"dist": "npm run build:prod && gulp dist",
"dist:mv3": "cross-env MANIFEST_VERSION=3 npm run build:prod && cross-env MANIFEST_VERSION=3 gulp dist",
"dist:chrome": "npm run build:prod && gulp dist:chrome",
"dist:chrome:beta": "cross-env MANIFEST_VERSION=3 npm run build:prod:beta && cross-env MANIFEST_VERSION=3 BETA_BUILD=1 gulp dist:chrome",
"dist:firefox": "npm run build:prod && gulp dist:firefox",
"dist:opera": "npm run build:prod && gulp dist:opera",
"dist:safari": "cross-env BROWSER=safari npm run build:prod && gulp dist:safari",
"dist:safari:mv3": "cross-env MANIFEST_VERSION=3 BROWSER=safari run build:prod && cross-env MANIFEST_VERSION=3 BROWSER=safari gulp dist:safari",
"dist:safari:mas": "npm run build:prod && gulp dist:safari:mas",
"dist:safari:masdev": "npm run build:prod && gulp dist:safari:masdev",
"dist:safari:dmg": "npm run build:prod && gulp dist:safari:dmg",
"test": "jest",
"test:watch": "jest --watch",
"test:watch:all": "jest --watchAll"

View File

@ -1,112 +0,0 @@
#!/usr/bin/env pwsh
####
# Builds the safari appex.
####
$buildDir = Join-Path $PSScriptRoot "../build"
$distDir = Join-Path $PSScriptRoot "../dist"
Write-Output $PSScriptRoot
if (-not (Test-Path $buildDir)) {
Write-Output "No build directory found. Exiting..."
exit
}
# Create dist directory if it doesn't exist
if (-not (Test-Path $distDir)) {
New-Item -ItemType Directory -Path $distDir
}
$subBuildPaths = @("mas", "masdev", "dmg")
$safariSrc = Join-Path $PSScriptRoot "../src/safari"
$safariDistPath = Join-Path -Path $distDir -ChildPath "Safari"
if (-not (Test-Path $safariDistPath)) {
New-Item -ItemType Directory -Path $safariDistPath
}
# Delete old safari dists
Remove-Item -LiteralPath $safariDistPath -Force -Recurse
foreach ($subBuildPath in $subBuildPaths) {
$safariBuildPath = Join-Path -Path $safariDistPath -ChildPath $subBuildPath
$builtAppexPath = Join-Path -Path $safariBuildPath -ChildPath "build/Release/safari.appex"
$builtAppexFrameworkPath = Join-Path -Path $safariBuildPath -ChildPath "build/Release/safari.appex/Contents/Frameworks/"
$entitlementsPath = Join-Path -Path $safariSrc -ChildPath "safari/safari.entitlements"
switch ($subBuildPath) {
"mas" {
$codesignArgs = @(
"--verbose",
"--force",
"--sign",
"3rd Party Mac Developer Application: Bitwarden Inc",
"--entitlements",
$entitlementsPath
)
}
"masdev" {
$codesignArgs = @(
"--verbose",
"--force",
"--sign",
"E7C9978F6FBCE0553429185C405E61F5380BE8EB",
"--entitlements",
$entitlementsPath
)
}
"dmg" {
$codesignArgs = @(
"--verbose",
"--force",
"-o",
"runtime",
"--sign",
"Developer ID Application: 8bit Solutions LLC",
"--entitlements",
$entitlementsPath
)
}
}
# Copy safari src
Copy-Item -Path $safariSrc -Destination $safariBuildPath -Recurse
# Copy build
$target = Join-Path -Path $safariBuildPath -ChildPath "safari/app"
Copy-Item -Path $buildDir -Destination $target -Recurse
# Update versions
$jsonFilePath = Join-Path $buildDir "manifest.json"
$jsonContent = Get-Content -Path $jsonFilePath -Raw
$jsonObject = $jsonContent | ConvertFrom-Json
$infoFile = Join-Path -Path $safariBuildPath -ChildPath "safari/Info.plist"
(Get-Content $infoFile).Replace('0.0.1', $jsonObject.version).Replace('0.0.2', $jsonObject.version) | Set-Content $infoFile
$projectFile = Join-Path -Path $safariBuildPath -ChildPath "desktop.xcodeproj/project.pbxproj"
(Get-Content $projectFile).Replace('../../../build', "../safari/app") | Set-Content $projectFile
# Build using xcode
$xcodeBuildArgs = @(
"-project",
(Join-Path $safariBuildPath "desktop.xcodeproj"),
"-alltargets",
"-configuration",
"Release"
)
$proc = Start-Process "xcodebuild" -ArgumentList $xcodeBuildArgs -NoNewWindow -PassThru
$proc.WaitForExit()
# Codesign
$libs = Get-ChildItem -Path $builtAppexFrameworkPath -Filter "*.dylib"
foreach ($lib in $libs) {
$proc = Start-Process "codesign" -ArgumentList ($codesignArgs + $lib.FullName) -NoNewWindow -PassThru
$proc.WaitForExit()
}
$proc = Start-Process "codesign" -ArgumentList ($codesignArgs + $builtAppexPath) -NoNewWindow -PassThru
$proc.WaitForExit()
}

View File

@ -52,37 +52,19 @@
"permissions": [
"<all_urls>",
"*://*/*",
"alarms",
"tabs",
"contextMenus",
"storage",
"unlimitedStorage",
"clipboardRead",
"clipboardWrite",
"contextMenus",
"idle",
"storage",
"tabs",
"unlimitedStorage",
"webNavigation",
"webRequest",
"webRequestBlocking"
],
"__safari__permissions": [
"<all_urls>",
"*://*/*",
"alarms",
"clipboardRead",
"clipboardWrite",
"contextMenus",
"idle",
"nativeMessaging",
"storage",
"tabs",
"unlimitedStorage",
"webNavigation",
"webRequest",
"webRequestBlocking"
"webRequestBlocking",
"webNavigation"
],
"optional_permissions": ["nativeMessaging", "privacy"],
"__firefox__optional_permissions": ["nativeMessaging"],
"__safari__optional_permissions": null,
"content_security_policy": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self'",
"sandbox": {
"pages": [
@ -93,7 +75,6 @@
],
"content_security_policy": "sandbox allow-scripts; script-src 'self'"
},
"__firefox__sandbox": null,
"commands": {
"_execute_browser_action": {
"suggested_key": {
@ -102,14 +83,7 @@
},
"description": "__MSG_commandOpenPopup__"
},
"__firefox___execute_sidebar_action": {
"suggested_key": {
"default": "Alt+Shift+Y",
"linux": "Alt+Shift+U"
},
"description": "__MSG_commandOpenSidebar__"
},
"__opera___execute_sidebar_action": {
"_execute_sidebar_action": {
"suggested_key": {
"default": "Alt+Shift+Y",
"linux": "Alt+Shift+U"
@ -151,26 +125,20 @@
"overlay/list.html",
"popup/fonts/*"
],
"__firefox__browser_specific_settings": {
"applications": {
"gecko": {
"id": "{446900e4-71c2-419f-a6a7-df9c091e268b}",
"strict_min_version": "91.0"
}
},
"__firefox__sidebar_action": {
"sidebar_action": {
"default_title": "Bitwarden",
"default_panel": "popup/index.html?uilocation=sidebar",
"default_icon": "images/icon19.png",
"open_at_install": false,
"browser_style": false
},
"__opera__sidebar_action": {
"default_title": "Bitwarden",
"default_panel": "popup/index.html?uilocation=sidebar",
"default_icon": "images/icon19.png",
"open_at_install": false,
"browser_style": false
},
"storage": { "managed_schema": "managed_schema.json" },
"__firefox__storage": null
"storage": {
"managed_schema": "managed_schema.json"
}
}

View File

@ -41,9 +41,6 @@
"background": {
"service_worker": "background.js"
},
"__firefox__background": {
"scripts": ["background.js"]
},
"action": {
"default_icon": {
"19": "images/icon19.png",
@ -54,40 +51,21 @@
},
"permissions": [
"activeTab",
"alarms",
"tabs",
"contextMenus",
"storage",
"unlimitedStorage",
"clipboardRead",
"clipboardWrite",
"contextMenus",
"idle",
"offscreen",
"scripting",
"storage",
"tabs",
"unlimitedStorage",
"webNavigation",
"webRequest",
"webRequestAuthProvider"
],
"__safari__permissions": [
"activeTab",
"alarms",
"clipboardRead",
"clipboardWrite",
"contextMenus",
"idle",
"nativeMessaging",
"offscreen",
"scripting",
"storage",
"tabs",
"unlimitedStorage",
"webNavigation",
"offscreen",
"webRequest",
"webRequestAuthProvider"
"webRequestAuthProvider",
"webNavigation"
],
"optional_permissions": ["nativeMessaging", "privacy"],
"__firefox__optional_permissions": ["nativeMessaging"],
"__safari__optional_permissions": null,
"host_permissions": ["https://*/*", "http://*/*"],
"content_security_policy": {
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self'",
@ -101,7 +79,6 @@
"overlay/list.html"
]
},
"__firefox__sandbox": null,
"commands": {
"_execute_action": {
"suggested_key": {
@ -110,7 +87,7 @@
},
"description": "__MSG_commandOpenPopup__"
},
"__firefox___execute_sidebar_action": {
"_execute_sidebar_action": {
"suggested_key": {
"default": "Alt+Shift+Y",
"linux": "Alt+Shift+U"
@ -156,13 +133,13 @@
"matches": ["<all_urls>"]
}
],
"__firefox__browser_specific_settings": {
"applications": {
"gecko": {
"id": "{446900e4-71c2-419f-a6a7-df9c091e268b}",
"strict_min_version": "91.0"
}
},
"__firefox__sidebar_action": {
"sidebar_action": {
"default_title": "Bitwarden",
"default_panel": "popup/index.html?uilocation=sidebar",
"default_icon": "images/icon19.png",
@ -170,6 +147,5 @@
},
"storage": {
"managed_schema": "managed_schema.json"
},
"__firefox__storage": null
}
}

View File

@ -1,5 +1,5 @@
<!doctype html>
<html class="browser_<%= htmlWebpackPlugin.options.browser %>">
<html class="__BROWSER__">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />

View File

@ -7,14 +7,58 @@ const { AngularWebpackPlugin } = require("@ngtools/webpack");
const TerserPlugin = require("terser-webpack-plugin");
const { TsconfigPathsPlugin } = require("tsconfig-paths-webpack-plugin");
const configurator = require("./config/config");
const manifest = require("./webpack/manifest");
if (process.env.NODE_ENV == null) {
process.env.NODE_ENV = "development";
}
const ENV = (process.env.ENV = process.env.NODE_ENV);
const manifestVersion = process.env.MANIFEST_VERSION == 3 ? 3 : 2;
const browser = process.env.BROWSER ?? "chrome";
const browser = process.env.BROWSER;
function modifyManifestV3(buffer) {
if (manifestVersion === 2 || !browser) {
return buffer;
}
const manifest = JSON.parse(buffer.toString());
if (browser === "chrome") {
// Remove unsupported properties
delete manifest.applications;
delete manifest.sidebar_action;
delete manifest.commands._execute_sidebar_action;
return JSON.stringify(manifest, null, 2);
}
// Update the background script reference to be an event page
const backgroundScript = manifest.background.service_worker;
delete manifest.background.service_worker;
manifest.background.scripts = [backgroundScript];
// Remove unsupported properties
delete manifest.content_security_policy.sandbox;
delete manifest.sandbox;
delete manifest.applications;
manifest.permissions = manifest.permissions.filter((permission) => permission !== "offscreen");
if (browser === "safari") {
delete manifest.sidebar_action;
delete manifest.commands._execute_sidebar_action;
delete manifest.optional_permissions;
manifest.permissions.push("nativeMessaging");
}
if (browser === "firefox") {
delete manifest.storage;
manifest.optional_permissions = manifest.optional_permissions.filter(
(permission) => permission !== "privacy",
);
}
return JSON.stringify(manifest, null, 2);
}
console.log(`Building Manifest Version ${manifestVersion} app`);
@ -98,10 +142,9 @@ const requiredPlugins = [
const plugins = [
new HtmlWebpackPlugin({
template: "./src/popup/index.ejs",
template: "./src/popup/index.html",
filename: "popup/index.html",
chunks: ["popup/polyfills", "popup/vendor-angular", "popup/vendor", "popup/main"],
browser: browser,
}),
new HtmlWebpackPlugin({
template: "./src/autofill/notification/bar.html",
@ -135,11 +178,13 @@ const plugins = [
}),
new CopyWebpackPlugin({
patterns: [
{
from: manifestVersion == 3 ? "./src/manifest.v3.json" : "./src/manifest.json",
to: "manifest.json",
transform: manifest.transform(browser),
},
manifestVersion == 3
? {
from: "./src/manifest.v3.json",
to: "manifest.json",
transform: (content) => modifyManifestV3(content),
}
: "./src/manifest.json",
{ from: "./src/managed_schema.json", to: "managed_schema.json" },
{ from: "./src/_locales", to: "_locales" },
{ from: "./src/images", to: "images" },

View File

@ -1,72 +0,0 @@
/**
* Transform the manifest template into a browser specific manifest.
*
* We support a simple browser prefix to the manifest keys. Example:
*
* ```json
* {
* "name": "Default name",
* "__chrome__name": "Chrome override"
* }
* ```
*
* Will result in the following manifest:
*
* ```json
* {
* "name": "Chrome override"
* }
* ```
*
* for Chrome.
*/
function transform(browser) {
return (buffer) => {
let manifest = JSON.parse(buffer.toString());
manifest = transformPrefixes(manifest, browser);
return JSON.stringify(manifest, null, 2);
};
}
const browsers = ["chrome", "edge", "firefox", "opera", "safari"];
/**
* Flatten the browser prefixes in the manifest.
*
* - Removes unrelated browser prefixes.
* - A null value deletes the non prefixed key.
*/
function transformPrefixes(manifest, browser) {
const prefix = `__${browser}__`;
function transformObject(obj) {
return Object.keys(obj).reduce((acc, key) => {
// Determine if we need to recurse into the object.
const nested = typeof obj[key] === "object" && obj[key] !== null && !Array.isArray(obj[key]);
if (key.startsWith(prefix)) {
const newKey = key.slice(prefix.length);
// Null values are used to remove keys.
if (obj[key] == null) {
delete acc[newKey];
return acc;
}
acc[newKey] = nested ? transformObject(obj[key]) : obj[key];
} else if (!browsers.some((b) => key.startsWith(`__${b}__`))) {
acc[key] = nested ? transformObject(obj[key]) : obj[key];
}
return acc;
}, {});
}
return transformObject(manifest);
}
module.exports = {
transform,
};

5009
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -107,6 +107,11 @@
"eslint-plugin-rxjs-angular": "2.0.1",
"eslint-plugin-storybook": "0.8.0",
"eslint-plugin-tailwindcss": "3.17.4",
"gulp": "4.0.2",
"gulp-if": "3.0.0",
"gulp-json-editor": "2.6.0",
"gulp-replace": "1.1.4",
"gulp-zip": "6.0.0",
"html-loader": "5.1.0",
"html-webpack-injector": "1.1.4",
"html-webpack-plugin": "5.6.3",