Skip to content

Commit

Permalink
feature: adds support for manifest 3 (v0.23.0)
Browse files Browse the repository at this point in the history
- github issue [#9]
  • Loading branch information
this-oliver committed Apr 16, 2023
1 parent b6ba226 commit 0074e97
Show file tree
Hide file tree
Showing 13 changed files with 103 additions and 61 deletions.
1 change: 0 additions & 1 deletion docs/extension.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,3 @@ The following steps should be followed regardless of the browser you are publish

1. [create a chrome developer account](https://developer.chrome.com/docs/webstore/register/) and pay the $5 fee 😤
2. [upload zip file](https://chrome.google.com/webstore/devconsole) to Chrome's devconsole
3. []
20 changes: 10 additions & 10 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SSASy</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>SSASY</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
16 changes: 10 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"name": "@ssasy-auth/extension",
"nickname": "ssasy",
"version": "0.22.14",
"version": "0.23.0",
"license": "MIT",
"description": "a browser extension that is built with a secure, usable and scalable authentictaion scheme",
"description": "A browser extension that offers a secure and usable alternative to passwords and federated identity providers.",
"repository": "this-oliver/ssasy-ext",
"author": "[email protected]",
"scripts": {
Expand All @@ -14,24 +14,28 @@
"bridge:preview": "pnpm bridge:prepare && cd src/bridge && npm pack && cd ../../ && pnpm bridge:clear",
"bridge:clear": "rimraf src/bridge/package.json src/bridge/*-lock.* src/bridge/lib src/bridge/node_modules",
"build": "cross-env NODE_ENV=production run-s clear build:web build:prepare build:js",
"build:mv3": "cross-env NODE_ENV=production MANIFEST_VERSION=3 run-s clear build:web build:prepare build:js build:bg",
"build:prepare": "esno scripts/prepare.ts",
"build:web": "vite build",
"build:js": "vite build --config vite.config.content.ts",
"build:bg": "vite build --config vite.config.background.ts",
"bump": "npx fistbump",
"clear": "rimraf extension/dist extension/manifest.json extension.* *.tgz",
"dev": "npm run clear && cross-env NODE_ENV=development run-p dev:*",
"dev": "npm run clear && cross-env NODE_ENV=development run-p 'dev:!(mv3|bg)'",
"dev:mv3": "npm run clear && cross-env NODE_ENV=development MANIFEST_VERSION=3 run-p 'dev:!(mv3)'",
"dev:prepare": "esno scripts/prepare.ts",
"dev:web": "vite",
"dev:js": "npm run build:js -- --mode development",
"dev:bg": "npm run build:bg -- --mode development",
"lint": "eslint --cache --ext .html,.vue,.js,.ts",
"lint:fix": "eslint --fix --ext .html,.vue,.js,.ts",
"pack": "cross-env NODE_ENV=production run-p pack:*",
"pack:zip": "rimraf extension.zip && jszip-cli add extension/* -o ./extension.zip",
"pack:crx": "crx pack extension -o ./extension.crx",
"pack:xpi": "cross-env WEB_EXT_ARTIFACTS_DIR=./ web-ext build --source-dir ./extension --filename extension.xpi --overwrite-dest",
"prepare:firefox": "run-s build pack:zip",
"release:firefox": "pnpm build && pnpm pack && pnpm pack:zip",
"release:chromium": "pnpm build:mv3 && pnpm pack && pnpm pack:zip",
"postinstall": "simple-git-hooks",
"publish": "pnpm bridge:preview",
"start:chromium": "web-ext run --source-dir ./extension --target=chromium",
"start:firefox": "web-ext run --source-dir ./extension --target=firefox-desktop --firefox=firefoxdeveloperedition",
"test": "vitest test"
Expand Down Expand Up @@ -92,4 +96,4 @@
"*.ts": "eslint --fix"
},
"packageManager": "[email protected]"
}
}
7 changes: 5 additions & 2 deletions scripts/manifest.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import fs from 'fs-extra'
import { getManifest } from '../src/manifest'
import { log, r } from './utils'
import { log, r, isManifest3 } from './utils'

/**
* Writes manifest.ts to extension folder as manifest.json
*/
export async function writeManifest() {
await fs.writeJSON(r('extension/manifest.json'), await getManifest(), { spaces: 2 })
await fs.writeJSON(r('extension/manifest.json'), await getManifest(isManifest3 ? 'v3' : 'v2'), { spaces: 2 })
log('PRE', 'write manifest.json')
}

Expand Down
19 changes: 15 additions & 4 deletions scripts/prepare.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@
import { execSync } from 'node:child_process'
import fs from 'fs-extra'
import chokidar from 'chokidar'
import { isDev, log, port, r } from './utils'
import { isDev, log, port, r, isManifest3 } from './utils'

/**
* Stub index.html to use Vite in development
*/
async function stubIndexHtml() {
const views = [
'options',
'popup',
'background'
'popup'
]

// manifest v3 does not support background pages
if (!isManifest3) {
views.push('background')
}

for (const view of views) {
await fs.ensureDir(r(`extension/dist/${view}`))
let data = await fs.readFile(r(`src/${view}/index.html`), 'utf-8')
Expand All @@ -25,18 +29,25 @@ async function stubIndexHtml() {
}
}

/**
* Write manifest.json to extension folder
*/
function writeManifest() {
execSync('npx esno ./scripts/manifest.ts', { stdio: 'inherit' })
}

writeManifest()

if (isDev) {
if (isDev && !isManifest3) {
stubIndexHtml()

// watch for changes to html files
chokidar.watch(r('src/**/*.html'))
.on('change', () => {
stubIndexHtml()
})

// watch for changes to manifest.ts or package.json
chokidar.watch([ r('src/manifest.ts'), r('package.json') ])
.on('change', () => {
writeManifest()
Expand Down
1 change: 1 addition & 0 deletions scripts/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { bgCyan, black } from 'kolorist'
export const port = parseInt(process.env.PORT || '') || 3303
export const r = (...args: string[]) => resolve(__dirname, '..', ...args)
export const isDev = process.env.NODE_ENV !== 'production'
export const isManifest3 = process.env.MANIFEST_VERSION === '3'

export function log(name: string, message: string) {
console.log(black(bgCyan(` ${name} `)), message)
Expand Down
14 changes: 7 additions & 7 deletions src/background/index.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Background</title>
</head>
<body>
<script type="module" src="./main.ts"></script>
</body>
<head>
<meta charset="UTF-8" />
<title>Background</title>
</head>
<body>
<script type="module" src="./index.ts"></script>
</body>
</html>
7 changes: 0 additions & 7 deletions src/background/main.ts → src/background/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,6 @@ if (import.meta.hot) {
import('./contentScriptHMR');
}

/**
* Listen for extension install and log to console
*/
browser.runtime.onInstalled.addListener((): void => {
Logger.info('Extension installed', null, 'background');
});

export interface Session {
request: PublicKeyRequest | ChallengeRequest;
popupPage: Windows.Window | Tabs.Tab;
Expand Down
10 changes: 1 addition & 9 deletions src/contentScripts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,16 +197,8 @@ import App from './App.vue';
// ======== ssasy logic - request channel ========

// mount component to context window
const container = document.createElement('div');
const root = document.createElement('div');
const styleEl = document.createElement('link');
const shadowDOM = container.attachShadow?.({ mode: __DEV__ ? 'open' : 'closed' }) || container;
styleEl.setAttribute('rel', 'stylesheet');
styleEl.setAttribute('href', browser.runtime.getURL('dist/contentScripts/style.css'));
shadowDOM.appendChild(styleEl);
shadowDOM.appendChild(root);
document.body.appendChild(container);
const app = createApp(App);
setupApp(app, { blockVuetify: true });
setupApp(app, { blockVuetify: true, blockPinia: true });
app.mount(root);
})();
29 changes: 17 additions & 12 deletions src/manifest.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import fs from 'fs-extra'
import type { Manifest } from 'webextension-polyfill'
import type PkgType from '../package.json'
import { isDev, port, r } from '../scripts/utils'
import { isDev, port, r, isManifest3 } from '../scripts/utils'

const extIcons = {
16: './assets/icon-16.png',
Expand Down Expand Up @@ -35,8 +35,7 @@ const manifestV2: Manifest.WebExtensionManifest = {
permissions: [ ...extPermissions, ...extHostPermissions ],
options_ui: {
page: './dist/options/index.html',
open_in_tab: true,
chrome_style: false
open_in_tab: true
},
background: {
page: './dist/background/index.html',
Expand Down Expand Up @@ -64,7 +63,6 @@ const manifestV2: Manifest.WebExtensionManifest = {
}
}

// TODO: convert background script to service worker
const manifestV3: Manifest.WebExtensionManifest = {
...manifestV2,

Expand All @@ -79,19 +77,24 @@ const manifestV3: Manifest.WebExtensionManifest = {

host_permissions: extHostPermissions,

// TODO: fix this and celebrate
//background: {
// service_worker: 'service_worker.js',
// page: './dist/background/index.html'
//},
background: {
service_worker: './dist/background/index.js',
type: 'module'
},

// remove deprecated fields
browser_action: undefined
}

type ManifestVersion = 'v2' | 'v3'

export async function getManifest(version: ManifestVersion = 'v2') {
/**
* Returns a json object of the manifest config based on the manifest version
*
* @param version - manifest version
* @returns manifest.json
*/
export async function getManifest(version: ManifestVersion = 'v2'): Promise<Manifest.WebExtensionManifest> {
const pkg = await fs.readJSON(r('package.json')) as typeof PkgType

// set base manifest based on manifest version
Expand All @@ -117,8 +120,10 @@ export async function getManifest(version: ManifestVersion = 'v2') {
manifest.permissions?.push('webNavigation')

// this is required on dev for Vite script to load
// eslint-disable-next-line no-useless-escape
manifest.content_security_policy = `script-src \'self\' http://localhost:${port}; object-src \'self\'`
const policy = `script-src 'self' http://localhost:${port}; object-src 'self'`;
manifest.content_security_policy = isManifest3
? { 'extension_pages': policy }
: policy
}

return manifest
Expand Down
2 changes: 1 addition & 1 deletion src/utils/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export const PopupPage: PageController = {
url: extensionURL,
type: 'popup',
top: 0,
left: screen.width - 400,
left: screen ? screen.width - 400 : 0,
width: 400,
height: 600
};
Expand Down
34 changes: 34 additions & 0 deletions vite.config.background.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { defineConfig } from 'vite'
import { sharedConfig } from './vite.config'
import { isDev, r } from './scripts/utils'
import packageJson from './package.json'

// bundling the content script using Vite
export default defineConfig({
...sharedConfig,
define: {
'__DEV__': isDev,
// https://github.com/vitejs/vite/issues/9320
// https://github.com/vitejs/vite/issues/9186
'process.env.NODE_ENV': JSON.stringify(isDev ? 'development' : 'production')
},
build: {
watch: isDev
? {}
: undefined,
outDir: r('extension/dist/background'),
emptyOutDir: false,
sourcemap: isDev ? 'inline' : false,
lib: {
entry: r('src/background/index.ts'),
name: packageJson.name,
formats: [ 'iife' ]
},
rollupOptions: {
output: {
entryFileNames: 'index.js',
extend: true
}
}
}
})
4 changes: 2 additions & 2 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Layouts from 'vite-plugin-vue-layouts'
import Components from 'unplugin-vue-components/vite'
import AutoImport from 'unplugin-auto-import/vite'
import UnoCSS from 'unocss/vite'
import { isDev, port, r } from './scripts/utils'
import { isDev, port, r, isManifest3 } from './scripts/utils'

export const sharedConfig: UserConfig = {
root: r('src'),
Expand Down Expand Up @@ -89,7 +89,7 @@ export default defineConfig(({ command }) => ({
},
rollupOptions: {
input: {
background: r('src/background/index.html'),
...(isManifest3 ? {} : { background: r('src/background/index.html') }), // add the background if it's not manifest v3
options: r('src/options/index.html'),
popup: r('src/popup/index.html')
}
Expand Down

0 comments on commit 0074e97

Please sign in to comment.