feat: add extension scaffolding
Manifest, package.json, tsconfig, webpack config, popup HTML shell, WASM type declarations, and .gitignore entries for the Chrome MV3 extension. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,3 +1,6 @@
|
|||||||
target/
|
target/
|
||||||
.superpowers/
|
.superpowers/
|
||||||
.worktrees/
|
.worktrees/
|
||||||
|
extension/node_modules/
|
||||||
|
extension/dist/
|
||||||
|
extension/wasm/
|
||||||
|
|||||||
28
extension/manifest.json
Normal file
28
extension/manifest.json
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"manifest_version": 3,
|
||||||
|
"name": "idfoto",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "Two-factor encrypted password manager",
|
||||||
|
"permissions": ["storage", "activeTab", "clipboardWrite"],
|
||||||
|
"host_permissions": ["<all_urls>"],
|
||||||
|
"background": {
|
||||||
|
"service_worker": "service-worker.js",
|
||||||
|
"type": "module"
|
||||||
|
},
|
||||||
|
"action": {
|
||||||
|
"default_popup": "popup.html",
|
||||||
|
"default_icon": {
|
||||||
|
"16": "icons/icon-16.png",
|
||||||
|
"48": "icons/icon-48.png",
|
||||||
|
"128": "icons/icon-128.png"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"content_scripts": [{
|
||||||
|
"matches": ["<all_urls>"],
|
||||||
|
"js": ["content.js"],
|
||||||
|
"run_at": "document_idle"
|
||||||
|
}],
|
||||||
|
"content_security_policy": {
|
||||||
|
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self'"
|
||||||
|
}
|
||||||
|
}
|
||||||
19
extension/package.json
Normal file
19
extension/package.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"name": "idfoto-extension",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"build": "webpack --mode production",
|
||||||
|
"dev": "webpack --mode development --watch",
|
||||||
|
"build:wasm": "wasm-pack build ../crates/idfoto-wasm --target web --out-dir ../../extension/wasm",
|
||||||
|
"build:all": "npm run build:wasm && npm run build"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/chrome": "^0.1.40",
|
||||||
|
"copy-webpack-plugin": "^12.0",
|
||||||
|
"ts-loader": "^9.5",
|
||||||
|
"typescript": "^5.4",
|
||||||
|
"webpack": "^5.90",
|
||||||
|
"webpack-cli": "^5.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
13
extension/src/popup/index.html
Normal file
13
extension/src/popup/index.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=360">
|
||||||
|
<link rel="stylesheet" href="styles.css">
|
||||||
|
<title>idfoto</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script src="popup.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
24
extension/src/wasm.d.ts
vendored
Normal file
24
extension/src/wasm.d.ts
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/// Type declarations for the idfoto WASM module produced by wasm-pack.
|
||||||
|
|
||||||
|
// Ambient module declarations for the WASM glue code.
|
||||||
|
// The module specifier must exactly match what's used in import statements.
|
||||||
|
|
||||||
|
declare module 'idfoto-wasm' {
|
||||||
|
export default function init(input?: string | URL): Promise<void>;
|
||||||
|
export function derive_master_key(
|
||||||
|
passphrase: string,
|
||||||
|
image_secret: Uint8Array,
|
||||||
|
salt: Uint8Array,
|
||||||
|
params_json: string,
|
||||||
|
): Uint8Array;
|
||||||
|
export function encrypt(plaintext: Uint8Array, key: Uint8Array): Uint8Array;
|
||||||
|
export function decrypt(ciphertext: Uint8Array, key: Uint8Array): Uint8Array;
|
||||||
|
export function extract_image_secret(jpeg_bytes: Uint8Array): Uint8Array;
|
||||||
|
export function encrypt_entry(entry_json: string, key: Uint8Array): Uint8Array;
|
||||||
|
export function decrypt_entry(ciphertext: Uint8Array, key: Uint8Array): string;
|
||||||
|
export function encrypt_manifest(manifest_json: string, key: Uint8Array): Uint8Array;
|
||||||
|
export function decrypt_manifest(ciphertext: Uint8Array, key: Uint8Array): string;
|
||||||
|
export function generate_totp(secret_base32: string, timestamp_secs: bigint): string;
|
||||||
|
export function generate_password(length: number): string;
|
||||||
|
export function generate_entry_id(): string;
|
||||||
|
}
|
||||||
19
extension/tsconfig.json
Normal file
19
extension/tsconfig.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2022",
|
||||||
|
"module": "ES2022",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"outDir": "./dist",
|
||||||
|
"rootDir": "./src",
|
||||||
|
"sourceMap": true,
|
||||||
|
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||||
|
"paths": {
|
||||||
|
"idfoto-wasm": ["./wasm/idfoto_wasm.js"]
|
||||||
|
},
|
||||||
|
"baseUrl": "."
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist", "wasm"]
|
||||||
|
}
|
||||||
34
extension/webpack.config.js
Normal file
34
extension/webpack.config.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const CopyPlugin = require('copy-webpack-plugin');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
entry: {
|
||||||
|
'service-worker': './src/service-worker/index.ts',
|
||||||
|
popup: './src/popup/popup.ts',
|
||||||
|
content: './src/content/detector.ts',
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
path: path.resolve(__dirname, 'dist'),
|
||||||
|
filename: '[name].js',
|
||||||
|
clean: true,
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.ts', '.js'],
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [{ test: /\.ts$/, use: 'ts-loader', exclude: /node_modules/ }],
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new CopyPlugin({
|
||||||
|
patterns: [
|
||||||
|
{ from: 'manifest.json', to: '.' },
|
||||||
|
{ from: 'src/popup/index.html', to: 'popup.html' },
|
||||||
|
{ from: 'src/popup/styles.css', to: 'styles.css' },
|
||||||
|
{ from: 'icons', to: 'icons' },
|
||||||
|
{ from: 'wasm/idfoto_wasm_bg.wasm', to: '.' },
|
||||||
|
{ from: 'wasm/idfoto_wasm.js', to: '.' },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
experiments: { asyncWebAssembly: true },
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user