first commit
This commit is contained in:
commit
46aea254d0
19 changed files with 569 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
.env
|
||||||
57
README.md
Normal file
57
README.md
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
# Figma Windows UA Spoofer (Chrome + Firefox)
|
||||||
|
|
||||||
|
`figma.com` / `*.figma.com`에서만 User-Agent를 Windows로 바꾸고,
|
||||||
|
페이지 JS의 `navigator.userAgent`, `navigator.platform`도 Windows 값으로 오버라이드합니다.
|
||||||
|
|
||||||
|
## 빠른 사용
|
||||||
|
|
||||||
|
### Chrome / Edge
|
||||||
|
|
||||||
|
1. `chrome://extensions` (Edge: `edge://extensions`) 접속
|
||||||
|
2. 개발자 모드 ON
|
||||||
|
3. 압축해제된 확장 프로그램 로드
|
||||||
|
4. 프로젝트 폴더 선택
|
||||||
|
|
||||||
|
### Firefox unsigned 빌드
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./build-firefox.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
- 출력: `dist/figma-windows-ua-firefox-unsigned.xpi`
|
||||||
|
- 개발/테스트용 unsigned 패키지
|
||||||
|
|
||||||
|
### Firefox 서명 빌드 (실사용)
|
||||||
|
|
||||||
|
1. AMO(Add-ons Mozilla)에서 API Key/Secret 발급
|
||||||
|
2. `.env`에 값 저장 (자동 로드)
|
||||||
|
|
||||||
|
```dotenv
|
||||||
|
AMO_JWT_ISSUER="<your-api-key>"
|
||||||
|
AMO_JWT_SECRET="<your-api-secret>"
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Nix로 서명 실행 (추천)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix run .#sign-firefox
|
||||||
|
```
|
||||||
|
|
||||||
|
- 출력: `dist/signed/*.xpi` (서명 완료)
|
||||||
|
|
||||||
|
## Firefox 설치
|
||||||
|
|
||||||
|
- 임시 로드: `about:debugging#/runtime/this-firefox` → 임시 부가 기능 로드 → `dist/firefox/manifest.json`
|
||||||
|
- 실제 배포/설치: `dist/signed/*.xpi` 사용
|
||||||
|
|
||||||
|
## 확인
|
||||||
|
|
||||||
|
`figma.com`에서 콘솔 실행:
|
||||||
|
|
||||||
|
```js
|
||||||
|
navigator.userAgent
|
||||||
|
navigator.platform
|
||||||
|
navigator.userAgentData?.platform
|
||||||
|
```
|
||||||
|
|
||||||
|
Windows 계열 값이면 정상입니다.
|
||||||
29
background.firefox.js
Normal file
29
background.firefox.js
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
const WINDOWS_UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.7444.163 Safari/537.36';
|
||||||
|
|
||||||
|
browser.webRequest.onBeforeSendHeaders.addListener(
|
||||||
|
(details) => {
|
||||||
|
const headers = details.requestHeaders || [];
|
||||||
|
let found = false;
|
||||||
|
|
||||||
|
for (const header of headers) {
|
||||||
|
if (header.name && header.name.toLowerCase() === 'user-agent') {
|
||||||
|
header.value = WINDOWS_UA;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
headers.push({ name: 'User-Agent', value: WINDOWS_UA });
|
||||||
|
}
|
||||||
|
|
||||||
|
return { requestHeaders: headers };
|
||||||
|
},
|
||||||
|
{
|
||||||
|
urls: [
|
||||||
|
'https://figma.com/*',
|
||||||
|
'https://*.figma.com/*'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
['blocking', 'requestHeaders']
|
||||||
|
);
|
||||||
25
build-firefox.sh
Executable file
25
build-firefox.sh
Executable file
|
|
@ -0,0 +1,25 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
DIST_DIR="$ROOT_DIR/dist/firefox"
|
||||||
|
XPI_PATH="$ROOT_DIR/dist/figma-windows-ua-firefox-unsigned.xpi"
|
||||||
|
|
||||||
|
rm -rf "$DIST_DIR"
|
||||||
|
mkdir -p "$DIST_DIR"
|
||||||
|
|
||||||
|
rm -f "$ROOT_DIR/dist/figma-windows-ua-firefox.xpi"
|
||||||
|
rm -f "$ROOT_DIR/dist/figma-windows-ua-firefox.zip"
|
||||||
|
|
||||||
|
cp "$ROOT_DIR/manifest.firefox.json" "$DIST_DIR/manifest.json"
|
||||||
|
cp "$ROOT_DIR/background.firefox.js" "$DIST_DIR/background.firefox.js"
|
||||||
|
cp "$ROOT_DIR/content.js" "$DIST_DIR/content.js"
|
||||||
|
cp "$ROOT_DIR/injected.js" "$DIST_DIR/injected.js"
|
||||||
|
|
||||||
|
rm -f "$XPI_PATH"
|
||||||
|
(
|
||||||
|
cd "$DIST_DIR"
|
||||||
|
zip -r "$XPI_PATH" .
|
||||||
|
)
|
||||||
|
|
||||||
|
echo "Firefox build created: $XPI_PATH"
|
||||||
6
content.js
Normal file
6
content.js
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
(() => {
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.src = chrome.runtime.getURL('injected.js');
|
||||||
|
script.onload = () => script.remove();
|
||||||
|
(document.head || document.documentElement).appendChild(script);
|
||||||
|
})();
|
||||||
BIN
dist/figma-windows-ua-firefox-unsigned.xpi
vendored
Normal file
BIN
dist/figma-windows-ua-firefox-unsigned.xpi
vendored
Normal file
Binary file not shown.
1
dist/firefox/.amo-upload-uuid
vendored
Normal file
1
dist/firefox/.amo-upload-uuid
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
{"uploadUuid":"b4b16a82abdb4ce5850b5d0deb76ef3b","channel":"unlisted","xpiCrcHash":"e5567d47cfb9f6133110396308a37ed42afc5be51f6b047ae4643d3f5f063591"}
|
||||||
29
dist/firefox/background.firefox.js
vendored
Normal file
29
dist/firefox/background.firefox.js
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
const WINDOWS_UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.7444.163 Safari/537.36';
|
||||||
|
|
||||||
|
browser.webRequest.onBeforeSendHeaders.addListener(
|
||||||
|
(details) => {
|
||||||
|
const headers = details.requestHeaders || [];
|
||||||
|
let found = false;
|
||||||
|
|
||||||
|
for (const header of headers) {
|
||||||
|
if (header.name && header.name.toLowerCase() === 'user-agent') {
|
||||||
|
header.value = WINDOWS_UA;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
headers.push({ name: 'User-Agent', value: WINDOWS_UA });
|
||||||
|
}
|
||||||
|
|
||||||
|
return { requestHeaders: headers };
|
||||||
|
},
|
||||||
|
{
|
||||||
|
urls: [
|
||||||
|
'https://figma.com/*',
|
||||||
|
'https://*.figma.com/*'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
['blocking', 'requestHeaders']
|
||||||
|
);
|
||||||
6
dist/firefox/content.js
vendored
Normal file
6
dist/firefox/content.js
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
(() => {
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.src = chrome.runtime.getURL('injected.js');
|
||||||
|
script.onload = () => script.remove();
|
||||||
|
(document.head || document.documentElement).appendChild(script);
|
||||||
|
})();
|
||||||
62
dist/firefox/injected.js
vendored
Normal file
62
dist/firefox/injected.js
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
(() => {
|
||||||
|
const windowsUA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.7444.163 Safari/537.36';
|
||||||
|
const appVersion = '5.0 (Windows)';
|
||||||
|
|
||||||
|
const override = (obj, key, value) => {
|
||||||
|
try {
|
||||||
|
Object.defineProperty(obj, key, {
|
||||||
|
get: () => value,
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
override(Navigator.prototype, 'userAgent', windowsUA);
|
||||||
|
override(Navigator.prototype, 'appVersion', appVersion);
|
||||||
|
override(Navigator.prototype, 'platform', 'Win32');
|
||||||
|
override(Navigator.prototype, 'oscpu', 'Windows NT 10.0; Win64; x64');
|
||||||
|
|
||||||
|
if (navigator.userAgentData) {
|
||||||
|
const uaData = {
|
||||||
|
brands: [
|
||||||
|
{ brand: 'Chromium', version: '142' },
|
||||||
|
{ brand: 'Google Chrome', version: '142' }
|
||||||
|
],
|
||||||
|
mobile: false,
|
||||||
|
platform: 'Windows',
|
||||||
|
getHighEntropyValues: async (hints) => {
|
||||||
|
const result = {
|
||||||
|
architecture: 'x86',
|
||||||
|
bitness: '64',
|
||||||
|
mobile: false,
|
||||||
|
model: '',
|
||||||
|
platform: 'Windows',
|
||||||
|
platformVersion: '10.0.0',
|
||||||
|
uaFullVersion: '142.0.7444.163',
|
||||||
|
wow64: false
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Array.isArray(hints)) {
|
||||||
|
return hints.reduce((acc, hint) => {
|
||||||
|
if (hint in result) acc[hint] = result[hint];
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
toJSON: () => ({
|
||||||
|
brands: [
|
||||||
|
{ brand: 'Chromium', version: '142' },
|
||||||
|
{ brand: 'Google Chrome', version: '142' }
|
||||||
|
],
|
||||||
|
mobile: false,
|
||||||
|
platform: 'Windows'
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
override(Navigator.prototype, 'userAgentData', uaData);
|
||||||
|
}
|
||||||
|
})();
|
||||||
38
dist/firefox/manifest.json
vendored
Normal file
38
dist/firefox/manifest.json
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"manifest_version": 2,
|
||||||
|
"name": "Figma Windows UA Spoofer",
|
||||||
|
"description": "Spoof Windows User-Agent and platform on figma.com",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"applications": {
|
||||||
|
"gecko": {
|
||||||
|
"id": "figma-windows-ua-spoofer@imnyang.local",
|
||||||
|
"strict_min_version": "109.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"permissions": [
|
||||||
|
"webRequest",
|
||||||
|
"webRequestBlocking",
|
||||||
|
"https://figma.com/*",
|
||||||
|
"https://*.figma.com/*"
|
||||||
|
],
|
||||||
|
"background": {
|
||||||
|
"scripts": [
|
||||||
|
"background.firefox.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"content_scripts": [
|
||||||
|
{
|
||||||
|
"matches": [
|
||||||
|
"https://figma.com/*",
|
||||||
|
"https://*.figma.com/*"
|
||||||
|
],
|
||||||
|
"js": [
|
||||||
|
"content.js"
|
||||||
|
],
|
||||||
|
"run_at": "document_start"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"web_accessible_resources": [
|
||||||
|
"injected.js"
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
dist/signed/d168a70cb6a24fe4a478-1.0.0.xpi
vendored
Normal file
BIN
dist/signed/d168a70cb6a24fe4a478-1.0.0.xpi
vendored
Normal file
Binary file not shown.
61
flake.lock
generated
Normal file
61
flake.lock
generated
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731533236,
|
||||||
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1772542754,
|
||||||
|
"narHash": "sha256-WGV2hy+VIeQsYXpsLjdr4GvHv5eECMISX1zKLTedhdg=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "8c809a146a140c5c8806f13399592dbcb1bb5dc4",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
32
flake.nix
Normal file
32
flake.nix
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
description = "Figma Windows UA Spoofer - Firefox signing environment";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, flake-utils }:
|
||||||
|
flake-utils.lib.eachDefaultSystem (system:
|
||||||
|
let
|
||||||
|
pkgs = import nixpkgs { inherit system; };
|
||||||
|
in
|
||||||
|
{
|
||||||
|
devShells.default = pkgs.mkShell {
|
||||||
|
packages = with pkgs; [
|
||||||
|
bash
|
||||||
|
zip
|
||||||
|
web-ext
|
||||||
|
nodejs
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
apps.sign-firefox = {
|
||||||
|
type = "app";
|
||||||
|
program = toString (pkgs.writeShellScript "sign-firefox" ''
|
||||||
|
set -euo pipefail
|
||||||
|
exec ${pkgs.bash}/bin/bash ./sign-firefox.sh
|
||||||
|
'');
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
62
injected.js
Normal file
62
injected.js
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
(() => {
|
||||||
|
const windowsUA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.7444.163 Safari/537.36';
|
||||||
|
const appVersion = '5.0 (Windows)';
|
||||||
|
|
||||||
|
const override = (obj, key, value) => {
|
||||||
|
try {
|
||||||
|
Object.defineProperty(obj, key, {
|
||||||
|
get: () => value,
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
override(Navigator.prototype, 'userAgent', windowsUA);
|
||||||
|
override(Navigator.prototype, 'appVersion', appVersion);
|
||||||
|
override(Navigator.prototype, 'platform', 'Win32');
|
||||||
|
override(Navigator.prototype, 'oscpu', 'Windows NT 10.0; Win64; x64');
|
||||||
|
|
||||||
|
if (navigator.userAgentData) {
|
||||||
|
const uaData = {
|
||||||
|
brands: [
|
||||||
|
{ brand: 'Chromium', version: '142' },
|
||||||
|
{ brand: 'Google Chrome', version: '142' }
|
||||||
|
],
|
||||||
|
mobile: false,
|
||||||
|
platform: 'Windows',
|
||||||
|
getHighEntropyValues: async (hints) => {
|
||||||
|
const result = {
|
||||||
|
architecture: 'x86',
|
||||||
|
bitness: '64',
|
||||||
|
mobile: false,
|
||||||
|
model: '',
|
||||||
|
platform: 'Windows',
|
||||||
|
platformVersion: '10.0.0',
|
||||||
|
uaFullVersion: '142.0.7444.163',
|
||||||
|
wow64: false
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Array.isArray(hints)) {
|
||||||
|
return hints.reduce((acc, hint) => {
|
||||||
|
if (hint in result) acc[hint] = result[hint];
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
toJSON: () => ({
|
||||||
|
brands: [
|
||||||
|
{ brand: 'Chromium', version: '142' },
|
||||||
|
{ brand: 'Google Chrome', version: '142' }
|
||||||
|
],
|
||||||
|
mobile: false,
|
||||||
|
platform: 'Windows'
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
override(Navigator.prototype, 'userAgentData', uaData);
|
||||||
|
}
|
||||||
|
})();
|
||||||
38
manifest.firefox.json
Normal file
38
manifest.firefox.json
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"manifest_version": 2,
|
||||||
|
"name": "Figma Windows UA Spoofer",
|
||||||
|
"description": "Spoof Windows User-Agent and platform on figma.com",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"applications": {
|
||||||
|
"gecko": {
|
||||||
|
"id": "figma-windows-ua-spoofer@imnyang.local",
|
||||||
|
"strict_min_version": "109.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"permissions": [
|
||||||
|
"webRequest",
|
||||||
|
"webRequestBlocking",
|
||||||
|
"https://figma.com/*",
|
||||||
|
"https://*.figma.com/*"
|
||||||
|
],
|
||||||
|
"background": {
|
||||||
|
"scripts": [
|
||||||
|
"background.firefox.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"content_scripts": [
|
||||||
|
{
|
||||||
|
"matches": [
|
||||||
|
"https://figma.com/*",
|
||||||
|
"https://*.figma.com/*"
|
||||||
|
],
|
||||||
|
"js": [
|
||||||
|
"content.js"
|
||||||
|
],
|
||||||
|
"run_at": "document_start"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"web_accessible_resources": [
|
||||||
|
"injected.js"
|
||||||
|
]
|
||||||
|
}
|
||||||
45
manifest.json
Normal file
45
manifest.json
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
{
|
||||||
|
"manifest_version": 3,
|
||||||
|
"name": "Figma Windows UA Spoofer",
|
||||||
|
"description": "Spoof Windows User-Agent and platform on figma.com",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"permissions": [
|
||||||
|
"declarativeNetRequest"
|
||||||
|
],
|
||||||
|
"host_permissions": [
|
||||||
|
"https://figma.com/*",
|
||||||
|
"https://*.figma.com/*"
|
||||||
|
],
|
||||||
|
"declarative_net_request": {
|
||||||
|
"rule_resources": [
|
||||||
|
{
|
||||||
|
"id": "ruleset_1",
|
||||||
|
"enabled": true,
|
||||||
|
"path": "rules.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"content_scripts": [
|
||||||
|
{
|
||||||
|
"matches": [
|
||||||
|
"https://figma.com/*",
|
||||||
|
"https://*.figma.com/*"
|
||||||
|
],
|
||||||
|
"js": [
|
||||||
|
"content.js"
|
||||||
|
],
|
||||||
|
"run_at": "document_start"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"web_accessible_resources": [
|
||||||
|
{
|
||||||
|
"resources": [
|
||||||
|
"injected.js"
|
||||||
|
],
|
||||||
|
"matches": [
|
||||||
|
"https://figma.com/*",
|
||||||
|
"https://*.figma.com/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
30
rules.json
Normal file
30
rules.json
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"priority": 1,
|
||||||
|
"action": {
|
||||||
|
"type": "modifyHeaders",
|
||||||
|
"requestHeaders": [
|
||||||
|
{
|
||||||
|
"header": "User-Agent",
|
||||||
|
"operation": "set",
|
||||||
|
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.7444.163 Safari/537.36"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"condition": {
|
||||||
|
"regexFilter": "^https:\\/\\/([a-zA-Z0-9-]+\\.)*figma\\.com\\/",
|
||||||
|
"resourceTypes": [
|
||||||
|
"main_frame",
|
||||||
|
"sub_frame",
|
||||||
|
"xmlhttprequest",
|
||||||
|
"script",
|
||||||
|
"image",
|
||||||
|
"font",
|
||||||
|
"stylesheet",
|
||||||
|
"media",
|
||||||
|
"other"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
47
sign-firefox.sh
Executable file
47
sign-firefox.sh
Executable file
|
|
@ -0,0 +1,47 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
SOURCE_DIR="$ROOT_DIR/dist/firefox"
|
||||||
|
SIGNED_DIR="$ROOT_DIR/dist/signed"
|
||||||
|
|
||||||
|
if [ -f "$ROOT_DIR/.env" ]; then
|
||||||
|
set -a
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
. "$ROOT_DIR/.env"
|
||||||
|
set +a
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${AMO_JWT_ISSUER:-}" ] || [ -z "${AMO_JWT_SECRET:-}" ]; then
|
||||||
|
echo "AMO_JWT_ISSUER / AMO_JWT_SECRET 값이 필요합니다."
|
||||||
|
echo "(.env 또는 환경변수에서 읽습니다)"
|
||||||
|
echo "예:"
|
||||||
|
echo " export AMO_JWT_ISSUER=\"<your-api-key>\""
|
||||||
|
echo " export AMO_JWT_SECRET=\"<your-api-secret>\""
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$ROOT_DIR/build-firefox.sh"
|
||||||
|
mkdir -p "$SIGNED_DIR"
|
||||||
|
|
||||||
|
if command -v web-ext >/dev/null 2>&1; then
|
||||||
|
web-ext sign \
|
||||||
|
--source-dir "$SOURCE_DIR" \
|
||||||
|
--artifacts-dir "$SIGNED_DIR" \
|
||||||
|
--api-key "$AMO_JWT_ISSUER" \
|
||||||
|
--api-secret "$AMO_JWT_SECRET" \
|
||||||
|
--channel unlisted
|
||||||
|
elif command -v npx >/dev/null 2>&1; then
|
||||||
|
npx --yes web-ext sign \
|
||||||
|
--source-dir "$SOURCE_DIR" \
|
||||||
|
--artifacts-dir "$SIGNED_DIR" \
|
||||||
|
--api-key "$AMO_JWT_ISSUER" \
|
||||||
|
--api-secret "$AMO_JWT_SECRET" \
|
||||||
|
--channel unlisted
|
||||||
|
else
|
||||||
|
echo "web-ext 또는 npx가 필요합니다."
|
||||||
|
echo "Nix 사용 시: nix develop -c ./sign-firefox.sh"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Signed XPI generated under: $SIGNED_DIR"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue