Skip to content

Commit

Permalink
Add random user-agent
Browse files Browse the repository at this point in the history
  • Loading branch information
Oein committed Jun 28, 2024
1 parent 894332c commit 57d5d1a
Show file tree
Hide file tree
Showing 8 changed files with 293 additions and 9 deletions.
27 changes: 18 additions & 9 deletions electron/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { session } from "electron";
import { join } from "path";
import { MenuBase } from "./menuTemplate";

const UserAgent =
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36";
import generateRandomAgent from "./user-agent/index";
const uadata = generateRandomAgent();

protocol.registerSchemesAsPrivileged([
{
Expand Down Expand Up @@ -133,11 +133,16 @@ const createWindow = async () => {
});

session.defaultSession.webRequest.onBeforeSendHeaders((details, callback) => {
details.requestHeaders["User-Agent"] = UserAgent;
details.requestHeaders["Sec-CH-UA-Platform"] = '"macOS"';
details.requestHeaders["Sec-Ch-Ua-Mobile"] = "?0";
details.requestHeaders["Sec-CH-UA"] =
'"Not/A)Brand";v="8", "Chromium";v="126"';
for (const operation of uadata.dt) {
for (const header of operation.action.requestHeaders) {
if (header.operation == "remove") {
delete details.requestHeaders[header.header];
}
if (header.operation == "set") {
details.requestHeaders[header.header] = header.value!;
}
}
}
callback({ cancel: false, requestHeaders: details.requestHeaders });
});

Expand All @@ -148,7 +153,7 @@ const createWindow = async () => {
height: 800,
webPreferences: { nodeIntegration: true, contextIsolation: false },
});
chzzkWindow.webContents.setUserAgent(UserAgent);
chzzkWindow.webContents.setUserAgent(uadata.ua);
chzzkWindow.loadFile(join(__dirname, "..", "static", "loading.html"));

// =============================================
Expand All @@ -164,7 +169,11 @@ const createWindow = async () => {

// =============================================

session.defaultSession.loadExtension(join(configDir, "extension"));
if (true)
session.defaultSession.loadExtension(
join(__dirname, "..", "..", "extension", "dist-electron")
);
else session.defaultSession.loadExtension(join(configDir, "extension"));

// =============================================

Expand Down
3 changes: 3 additions & 0 deletions electron/src/user-agent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Notice

> [tarampampam/random-user-agent](https://github.com/tarampampam/random-user-agent/tree/master)에서 많은 코드를 가져왔습니다. 고마워요 [tarampampam](https://github.com/tarampampam)!
88 changes: 88 additions & 0 deletions electron/src/user-agent/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import apply from "./steps/apply";
const fromRange = (min: number, max: number): number => {
min = Math.ceil(min);

return Math.floor(Math.random() * (Math.floor(max) - min + 1)) + min;
};
export default function generateRandomAgent() {
const macOSVersions = [
"14.6",
"14.5",
"14.4",
"14.3",
"14.2",
"14.1",
"14",
"13.7",
"13.6",
"13.5",
"13.4",
"13.3",
"13.2",
"13.1",
"13",
"12.6",
"12.5",
"12.4",
"12.3",
"12.2",
"12.1",
"12.0",
"11.3",
"11.2",
"11.1",
"11",
"10_13",
"10",
];
const genChromeVersion = (
maxMajor?: number,
majorDelta: number = 2
): [major: number, full: string] => {
const variants = {
major: { min: 122, max: 124 }, // 👈 periodically we should update those values
patch: { min: 6261, max: 6356 }, // 👈 same here
build: { min: 194, max: 226 }, // 👈 and here
};

if (maxMajor) {
variants.major.max = Math.max(maxMajor, 0);
variants.major.min = Math.max(maxMajor - majorDelta, 0);
}

const major = fromRange(variants.major.min, variants.major.max);

return [
major,
`${major}.0.${fromRange(
variants.patch.min,
variants.patch.max
)}.${fromRange(variants.build.min, variants.build.max)}`,
];
};
const chromeVersion = genChromeVersion();
const ua = [
"Mozilla/5.0",
`(Macintosh; Intel Mac OS X ${
macOSVersions[fromRange(0, macOSVersions.length - 1)]
})`,
"AppleWebKit/537.36",
"(KHTML, like Gecko)",
`Chrome/${chromeVersion[1]}`,
"Safari/537.36",
].join(" ");

const dt = apply({
browser: "chrome",
os: "macOS",
userAgent: ua,
version: {
browser: {
full: chromeVersion[1],
major: chromeVersion[0],
},
},
});

return { ua, dt };
}
126 changes: 126 additions & 0 deletions electron/src/user-agent/steps/apply.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { UAConfig } from "../types";
import extractBrandsWithMajor from "./brands/brandsWithMajor";
import extractBrandsWithFull from "./brands/brandsWithFull";

// copy-paste of chrome.declarativeNetRequest.RuleActionType type (FireFox v124 does not have it)
// https://developer.chrome.com/docs/extensions/reference/api/declarativeNetRequest#type-RuleActionType
enum RuleActionType {
BLOCK = "block", // Block the network request
REDIRECT = "redirect", // Redirect the network request
ALLOW = "allow", // Allow the network request. The request won't be intercepted if there is an allow rule which matches it
UPGRADE_SCHEME = "upgradeScheme", // Upgrade the network request url's scheme to https if the request is http or ftp
MODIFY_HEADERS = "modifyHeaders", // Modify request/response headers from the network request
ALLOW_ALL_REQUESTS = "allowAllRequests", // Allow all requests within a frame hierarchy, including the frame request itself
}

// copy-paste of chrome.declarativeNetRequest.HeaderOperation type (FireFox v124 does not have it)
// https://developer.chrome.com/docs/extensions/reference/api/declarativeNetRequest#type-HeaderOperation
enum HeaderOperation {
SET = "set", // Sets a new value for the specified header, removing any existing headers with the same name
REMOVE = "remove", // Removes all entries for the specified header
}

// Note: the rule IDs must be unique, and do not change them after the extension is published.
// The rule IDs are used to remove the existing rules before adding new ones.
const RuleIDs: {
readonly [_ in
| "ReplaceUserAgent"
| "ReplaceClientHints"
| "ProvidePayload"
| "Cond2ReplaceUserAgent"
| "Cond2ReplaceClientHints"
| "Cond2ProvidePayload"]: number;
} = {
ReplaceUserAgent: 1,
ReplaceClientHints: 2,
ProvidePayload: 3,
Cond2ReplaceUserAgent: 4,
Cond2ReplaceClientHints: 5,
Cond2ProvidePayload: 6,
};

enum HeaderNames {
USER_AGENT = "User-Agent",
CLIENT_HINT_FULL_VERSION = "Sec-CH-UA-Full-Version", // deprecated, https://mzl.la/3g1NzEI
CLIENT_HINT_PLATFORM_VERSION = "Sec-CH-UA-Platform-Version", // https://mzl.la/3yyNXAY
CLIENT_HINT_BRAND_MAJOR = "Sec-CH-UA", // https://mzl.la/3EaQyoi
CLIENT_HINT_BRAND_FULL = "Sec-CH-UA-Full-Version-List", // https://mzl.la/3C3x5TT
CLIENT_HINT_PLATFORM = "Sec-CH-UA-Platform", // https://mzl.la/3EbrbTj
CLIENT_HINT_MOBILE = "Sec-CH-UA-Mobile", // https://mzl.la/3SYTA3f
SERVER_TIMING = "server-timing", // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing
}

export default function apply(config: UAConfig) {
const brandsWithMajor = extractBrandsWithMajor(config);
const brandsWithFull = extractBrandsWithFull(config);

const rules = [
{
id: RuleIDs.ReplaceUserAgent,
action: {
type: RuleActionType.MODIFY_HEADERS,
requestHeaders: [
{
operation: HeaderOperation.SET,
header: HeaderNames.USER_AGENT,
value: config.userAgent,
},
],
},
priority: 1,
},
{
id: RuleIDs.ReplaceClientHints,
priority: 1,
action: {
type: RuleActionType.MODIFY_HEADERS,
requestHeaders: [
brandsWithMajor.length
? {
operation: HeaderOperation.SET,
header: HeaderNames.CLIENT_HINT_BRAND_MAJOR,
value: brandsWithMajor
.map((b) => `"${b.brand}";v="${b.version}"`)
.join(", "),
}
: {
operation: HeaderOperation.REMOVE,
header: HeaderNames.CLIENT_HINT_BRAND_MAJOR,
},
brandsWithFull.length
? {
operation: HeaderOperation.SET,
header: HeaderNames.CLIENT_HINT_BRAND_FULL,
value: brandsWithFull
.map((b) => `"${b.brand}";v="${b.version}"`)
.join(", "),
}
: {
operation: HeaderOperation.REMOVE,
header: HeaderNames.CLIENT_HINT_BRAND_FULL,
},
{
operation: HeaderOperation.SET,
header: HeaderNames.CLIENT_HINT_PLATFORM,
value: `"macOS"`,
},
{
operation: HeaderOperation.SET,
header: HeaderNames.CLIENT_HINT_MOBILE,
value: "?0",
},
{
operation: HeaderOperation.REMOVE,
header: HeaderNames.CLIENT_HINT_FULL_VERSION,
},
{
operation: HeaderOperation.REMOVE,
header: HeaderNames.CLIENT_HINT_PLATFORM_VERSION,
},
],
},
},
];

return rules;
}
6 changes: 6 additions & 0 deletions electron/src/user-agent/steps/brands/brandsWithFull.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { UAConfig } from "../../types";
import extractBrands from "./extractBrands";

export default function brandsWithFull(config: UAConfig) {
return extractBrands(config, config.version.browser.full);
}
6 changes: 6 additions & 0 deletions electron/src/user-agent/steps/brands/brandsWithMajor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { UAConfig } from "../../types";
import extractBrands from "./extractBrands";

export default function brandsWithMajor(config: UAConfig) {
return extractBrands(config, config.version.browser.major);
}
32 changes: 32 additions & 0 deletions electron/src/user-agent/steps/brands/extractBrands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Brand, UAConfig } from "../../types";

export default function extractBrands(
config: UAConfig,
version: string | number
) {
const extractMajor = (full: string | number): string => {
if (typeof full !== "string") {
return Math.max(Math.floor(full === Infinity ? 0 : full), 0).toString();
}

const asNumber = parseInt(full.split(".")[0]);

return isNaN(asNumber) ? "0" : Math.max(asNumber, 0).toString();
};

const result: Array<Brand> = [
{
brand: "(Not(A:Brand",
version: typeof version === "string" ? "99.0.0.0" : "99",
}, // for every case
];

const chromeVersion: string = extractMajor(version);

result.push(
{ brand: "Google Chrome", version: chromeVersion },
{ brand: "Chromium", version: chromeVersion }
);

return result;
}
14 changes: 14 additions & 0 deletions electron/src/user-agent/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const exampleUAConfig = {
browser: "chrome",
os: "macOS",
userAgent:
"Mozilla/5.0 (Macintosh; Intel Mac OS X 12.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.6287.218 Safari/537.36",
version: {
browser: {
full: "124.0.6287.218",
major: 124,
},
},
};
export type UAConfig = typeof exampleUAConfig;
export type Brand = { brand: string; version: string };

0 comments on commit 57d5d1a

Please sign in to comment.