@rvanbaalen/roxyproxy 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +658 -0
  3. package/dist/cli/banner.d.ts +6 -0
  4. package/dist/cli/banner.js +30 -0
  5. package/dist/cli/banner.js.map +1 -0
  6. package/dist/cli/commands/clear.d.ts +2 -0
  7. package/dist/cli/commands/clear.js +35 -0
  8. package/dist/cli/commands/clear.js.map +1 -0
  9. package/dist/cli/commands/proxy-off.d.ts +2 -0
  10. package/dist/cli/commands/proxy-off.js +19 -0
  11. package/dist/cli/commands/proxy-off.js.map +1 -0
  12. package/dist/cli/commands/proxy-on.d.ts +2 -0
  13. package/dist/cli/commands/proxy-on.js +20 -0
  14. package/dist/cli/commands/proxy-on.js.map +1 -0
  15. package/dist/cli/commands/request.d.ts +2 -0
  16. package/dist/cli/commands/request.js +23 -0
  17. package/dist/cli/commands/request.js.map +1 -0
  18. package/dist/cli/commands/requests.d.ts +2 -0
  19. package/dist/cli/commands/requests.js +46 -0
  20. package/dist/cli/commands/requests.js.map +1 -0
  21. package/dist/cli/commands/start.d.ts +2 -0
  22. package/dist/cli/commands/start.js +41 -0
  23. package/dist/cli/commands/start.js.map +1 -0
  24. package/dist/cli/commands/status.d.ts +2 -0
  25. package/dist/cli/commands/status.js +44 -0
  26. package/dist/cli/commands/status.js.map +1 -0
  27. package/dist/cli/commands/stop.d.ts +2 -0
  28. package/dist/cli/commands/stop.js +52 -0
  29. package/dist/cli/commands/stop.js.map +1 -0
  30. package/dist/cli/commands/trust-ca.d.ts +2 -0
  31. package/dist/cli/commands/trust-ca.js +134 -0
  32. package/dist/cli/commands/trust-ca.js.map +1 -0
  33. package/dist/cli/format.d.ts +3 -0
  34. package/dist/cli/format.js +112 -0
  35. package/dist/cli/format.js.map +1 -0
  36. package/dist/cli/index.d.ts +2 -0
  37. package/dist/cli/index.js +35 -0
  38. package/dist/cli/index.js.map +1 -0
  39. package/dist/cli/interactive.d.ts +1 -0
  40. package/dist/cli/interactive.js +408 -0
  41. package/dist/cli/interactive.js.map +1 -0
  42. package/dist/cli/system-proxy.d.ts +14 -0
  43. package/dist/cli/system-proxy.js +115 -0
  44. package/dist/cli/system-proxy.js.map +1 -0
  45. package/dist/server/api.d.ts +10 -0
  46. package/dist/server/api.js +109 -0
  47. package/dist/server/api.js.map +1 -0
  48. package/dist/server/config.d.ts +6 -0
  49. package/dist/server/config.js +66 -0
  50. package/dist/server/config.js.map +1 -0
  51. package/dist/server/events.d.ts +20 -0
  52. package/dist/server/events.js +49 -0
  53. package/dist/server/events.js.map +1 -0
  54. package/dist/server/index.d.ts +20 -0
  55. package/dist/server/index.js +91 -0
  56. package/dist/server/index.js.map +1 -0
  57. package/dist/server/proxy.d.ts +27 -0
  58. package/dist/server/proxy.js +245 -0
  59. package/dist/server/proxy.js.map +1 -0
  60. package/dist/server/ssl.d.ts +17 -0
  61. package/dist/server/ssl.js +88 -0
  62. package/dist/server/ssl.js.map +1 -0
  63. package/dist/shared/types.d.ts +53 -0
  64. package/dist/shared/types.js +10 -0
  65. package/dist/shared/types.js.map +1 -0
  66. package/dist/storage/cleanup.d.ts +11 -0
  67. package/dist/storage/cleanup.js +32 -0
  68. package/dist/storage/cleanup.js.map +1 -0
  69. package/dist/storage/db.d.ts +17 -0
  70. package/dist/storage/db.js +152 -0
  71. package/dist/storage/db.js.map +1 -0
  72. package/dist/ui/assets/index-C8qts74N.js +9 -0
  73. package/dist/ui/assets/index-CrfXQK5U.css +2 -0
  74. package/dist/ui/index.html +13 -0
  75. package/package.json +59 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-proxy.js","sourceRoot":"","sources":["../../src/cli/system-proxy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { Router } from 'express';
2
+ import type { Database } from '../storage/db.js';
3
+ import type { EventManager } from './events.js';
4
+ export interface ProxyControl {
5
+ getProxyRunning: () => boolean;
6
+ getProxyPort: () => number;
7
+ startProxy: () => Promise<void>;
8
+ stopProxy: () => Promise<void>;
9
+ }
10
+ export declare function createApiRouter(db: Database, events: EventManager, proxy: ProxyControl): Router;
@@ -0,0 +1,109 @@
1
+ import { Router } from 'express';
2
+ function serializeRecord(r) {
3
+ return {
4
+ ...r,
5
+ request_body: r.request_body ? Buffer.from(r.request_body).toString('base64') : null,
6
+ response_body: r.response_body ? Buffer.from(r.response_body).toString('base64') : null,
7
+ };
8
+ }
9
+ export function createApiRouter(db, events, proxy) {
10
+ const router = Router();
11
+ const emitStatusEvent = () => {
12
+ events.emitStatus({
13
+ running: proxy.getProxyRunning(),
14
+ proxyPort: proxy.getProxyPort(),
15
+ });
16
+ };
17
+ router.get('/requests', (req, res) => {
18
+ const filter = {};
19
+ if (req.query.host)
20
+ filter.host = req.query.host;
21
+ if (req.query.status)
22
+ filter.status = parseInt(req.query.status, 10);
23
+ if (req.query.method)
24
+ filter.method = req.query.method;
25
+ if (req.query.content_type)
26
+ filter.content_type = req.query.content_type;
27
+ if (req.query.search)
28
+ filter.search = req.query.search;
29
+ if (req.query.since)
30
+ filter.since = parseInt(req.query.since, 10);
31
+ if (req.query.until)
32
+ filter.until = parseInt(req.query.until, 10);
33
+ if (req.query.limit)
34
+ filter.limit = parseInt(req.query.limit, 10);
35
+ if (req.query.offset)
36
+ filter.offset = parseInt(req.query.offset, 10);
37
+ const result = db.query(filter);
38
+ res.json({
39
+ ...result,
40
+ data: result.data.map(serializeRecord),
41
+ });
42
+ });
43
+ router.get('/requests/:id', (req, res) => {
44
+ const record = db.getById(req.params.id);
45
+ if (!record) {
46
+ res.status(404).json({ error: 'Not found' });
47
+ return;
48
+ }
49
+ res.json(serializeRecord(record));
50
+ });
51
+ router.delete('/requests', (_req, res) => {
52
+ db.deleteAll();
53
+ res.json({ ok: true });
54
+ });
55
+ router.get('/status', (_req, res) => {
56
+ res.json({
57
+ running: proxy.getProxyRunning(),
58
+ proxyPort: proxy.getProxyPort(),
59
+ requestCount: db.getRequestCount(),
60
+ dbSizeBytes: db.getDbSize(),
61
+ });
62
+ });
63
+ router.post('/proxy/start', async (_req, res) => {
64
+ try {
65
+ await proxy.startProxy();
66
+ emitStatusEvent();
67
+ res.json({ ok: true });
68
+ }
69
+ catch (err) {
70
+ res.status(500).json({ error: err.message });
71
+ }
72
+ });
73
+ router.post('/proxy/stop', async (_req, res) => {
74
+ try {
75
+ await proxy.stopProxy();
76
+ emitStatusEvent();
77
+ res.json({ ok: true });
78
+ }
79
+ catch (err) {
80
+ res.status(500).json({ error: err.message });
81
+ }
82
+ });
83
+ // Shutdown the entire server process
84
+ router.post('/shutdown', (_req, res) => {
85
+ res.json({ ok: true });
86
+ setTimeout(() => process.exit(0), 100);
87
+ });
88
+ router.get('/events', (req, res) => {
89
+ res.writeHead(200, {
90
+ 'Content-Type': 'text/event-stream',
91
+ 'Cache-Control': 'no-cache',
92
+ Connection: 'keep-alive',
93
+ });
94
+ const unsubRequest = events.subscribe((records) => {
95
+ for (const record of records) {
96
+ res.write(`event: request\nid: ${record.id}\ndata: ${JSON.stringify(serializeRecord(record))}\n\n`);
97
+ }
98
+ });
99
+ const unsubStatus = events.subscribeStatus((status) => {
100
+ res.write(`event: status\ndata: ${JSON.stringify(status)}\n\n`);
101
+ });
102
+ req.on('close', () => {
103
+ unsubRequest();
104
+ unsubStatus();
105
+ });
106
+ });
107
+ return router;
108
+ }
109
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/server/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { Config } from '../shared/types.js';
2
+ declare function expandHome(filePath: string): string;
3
+ declare function parseSize(value: string): number;
4
+ declare function parseDuration(value: string): number;
5
+ export declare function loadConfig(cliFlags?: Partial<Config>): Config;
6
+ export { expandHome, parseSize, parseDuration };
@@ -0,0 +1,66 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import os from 'node:os';
4
+ import { DEFAULT_CONFIG } from '../shared/types.js';
5
+ function expandHome(filePath) {
6
+ if (filePath.startsWith('~')) {
7
+ return path.join(os.homedir(), filePath.slice(1));
8
+ }
9
+ return filePath;
10
+ }
11
+ function parseSize(value) {
12
+ const match = value.match(/^(\d+)\s*(MB|GB|KB|B)?$/i);
13
+ if (!match)
14
+ return parseInt(value, 10);
15
+ const num = parseInt(match[1], 10);
16
+ const unit = (match[2] || 'B').toUpperCase();
17
+ const multipliers = {
18
+ B: 1, KB: 1024, MB: 1024 * 1024, GB: 1024 * 1024 * 1024,
19
+ };
20
+ return num * (multipliers[unit] || 1);
21
+ }
22
+ function parseDuration(value) {
23
+ const match = value.match(/^(\d+)\s*(ms|s|m|h|d)?$/i);
24
+ if (!match)
25
+ return parseInt(value, 10);
26
+ const num = parseInt(match[1], 10);
27
+ const unit = (match[2] || 'ms').toLowerCase();
28
+ const multipliers = {
29
+ ms: 1, s: 1000, m: 60000, h: 3600000, d: 86400000,
30
+ };
31
+ return num * (multipliers[unit] || 1);
32
+ }
33
+ export function loadConfig(cliFlags = {}) {
34
+ let fileConfig = {};
35
+ const configPath = expandHome('~/.roxyproxy/config.json');
36
+ if (fs.existsSync(configPath)) {
37
+ try {
38
+ const raw = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
39
+ fileConfig = {
40
+ proxyPort: raw.proxyPort,
41
+ uiPort: raw.uiPort,
42
+ dbPath: raw.dbPath,
43
+ maxAge: typeof raw.maxAge === 'string' ? parseDuration(raw.maxAge) : raw.maxAge,
44
+ maxDbSize: typeof raw.maxDbSize === 'string' ? parseSize(raw.maxDbSize) : raw.maxDbSize,
45
+ maxBodySize: typeof raw.maxBodySize === 'string' ? parseSize(raw.maxBodySize) : raw.maxBodySize,
46
+ certCacheSize: raw.certCacheSize,
47
+ };
48
+ for (const key of Object.keys(fileConfig)) {
49
+ if (fileConfig[key] === undefined)
50
+ delete fileConfig[key];
51
+ }
52
+ }
53
+ catch {
54
+ // Ignore invalid config file
55
+ }
56
+ }
57
+ const merged = {
58
+ ...DEFAULT_CONFIG,
59
+ ...fileConfig,
60
+ ...cliFlags,
61
+ };
62
+ merged.dbPath = expandHome(merged.dbPath);
63
+ return merged;
64
+ }
65
+ export { expandHome, parseSize, parseDuration };
66
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/server/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { RequestRecord } from '../shared/types.js';
2
+ export interface StatusEvent {
3
+ running: boolean;
4
+ proxyPort: number;
5
+ }
6
+ type RequestSubscriber = (events: RequestRecord[]) => void;
7
+ type StatusSubscriber = (status: StatusEvent) => void;
8
+ export declare class EventManager {
9
+ private requestSubscribers;
10
+ private statusSubscribers;
11
+ private buffer;
12
+ private timer;
13
+ push(record: RequestRecord): void;
14
+ emitStatus(status: StatusEvent): void;
15
+ private flush;
16
+ subscribe(fn: RequestSubscriber): () => void;
17
+ subscribeStatus(fn: StatusSubscriber): () => void;
18
+ stop(): void;
19
+ }
20
+ export {};
@@ -0,0 +1,49 @@
1
+ export class EventManager {
2
+ requestSubscribers = new Set();
3
+ statusSubscribers = new Set();
4
+ buffer = [];
5
+ timer = null;
6
+ push(record) {
7
+ this.buffer.push(record);
8
+ if (!this.timer) {
9
+ this.timer = setTimeout(() => this.flush(), 100);
10
+ }
11
+ }
12
+ emitStatus(status) {
13
+ for (const sub of this.statusSubscribers) {
14
+ try {
15
+ sub(status);
16
+ }
17
+ catch { }
18
+ }
19
+ }
20
+ flush() {
21
+ this.timer = null;
22
+ if (this.buffer.length === 0)
23
+ return;
24
+ const batch = this.buffer;
25
+ this.buffer = [];
26
+ for (const sub of this.requestSubscribers) {
27
+ try {
28
+ sub(batch);
29
+ }
30
+ catch { }
31
+ }
32
+ }
33
+ subscribe(fn) {
34
+ this.requestSubscribers.add(fn);
35
+ return () => { this.requestSubscribers.delete(fn); };
36
+ }
37
+ subscribeStatus(fn) {
38
+ this.statusSubscribers.add(fn);
39
+ return () => { this.statusSubscribers.delete(fn); };
40
+ }
41
+ stop() {
42
+ if (this.timer) {
43
+ clearTimeout(this.timer);
44
+ this.timer = null;
45
+ }
46
+ this.buffer = [];
47
+ }
48
+ }
49
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/server/events.ts"],"names":[],"mappings":"AAUA,MAAM,OAAO,YAAY;IACf,kBAAkB,GAA2B,IAAI,GAAG,EAAE,CAAC;IACvD,iBAAiB,GAA0B,IAAI,GAAG,EAAE,CAAC;IACrD,MAAM,GAAoB,EAAE,CAAC;IAC7B,KAAK,GAAyC,IAAI,CAAC;IAE3D,IAAI,CAAC,MAAqB;QACxB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,GAAG,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,UAAU,CAAC,MAAmB;QAC5B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzC,IAAI,CAAC;gBAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QAC/B,CAAC;IACH,CAAC;IAEO,KAAK;QACX,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1C,IAAI,CAAC;gBAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,SAAS,CAAC,EAAqB;QAC7B,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChC,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC;IAED,eAAe,CAAC,EAAoB;QAClC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/B,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;IACnB,CAAC;CACF"}
@@ -0,0 +1,20 @@
1
+ import type { Config } from '../shared/types.js';
2
+ export declare class RoxyProxyServer {
3
+ private config;
4
+ private db;
5
+ private ca;
6
+ private proxy;
7
+ private events;
8
+ private cleanup;
9
+ private apiServer;
10
+ private connections;
11
+ private proxyRunning;
12
+ private actualProxyPort;
13
+ constructor(config: Config);
14
+ start(): Promise<{
15
+ proxyPort: number;
16
+ uiPort: number;
17
+ }>;
18
+ get isProxyRunning(): boolean;
19
+ stop(): Promise<void>;
20
+ }
@@ -0,0 +1,91 @@
1
+ import express from 'express';
2
+ import path from 'node:path';
3
+ import { Database } from '../storage/db.js';
4
+ import { CertificateAuthority } from './ssl.js';
5
+ import { ProxyServer } from './proxy.js';
6
+ import { EventManager } from './events.js';
7
+ import { Cleanup } from '../storage/cleanup.js';
8
+ import { createApiRouter } from './api.js';
9
+ export class RoxyProxyServer {
10
+ config;
11
+ db;
12
+ ca;
13
+ proxy;
14
+ events;
15
+ cleanup;
16
+ apiServer = null;
17
+ connections = new Set();
18
+ proxyRunning = false;
19
+ actualProxyPort = 0;
20
+ constructor(config) {
21
+ this.config = config;
22
+ const caDir = path.join(path.dirname(config.dbPath), 'ca');
23
+ this.db = new Database(config.dbPath);
24
+ this.ca = new CertificateAuthority(caDir, config.certCacheSize);
25
+ this.events = new EventManager();
26
+ this.proxy = new ProxyServer(this.db, this.ca, this.events, config);
27
+ this.cleanup = new Cleanup(this.db, config);
28
+ }
29
+ async start() {
30
+ this.ca.init();
31
+ this.actualProxyPort = await this.proxy.start();
32
+ this.proxyRunning = true;
33
+ this.cleanup.start();
34
+ const app = express();
35
+ app.use(express.json());
36
+ const proxyControl = {
37
+ getProxyRunning: () => this.proxyRunning,
38
+ getProxyPort: () => this.actualProxyPort,
39
+ startProxy: async () => {
40
+ if (!this.proxyRunning) {
41
+ this.actualProxyPort = await this.proxy.start();
42
+ this.proxyRunning = true;
43
+ }
44
+ },
45
+ stopProxy: async () => {
46
+ if (this.proxyRunning) {
47
+ await this.proxy.stop();
48
+ this.proxyRunning = false;
49
+ }
50
+ },
51
+ };
52
+ app.use('/api', createApiRouter(this.db, this.events, proxyControl));
53
+ const uiDistPath = path.join(import.meta.dirname, '..', '..', 'dist', 'ui');
54
+ app.use(express.static(uiDistPath));
55
+ app.get('/{*path}', (_req, res) => {
56
+ res.sendFile(path.join(uiDistPath, 'index.html'));
57
+ });
58
+ const uiPort = await new Promise((resolve) => {
59
+ this.apiServer = app.listen(this.config.uiPort, () => {
60
+ const addr = this.apiServer.address();
61
+ resolve(addr.port);
62
+ });
63
+ this.apiServer.on('connection', (socket) => {
64
+ this.connections.add(socket);
65
+ socket.on('close', () => this.connections.delete(socket));
66
+ });
67
+ });
68
+ return { proxyPort: this.actualProxyPort, uiPort };
69
+ }
70
+ get isProxyRunning() {
71
+ return this.proxyRunning;
72
+ }
73
+ async stop() {
74
+ this.cleanup.stop();
75
+ this.events.stop();
76
+ if (this.proxyRunning) {
77
+ await this.proxy.stop();
78
+ this.proxyRunning = false;
79
+ }
80
+ if (this.apiServer) {
81
+ // Destroy lingering connections (SSE keep-alive, etc.)
82
+ for (const socket of this.connections) {
83
+ socket.destroy();
84
+ }
85
+ this.connections.clear();
86
+ await new Promise((resolve) => this.apiServer.close(() => resolve()));
87
+ }
88
+ this.db.close();
89
+ }
90
+ }
91
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { Database } from '../storage/db.js';
2
+ import type { CertificateAuthority } from './ssl.js';
3
+ import type { EventManager } from './events.js';
4
+ import type { Config } from '../shared/types.js';
5
+ export declare class ProxyServer {
6
+ private db;
7
+ private ca;
8
+ private events;
9
+ private config;
10
+ private server;
11
+ private sockets;
12
+ private writeQueue;
13
+ private writeTimer;
14
+ constructor(db: Database, ca: CertificateAuthority, events: EventManager, config: Config);
15
+ start(): Promise<number>;
16
+ stop(): Promise<void>;
17
+ get port(): number;
18
+ private flushWrites;
19
+ /**
20
+ * Strip accept-encoding from outgoing headers so the upstream server
21
+ * sends an uncompressed response. This avoids all decompression edge cases.
22
+ */
23
+ private stripEncoding;
24
+ private handleRequest;
25
+ private handleConnect;
26
+ private handleMitmRequest;
27
+ }