carom-link 1.0.0

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.
package/README.md ADDED
@@ -0,0 +1,221 @@
1
+ # carom
2
+
3
+ Link redirect server with bot and automated traffic protection, plus CLI management.
4
+
5
+ Wrap destination URLs behind your own clean domain. When a link is clicked, real humans get a fast 301 redirect. Automated scanners — carrier pre-fetchers, security crawlers, bot scrapers — see a benign safe page instead.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ # Global install
11
+ npm install -g carom
12
+
13
+ # Or use npx
14
+ npx carom start
15
+ ```
16
+
17
+ Requires Node.js ≥ 18.
18
+
19
+ ## Quick Start
20
+
21
+ ```bash
22
+ # Start the server
23
+ carom start --port 3000
24
+
25
+ # Create a link
26
+ carom add https://example.com/landing-page my-slug
27
+ # → http://localhost:3000/my-slug
28
+
29
+ # List your links
30
+ carom ls
31
+
32
+ # Check click analytics
33
+ carom stats my-slug
34
+ ```
35
+
36
+ ## How Bot Protection Works
37
+
38
+ Every request to a short link is scored by the detection engine:
39
+
40
+ | Signal | Weight | What it detects |
41
+ |--------|--------|-----------------|
42
+ | `ua_pattern` | +30 | Known bot/crawler User-Agent substrings (80+ patterns) |
43
+ | `ua_missing` | +15 | No User-Agent header at all |
44
+ | `headers_suspicious` | +20 | Missing Accept-Language, unusual Accept header |
45
+ | `datacenter_ip` | +25 | IP belongs to a cloud provider (AWS, GCP, Azure, etc.) |
46
+ | `timing_fast` | +15 | Click arrives <3s after link creation |
47
+ | `velocity_high` | +15 | Same slug hit 5+ times in 10s window |
48
+ | Custom rules | configurable | Your own UA patterns, IP ranges, or ASNs |
49
+
50
+ **Score ≥ 40 (default)** → Bot → Serve safe page (HTTP 200)
51
+ **Score < 40** → Human → 301 redirect to destination
52
+
53
+ ## CLI Reference
54
+
55
+ ```
56
+ carom <command> [options]
57
+
58
+ Commands:
59
+ start Start the redirect server
60
+ add <url> [slug] Create a new short link
61
+ ls List all links with click stats
62
+ rm <id|slug> Deactivate a link
63
+ stats <id|slug> Show detailed click analytics
64
+ rules ls List detection rules
65
+ rules add <pattern> Add custom bot pattern
66
+ rules rm <id> Remove a custom rule
67
+ rules test <ua> Test a user-agent string
68
+ config ls Show current config
69
+ config set <key> <val> Set a config value
70
+ config reset Reset to defaults
71
+ install Install as system service (auto-start on boot)
72
+ uninstall Remove system service
73
+ status Show server status
74
+ logs Tail server logs
75
+
76
+ Global Options:
77
+ --data-dir <path> Data directory (default: ~/.carom)
78
+ --port <number> Server port (default: 3000)
79
+ --host <addr> Bind address (default: localhost)
80
+ --api-key <key> API key for the REST API
81
+ -v, --verbose Verbose logging
82
+ ```
83
+
84
+ ## Service Management (Survives Reboots)
85
+
86
+ ```bash
87
+ # Install as a system service
88
+ carom install --port 3000 --api-key your-secret-key
89
+ # macOS: creates ~/Library/LaunchAgents/com.carom.plist
90
+ # Linux: creates /etc/systemd/system/carom.service
91
+
92
+ # Check status
93
+ carom status
94
+
95
+ # View logs
96
+ carom logs
97
+
98
+ # Remove service (keeps data)
99
+ carom uninstall
100
+ ```
101
+
102
+ ## REST API
103
+
104
+ All API endpoints require the `x-api-key` header (if an API key is configured).
105
+
106
+ ### Links
107
+
108
+ ```bash
109
+ # Create a link
110
+ curl -X POST http://localhost:3000/api/links \
111
+ -H "Content-Type: application/json" \
112
+ -H "x-api-key: your-key" \
113
+ -d '{"url": "https://example.com", "slug": "my-link"}'
114
+
115
+ # List links
116
+ curl http://localhost:3000/api/links -H "x-api-key: your-key"
117
+
118
+ # Get link stats
119
+ curl http://localhost:3000/api/links/1/stats -H "x-api-key: your-key"
120
+
121
+ # Delete link
122
+ curl -X DELETE http://localhost:3000/api/links/1 -H "x-api-key: your-key"
123
+ ```
124
+
125
+ ### Detection Rules
126
+
127
+ ```bash
128
+ # List rules
129
+ curl http://localhost:3000/api/rules -H "x-api-key: your-key"
130
+
131
+ # Add a custom rule
132
+ curl -X POST http://localhost:3000/api/rules \
133
+ -H "Content-Type: application/json" \
134
+ -H "x-api-key: your-key" \
135
+ -d '{"type": "ua_pattern", "pattern": "CarrierIQ", "weight": 30}'
136
+
137
+ # Test a user-agent
138
+ curl -X POST http://localhost:3000/api/rules/test \
139
+ -H "Content-Type: application/json" \
140
+ -H "x-api-key: your-key" \
141
+ -d '{"userAgent": "curl/8.0"}'
142
+ ```
143
+
144
+ ## Admin Dashboard
145
+
146
+ Access the web dashboard at `http://localhost:3000/dashboard` when the server is running.
147
+
148
+ Features:
149
+ - Create and manage short links
150
+ - View click analytics with human/bot breakdown
151
+ - Add and manage detection rules
152
+ - Test user-agent strings against the detection engine
153
+
154
+ ## Configuration
155
+
156
+ Config is stored in `~/.carom/config.json`. Set values via CLI or env vars:
157
+
158
+ ```bash
159
+ # Via CLI
160
+ carom config set shield.threshold 50
161
+ carom config set shield.mode interstitial
162
+ carom config set baseUrl https://yourdomain.com
163
+
164
+ # Via environment variables
165
+ SHIELD_ENABLED=true
166
+ SHIELD_THRESHOLD=40
167
+ SHIELD_MODE=direct
168
+ BASE_URL=https://yourdomain.com
169
+ API_KEY=your-secret
170
+ PORT=3000
171
+ ```
172
+
173
+ ### Configuration Keys
174
+
175
+ | Key | Default | Description |
176
+ |-----|---------|-------------|
177
+ | `port` | 3000 | Server port |
178
+ | `host` | localhost | Bind address |
179
+ | `baseUrl` | (empty) | Public URL for generated short links |
180
+ | `apiKey` | (empty) | API key (empty = open access) |
181
+ | `shield.enabled` | true | Enable/disable bot protection |
182
+ | `shield.threshold` | 40 | Bot score threshold (0-100) |
183
+ | `shield.mode` | direct | `direct` or `interstitial` |
184
+ | `shield.safePage.title` | Welcome | Safe page title |
185
+ | `shield.safePage.description` | Visit our website... | Safe page description |
186
+ | `shield.safePage.brand` | YourBrand | Safe page brand name |
187
+
188
+ ## Programmatic Usage
189
+
190
+ ```js
191
+ import { startServer } from 'carom';
192
+
193
+ const { app, server, db } = await startServer({
194
+ port: 3000,
195
+ host: 'localhost',
196
+ apiKey: 'my-key',
197
+ shield: {
198
+ enabled: true,
199
+ threshold: 40,
200
+ mode: 'direct',
201
+ },
202
+ });
203
+ ```
204
+
205
+ ## Data Storage
206
+
207
+ All data is stored in `~/.carom/` (configurable via `--data-dir`):
208
+
209
+ ```
210
+ ~/.carom/
211
+ ├── data.db # SQLite database (links, clicks, rules)
212
+ ├── config.json # Configuration
213
+ ├── carom.pid # PID file (when running)
214
+ └── logs/
215
+ ├── stdout.log # Server output
216
+ └── stderr.log # Error output
217
+ ```
218
+
219
+ ## License
220
+
221
+ MIT
package/bin/carom.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import '../src/cli/index.js';
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "carom-link",
3
+ "version": "1.0.0",
4
+ "description": "Link redirect server with bot and automated traffic protection, plus CLI management",
5
+ "type": "module",
6
+ "bin": {
7
+ "carom": "./bin/carom.js"
8
+ },
9
+ "main": "src/server/server.js",
10
+ "exports": {
11
+ ".": "./src/server/server.js",
12
+ "./shield": "./src/cloak/detector.js"
13
+ },
14
+ "files": [
15
+ "bin/",
16
+ "src/",
17
+ "public/"
18
+ ],
19
+ "scripts": {
20
+ "start": "node bin/carom.js start",
21
+ "dev": "node --watch bin/carom.js start --verbose"
22
+ },
23
+ "engines": {
24
+ "node": ">=18.0.0"
25
+ },
26
+ "keywords": [
27
+ "carom",
28
+ "link",
29
+ "redirect",
30
+ "bot-detection",
31
+ "carrier",
32
+ "shortener"
33
+ ],
34
+ "license": "MIT",
35
+ "dependencies": {
36
+ "better-sqlite3": "^11.0.0",
37
+ "chalk": "^5.3.0",
38
+ "commander": "^12.0.0",
39
+ "cors": "^2.8.5",
40
+ "dotenv": "^16.4.0",
41
+ "express": "^4.21.0",
42
+ "express-rate-limit": "^7.4.0",
43
+ "helmet": "^8.0.0",
44
+ "nanoid": "^5.0.0"
45
+ }
46
+ }