78 lines
2.1 KiB
JavaScript
78 lines
2.1 KiB
JavaScript
|
|
/**
|
||
|
|
* 按 sessionKey 解析持久 Chrome Profile 目录
|
||
|
|
*/
|
||
|
|
const fs = require('fs');
|
||
|
|
const path = require('path');
|
||
|
|
const crypto = require('crypto');
|
||
|
|
const { RUNTIME_DIR, PERSIST_BROWSER_PROFILE, PROFILE_MAX_AGE_MS } = require('./constants');
|
||
|
|
|
||
|
|
const PROFILES_DIR = path.join(RUNTIME_DIR, 'profiles');
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param {string} sessionKey
|
||
|
|
* @param {'standard'|'real'} profile
|
||
|
|
* @returns {string|null}
|
||
|
|
*/
|
||
|
|
function resolveProfileDir(sessionKey, profile = 'standard') {
|
||
|
|
if (!sessionKey || !PERSIST_BROWSER_PROFILE) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
const hash = crypto.createHash('md5').update(String(sessionKey)).digest('hex');
|
||
|
|
const dir = path.join(PROFILES_DIR, `${hash}-${profile}`);
|
||
|
|
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
||
|
|
return dir;
|
||
|
|
}
|
||
|
|
|
||
|
|
function profileExists(sessionKey, profile = 'standard') {
|
||
|
|
const dir = resolveProfileDir(sessionKey, profile);
|
||
|
|
if (!dir) return false;
|
||
|
|
return fs.existsSync(dir);
|
||
|
|
}
|
||
|
|
|
||
|
|
function pruneStaleProfiles() {
|
||
|
|
if (!PERSIST_BROWSER_PROFILE || PROFILE_MAX_AGE_MS <= 0) {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
if (!fs.existsSync(PROFILES_DIR)) {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
const now = Date.now();
|
||
|
|
let removed = 0;
|
||
|
|
for (const name of fs.readdirSync(PROFILES_DIR)) {
|
||
|
|
const full = path.join(PROFILES_DIR, name);
|
||
|
|
try {
|
||
|
|
const stat = fs.statSync(full);
|
||
|
|
if (!stat.isDirectory()) continue;
|
||
|
|
if (now - stat.mtimeMs > PROFILE_MAX_AGE_MS) {
|
||
|
|
fs.rmSync(full, { recursive: true, force: true });
|
||
|
|
removed++;
|
||
|
|
}
|
||
|
|
} catch (_) {
|
||
|
|
/* ignore */
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return removed;
|
||
|
|
}
|
||
|
|
|
||
|
|
function getProfileStats() {
|
||
|
|
if (!fs.existsSync(PROFILES_DIR)) {
|
||
|
|
return { profilesDir: PROFILES_DIR, count: 0 };
|
||
|
|
}
|
||
|
|
const count = fs.readdirSync(PROFILES_DIR).filter((name) => {
|
||
|
|
try {
|
||
|
|
return fs.statSync(path.join(PROFILES_DIR, name)).isDirectory();
|
||
|
|
} catch (_) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}).length;
|
||
|
|
return { profilesDir: PROFILES_DIR, count };
|
||
|
|
}
|
||
|
|
|
||
|
|
module.exports = {
|
||
|
|
PROFILES_DIR,
|
||
|
|
resolveProfileDir,
|
||
|
|
profileExists,
|
||
|
|
pruneStaleProfiles,
|
||
|
|
getProfileStats,
|
||
|
|
};
|