@nightowne/tas-cli 2.3.0 → 2.4.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.
package/README.md CHANGED
@@ -1,234 +1,327 @@
1
1
  <p align="center">
2
- <img src="assets/demo.gif" alt="TAS — Telegram as Storage" width="640">
2
+ <img src="assets/demo.gif" alt="TAS — Telegram as Storage CLI demo" width="680">
3
3
  </p>
4
4
 
5
- <h1 align="center">
6
- 📦 TAS — Telegram as Storage
7
- </h1>
5
+ <h1 align="center">📦 TAS — Telegram as Storage</h1>
8
6
 
9
7
  <h3 align="center">
10
- Turn Telegram into your personal encrypted cloud drive.<br>
11
- Free forever. Zero-knowledge. No credit card. No limits.
8
+ Turn your Telegram bot into unlimited, encrypted cloud storage.<br>
9
+ <strong>Free forever. Zero-knowledge. No sign-up. No credit card. No limits.</strong>
12
10
  </h3>
13
11
 
14
12
  <p align="center">
15
- <a href="https://github.com/ixchio/tas/actions/workflows/ci.yml"><img src="https://github.com/ixchio/tas/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
16
- <a href="https://www.npmjs.com/package/@nightowne/tas-cli"><img src="https://img.shields.io/npm/v/@nightowne/tas-cli?color=cb3837&label=npm" alt="npm version"></a>
17
- <a href="https://www.npmjs.com/package/@nightowne/tas-cli"><img src="https://img.shields.io/npm/dm/@nightowne/tas-cli?color=blue" alt="Downloads"></a>
18
- <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License: MIT"></a>
13
+ <a href="https://github.com/ixchio/tas/actions/workflows/ci.yml"><img src="https://github.com/ixchio/tas/actions/workflows/ci.yml/badge.svg" alt="CI Status"></a>
14
+ <a href="https://www.npmjs.com/package/@nightowne/tas-cli"><img src="https://img.shields.io/npm/v/@nightowne/tas-cli?color=cb3837&label=npm&logo=npm" alt="npm version"></a>
15
+ <a href="https://www.npmjs.com/package/@nightowne/tas-cli"><img src="https://img.shields.io/npm/dm/@nightowne/tas-cli?color=blue&label=downloads&logo=npm" alt="Monthly Downloads"></a>
16
+ <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-brightgreen.svg" alt="License: MIT"></a>
19
17
  <a href="https://github.com/ixchio/tas/stargazers"><img src="https://img.shields.io/github/stars/ixchio/tas?style=social" alt="GitHub Stars"></a>
18
+ <a href="https://github.com/ixchio/tas/network/members"><img src="https://img.shields.io/github/forks/ixchio/tas?style=social" alt="GitHub Forks"></a>
19
+ <img src="https://img.shields.io/badge/node-%3E%3D18-brightgreen?logo=node.js" alt="Node.js >= 18">
20
+ <img src="https://img.shields.io/badge/encryption-AES--256--GCM-blueviolet?logo=shield" alt="AES-256-GCM">
21
+ <img src="https://img.shields.io/badge/tests-71%20passing-success" alt="71 Tests Passing">
20
22
  </p>
21
23
 
22
24
  <p align="center">
23
- <a href="#-quick-start">Quick Start</a> •
24
- <a href="#-why-tas">Why TAS</a> •
25
- <a href="#-features">Features</a> •
26
- <a href="#%EF%B8%8F-security">Security</a> •
27
- <a href="#-cli-reference">Docs</a> •
28
- <a href="#-contributing">Contributing</a>
25
+ <a href="QUICKSTART.md"><strong>📚 Quick Start</strong></a> &nbsp;•&nbsp;
26
+ <a href="FAQ.md">FAQ</a> &nbsp;•&nbsp;
27
+ <a href="#-why-tas">Why TAS?</a> &nbsp;•&nbsp;
28
+ <a href="#-features">Features</a> &nbsp;•&nbsp;
29
+ <a href="#-security-model">Security</a> &nbsp;•&nbsp;
30
+ <a href="#-cli-reference">CLI Docs</a> &nbsp;•&nbsp;
31
+ <a href="#-docker--cicd">Docker / CI</a> &nbsp;•&nbsp;
32
+ <a href="CHANGELOG.md">Changelog</a>
29
33
  </p>
30
34
 
31
35
  ---
32
36
 
33
- <br>
37
+ > **TL;DR** — One `npm install`, one `tas init`, then `tas push yourfile.pdf`. Your file is now AES-256 encrypted and stored for free on Telegram's infrastructure. No accounts, no fees, no vendor lock-in. Seriously.
34
38
 
35
- ## The Problem
39
+ ---
40
+
41
+ ## The Problem With "Free" Cloud Storage
42
+
43
+ Every major cloud provider has one of three business models: **scanning your data**, **charging you money**, or **capping your storage**. There is no free lunch.
36
44
 
37
- Google Drive scans your files. Dropbox costs $12/mo. iCloud locks you into Apple. Every "free" cloud storage either **reads your data**, **charges you money**, or **caps your storage**.
45
+ | Provider | Free Tier | Reads Your Data? | CLI-First? | Encryption At Rest (by you)? |
46
+ |---|---|---|---|---|
47
+ | Google Drive | 15 GB | ✅ Yes (indexes for ads) | ❌ | ❌ |
48
+ | Dropbox | 2 GB | ✅ Can access | ❌ | ❌ |
49
+ | iCloud | 5 GB | ✅ Apple ToS | ❌ | ❌ |
50
+ | Mega | 20 GB | ❓ Closed-source E2EE | ❌ | ❓ |
51
+ | Backblaze B2 | 10 GB | ❌ | ✅ | ❌ (you add it) |
52
+ | **TAS + Telegram** | **♾️ Unlimited** | **❌ Impossible (AES-256)** | **✅ First-class** | **✅ Always** |
38
53
 
39
- Meanwhile, Telegram gives every user **unlimited storage** with a bot API — and nobody's using it.
54
+ Meanwhile, Telegram gives every bot **unlimited file storage** via its public Bot API — and almost nobody is using it.
55
+
56
+ ---
40
57
 
41
58
  ## The Solution
42
59
 
43
- **TAS** compresses, encrypts, and uploads your files to your own private Telegram bot chat. Your password never leaves your machine. Telegram only sees encrypted noise. You get a real CLI-powered cloud drive — with mount, sync, share, and search — for **$0/month, forever.**
60
+ **TAS** compresses, encrypts (AES-256-GCM), chunks, and uploads your files to your own private Telegram bot chat. Your password never leaves your machine. Telegram only ever sees **encrypted noise**. You get a fully-featured, CLI-native cloud drive with FUSE mount, Dropbox-style sync, expiring share links, and tagging — at **$0/month, forever.**
44
61
 
45
62
  ```
46
- Your Machine Telegram Cloud
47
- ┌──────────────────┐ ┌──────────────────────┐
48
- │ │ Compress │ │
49
- │ tas push │──→ Encrypt ──→│ 🔒 Encrypted Blobs │
50
- │ tas mount │──→ Chunk ──→│ 🔒 Private Bot Chat │
51
- │ tas sync │ │ 🔒 Your Data, Safe │
52
- │ │ Decrypt │ │
53
- │ tas pull │←── Decomp ←──│ ← Download on demand│
54
- │ │ │ │
55
- └──────────────────┘ └──────────────────────┘
56
- SQLite Index Unlimited & Free
63
+ Your Machine Telegram Cloud
64
+ ┌─────────────────────────────┐ ┌──────────────────────────┐
65
+ │ │ │ │
66
+ │ tas push secret.tar.gz │──→ gzip ──→ │ 🔒 Encrypted Blob #1 │
67
+ │ tas mount ~/cloud │──→ AES-256 ──→│ 🔒 Encrypted Blob #2 │
68
+ │ tas sync start │──→ chunk ──→ │ 🔒 Encrypted Blob #3 │
69
+ │ │ │ (Private Bot Chat) │
70
+ │ tas pull secret.tar.gz │←── decrypt ←──│ │
71
+ │ (SHA-256 verified) │←── decomp ←──│ ← Stream on demand │
72
+ │ │ │ │
73
+ └─────────────────────────────┘ └──────────────────────────┘
74
+ SQLite Index Unlimited & Free
57
75
  ```
58
76
 
59
- <br>
77
+ ---
60
78
 
61
79
  ## ⚡ Quick Start
62
80
 
63
- Three commands. Two minutes. Zero cost.
81
+ **Three commands. Under two minutes. Zero cost.**
64
82
 
65
83
  ```bash
84
+ # 1. Install globally
66
85
  npm install -g @nightowne/tas-cli
67
86
 
68
- tas init # Connect your Telegram bot (guided wizard)
69
- tas push secret.pdf # Upload — encrypted, compressed, done
70
- tas pull secret.pdf # Download — decrypted, verified, instant
87
+ # 2. Connect your Telegram bot (guided wizard — takes ~60 seconds)
88
+ tas init
89
+
90
+ # 3. Start using it
91
+ tas push secret.pdf # Encrypt + compress + upload
92
+ tas pull secret.pdf # Download + decrypt + verify
93
+ tas list # See everything you've stored
71
94
  ```
72
95
 
73
- That's it. You now have encrypted cloud storage.
96
+ > **Need a Telegram bot?** Open Telegram → search `@BotFather` → `/newbot` → copy the token. That's it.
74
97
 
75
- <br>
98
+ ---
76
99
 
77
- ## 💡 Why TAS
100
+ ## 💡 Why TAS?
78
101
 
79
102
  <table>
80
103
  <tr>
81
- <td width="50%">
82
-
83
- ### vs. Google Drive
84
- - ❌ Google scans & indexes your files
85
- - ❌ 15 GB free tier
86
- - ❌ No encryption at rest (by you)
87
-
88
- ### vs. Dropbox
89
- - ❌ $12/mo for 2 TB
90
- - ❌ Can access your data
91
- - ❌ No CLI-first experience
104
+ <td width="50%" valign="top">
92
105
 
93
- ### vs. Mega / pCloud
94
- - ❌ Freemium with tight caps
95
- - ❌ Closed source encryption
96
- - ❌ Can't self-host or script
106
+ ### ❌ The Alternative
107
+ - Google Drive scans & indexes your files for ads
108
+ - Dropbox costs $12/mo — and can read your data
109
+ - iCloud locks you into the Apple ecosystem
110
+ - Self-hosting (Nextcloud, MinIO) costs VPS money + maintenance time
111
+ - S3 / B2 needs encryption wiring and costs per GB transferred
112
+ - rclone + any backend still needs a paid backend
97
113
 
98
114
  </td>
99
- <td width="50%">
100
-
101
- ### TAS gives you
102
- - ✅ **$0/month** — forever, no caps
103
- - ✅ **Zero-knowledge** — only you can decrypt
104
- - ✅ **AES-256-GCM** — military-grade encryption
105
- - ✅ **Mount as folder** — FUSE filesystem
106
- - ✅ **Auto-sync** — Dropbox-style folder sync
107
- - ✅ **Share links** — expiring, download-limited
108
- - ✅ **CLI-first** — cron, Docker, CI/CD ready
109
- - ✅ **Open source** — audit every line
115
+ <td width="50%" valign="top">
116
+
117
+ ### ✅ TAS gives you
118
+ - **$0/month** — forever, no storage caps, no bandwidth fees
119
+ - **Zero-knowledge** — only you hold the decryption key
120
+ - **AES-256-GCM** — same cipher used by banks and governments
121
+ - **FUSE mount** — Telegram storage appears as a real folder
122
+ - **Auto-sync** — Dropbox-style folder watcher built-in
123
+ - **Expiring share links** — send files without sharing your password
124
+ - **CLI-first** — pipe to `jq`, run in cron, automate everything
125
+ - **Open source** — audit every single line of crypto code
110
126
 
111
127
  </td>
112
128
  </tr>
113
129
  </table>
114
130
 
115
- <br>
131
+ ---
116
132
 
117
133
  ## 🔥 Features
118
134
 
119
- ### 🗂️ Mount as a Local Folder
120
- Drag and drop files into Telegram storage like it's a regular drive.
135
+ ### 🗂️ Mount as a Local Folder (FUSE)
136
+
137
+ Use Telegram storage exactly like a USB drive — drag and drop, open in any app.
121
138
 
122
139
  ```bash
123
- tas mount ~/cloud # Mount your Telegram storage
124
- # Now use Finder, Explorer, or any app — files sync to Telegram
125
- tas unmount ~/cloud
140
+ tas mount ~/cloud # Mount your Telegram storage as ~/cloud
141
+ ls ~/cloud # Browse your encrypted files normally
142
+ cp report.pdf ~/cloud/ # Drop files in — auto-encrypted and uploaded
143
+ tas unmount ~/cloud # Clean unmount when done
126
144
  ```
127
145
 
128
- > Requires `libfuse` — `apt install fuse libfuse-dev` on Linux, `brew install macfuse` on macOS.
146
+ > **Requirements:** `apt install fuse libfuse-dev` (Linux) · `brew install macfuse` (macOS)
147
+
148
+ ---
149
+
150
+ ### 🔄 Auto-Sync Folders (Dropbox-style)
129
151
 
130
- ### 🔄 Auto-Sync Folders
131
- Dropbox-style: register a folder, and TAS watches for changes and uploads automatically.
152
+ Register a local folder and TAS watches it. Any new or changed file is automatically encrypted and uploaded.
132
153
 
133
154
  ```bash
134
- tas sync add ~/Documents # Register a folder
135
- tas sync start # Watch & auto-upload changes
136
- tas sync pull # Download everything back
137
- tas sync status # See what's synced
155
+ tas sync add ~/Documents # Register ~/Documents for auto-sync
156
+ tas sync start # Start the watcher (runs in background)
157
+ tas sync pull # Pull all synced files back down
158
+ tas sync status # See what's queued / synced / pending
138
159
  ```
139
160
 
140
- ### 🔗 Share with Expiring Links
141
- Generate one-time download links with a sleek dark-themed download page. Files are decrypted on-the-fly — the link holder never sees your password.
161
+ ---
162
+
163
+ ### 🔗 Expiring Share Links
164
+
165
+ Generate time-limited, download-limited share links. Recipients get a clean dark-themed download page. **Your password is never shared — files are decrypted on-the-fly by the local server.**
142
166
 
143
167
  ```bash
144
- tas share create report.pdf --expire 1h --max-downloads 3
145
- # → http://localhost:3000/d/a1b2c3d4...
168
+ tas share create report.pdf --expire 24h --max-downloads 5
169
+ # → http://localhost:3000/d/a1b2c3d4e5f6...
146
170
 
147
- tas share list # See active shares
148
- tas share revoke a1b2c3d4 # Revoke anytime
171
+ tas share create backup.tar.gz --expire 1h --max-downloads 1 # Burn-after-read
172
+ tas share list # See active links with expiry info
173
+ tas share revoke a1b2c3d4 # Revoke instantly, anytime
149
174
  ```
150
175
 
151
- ### 🏷️ Tags & Search
152
- Organize and find files instantly.
176
+ ---
177
+
178
+ ### 🏷️ Tags & Full-Text Search
153
179
 
154
180
  ```bash
155
- tas tag add report.pdf work Q4
156
- tas search "report" # Search by filename
157
- tas search -t work # Search by tag
181
+ tas tag add report.pdf work Q4 finance
182
+ tas tag add keys.env secrets production
183
+ tas search "report" # Search by filename pattern
184
+ tas search -t work # All files tagged "work"
185
+ tas search -t secrets # Quickly find your credentials
158
186
  ```
159
187
 
188
+ ---
189
+
160
190
  ### 🩺 Self-Diagnostics
161
- One command to check if everything is healthy.
162
191
 
163
192
  ```bash
164
193
  tas doctor
165
194
  # ✓ Node.js 20.11.0
166
- # ✓ Config v2 (encrypted token)
167
- # ✓ Database: 42 files, 1.3 GB total
195
+ # ✓ Config v2 (encrypted bot token — AES-256-GCM at rest)
196
+ # ✓ Database: 42 files, 1.3 GB total across 28 chunks
168
197
  # ✓ Disk space: 50 GB free (32% used)
169
- # ✓ Encryption: AES-256-GCM, PBKDF2-SHA512 600,000 iterations
198
+ # ✓ Encryption: AES-256-GCM · PBKDF2-SHA512 · 600,000 iterations (OWASP 2025)
199
+ # ✓ Telegram connectivity: OK
170
200
  # ✨ All systems go!
171
201
  ```
172
202
 
173
- ### 🤖 Built for Automation
174
- First-class JSON output, environment variable support, and zero interactivity mode.
203
+ ---
204
+
205
+ ### 🤖 Built for Automation — CI/CD, Docker, Cron
206
+
207
+ TAS is fully scriptable. No interactive prompts needed when `TAS_PASSWORD` is set.
175
208
 
176
209
  ```bash
177
- export TAS_PASSWORD="your-password" # Skip prompts
178
- export TAS_DATA_DIR="/custom/path" # Custom data location
210
+ # Environment-based automation
211
+ export TAS_PASSWORD="your-password"
212
+ export TAS_DATA_DIR="/custom/path"
213
+
214
+ # Pipe to jq
215
+ tas list --json | jq '.[].filename'
216
+ tas list --json | jq '.[] | select(.size > 1000000)' # Files > 1MB
217
+
218
+ # GitHub Actions backup step
219
+ tas push db-backup-$(date +%Y%m%d).sql.gz
179
220
 
180
- tas push backup.tar.gz # Non-interactive upload
181
- tas list --json | jq '.[].filename' # Pipe to jq
182
- tas status --json # Machine-readable status
221
+ # cron: nightly backup at 2am
222
+ 0 2 * * * TAS_PASSWORD=$SECRET tas push /var/backups/db.tar.gz
183
223
 
184
- # Works with: cron • GitHub Actions • Docker • systemd • any CI/CD
224
+ # JSON machine output everywhere
225
+ tas status --json
226
+ tas list --json
185
227
  ```
186
228
 
187
- <br>
229
+ ---
230
+
231
+ ## 🐳 Docker & CI/CD
188
232
 
189
- ## 🛡️ Security
233
+ ```dockerfile
234
+ FROM node:20-alpine
235
+
236
+ RUN npm install -g @nightowne/tas-cli
237
+
238
+ ENV TAS_PASSWORD=""
239
+ ENV TAS_DATA_DIR="/data"
240
+
241
+ VOLUME ["/data"]
242
+
243
+ CMD ["tas", "status"]
244
+ ```
245
+
246
+ ```yaml
247
+ # .github/workflows/backup.yml
248
+ name: Nightly Backup
249
+
250
+ on:
251
+ schedule:
252
+ - cron: '0 2 * * *'
253
+
254
+ jobs:
255
+ backup:
256
+ runs-on: ubuntu-latest
257
+ steps:
258
+ - name: Install TAS
259
+ run: npm install -g @nightowne/tas-cli
260
+
261
+ - name: Push backup
262
+ env:
263
+ TAS_PASSWORD: ${{ secrets.TAS_PASSWORD }}
264
+ TAS_DATA_DIR: ${{ runner.temp }}/tas-data
265
+ run: |
266
+ tas init --token ${{ secrets.TELEGRAM_BOT_TOKEN }} --chat ${{ secrets.TELEGRAM_CHAT_ID }}
267
+ tar czf backup-$(date +%Y%m%d).tar.gz ./important-data/
268
+ tas push backup-$(date +%Y%m%d).tar.gz
269
+ ```
270
+
271
+ ---
190
272
 
191
- TAS implements **zero-knowledge encryption** — we can't read your data, Telegram can't read your data, nobody can read your data without your password.
273
+ ## 🛡️ Security Model
192
274
 
193
- | Layer | Implementation | Why It Matters |
194
- |-------|----------------|----------------|
195
- | **Cipher** | AES-256-GCM | Same cipher used by governments & banks |
196
- | **Key Derivation** | PBKDF2-SHA512, **600k iterations** | OWASP 2025 compliant — brute-force resistant |
197
- | **Salt** | 32 bytes, cryptographically random | Unique per file — no rainbow tables |
198
- | **IV** | 12 bytes, cryptographically random | Unique per file — no pattern analysis |
199
- | **Auth Tag** | 16 bytes GCM authentication | Tamper detection — any bit flip = rejected |
200
- | **Bot Token** | Encrypted at rest (AES-256-GCM) | Even your config file is protected |
201
- | **Password Hash** | PBKDF2-based verification | Your password hash is computationally expensive to crack |
202
- | **Integrity** | SHA-256 verified on every download | Bit-perfect downloads, guaranteed |
203
- | **Share Server** | XSS-safe, RFC 6266 headers | Hardened against injection attacks |
275
+ TAS implements **zero-knowledge encryption** — we can't read your data, Telegram can't read your data, and nobody without your password ever can.
204
276
 
205
- For the full threat model, cipher rationale, and file format spec, see **[docs/security.md](docs/security.md)**.
277
+ | Layer | Implementation | Standard |
278
+ |---|---|---|
279
+ | **Cipher** | AES-256-GCM (authenticated encryption) | NIST FIPS 197 |
280
+ | **Key Derivation** | PBKDF2-SHA512, **600,000 iterations** | OWASP 2025 |
281
+ | **Salt** | 32 bytes, `crypto.randomBytes()` — unique per file | No rainbow tables |
282
+ | **IV/Nonce** | 12 bytes, `crypto.randomBytes()` — unique per file | No nonce reuse |
283
+ | **Auth Tag** | 16 bytes GCM tag — any tampered bit = instant rejection | Tamper detection |
284
+ | **Bot Token** | Encrypted at rest in `config.json` (AES-256-GCM) | Config v2 |
285
+ | **Password Verification** | `crypto.timingSafeEqual()` on both PBKDF2 and legacy paths | Timing-safe |
286
+ | **Config Permissions** | `chmod 600 config.json` on creation | No world-readable secrets |
287
+ | **Integrity** | SHA-256 hash verified on every single download | Bit-perfect guarantee |
288
+ | **Share Server** | Binds `127.0.0.1` by default, XSS-escaped, RFC 6266 filenames | LAN-safe |
206
289
 
207
- ### What Telegram Sees
290
+ ### What Telegram Actually Sees
208
291
 
209
292
  ```
210
- 📦 a7f3b2c1e9d4.tas — 12.4 MB — application/octet-stream
293
+ 📦 a7f3b2c1e9d4f820.tas — 12.4 MB — application/octet-stream
211
294
  ```
212
295
 
213
- That's it. An opaque encrypted blob. No filename, no content, no metadata. Just noise.
296
+ An opaque, encrypted blob. No filename. No content type. No metadata. Just noise.
214
297
 
215
- <br>
298
+ ### Threat Model
299
+
300
+ | Threat | Mitigated? | How |
301
+ |---|---|---|
302
+ | Telegram reads your files | ✅ Yes | AES-256-GCM — mathematically impossible without key |
303
+ | Someone steals your config.json | ✅ Yes | Bot token encrypted at rest; password hash is PBKDF2 |
304
+ | Brute-force your password | ✅ Yes | 600k PBKDF2 iterations ≈ 100ms/attempt minimum |
305
+ | Tampered download | ✅ Yes | SHA-256 check + GCM auth tag on every download |
306
+ | Timing attack on password | ✅ Yes | `crypto.timingSafeEqual()` on all comparisons |
307
+ | Share link exposure | ✅ Yes | Localhost-only by default; expiry + download limits |
308
+
309
+ ---
216
310
 
217
311
  ## 🔄 Reliability
218
312
 
219
- Built like professional backup tools (inspired by restic, rclone, borg):
313
+ Built with the same philosophy as professional backup tools (restic, borg, rclone):
220
314
 
221
- | Feature | Details |
222
- |---------|---------|
315
+ | Feature | Implementation |
316
+ |---|---|
223
317
  | **Exponential Backoff** | Auto-retry with jitter on Telegram 429 errors and network timeouts |
224
- | **Rate Limiting** | Built-in 1 msg/sec limiter — never hits Telegram's rate limits |
225
- | **Integrity Verification** | SHA-256 hash check after every single download |
226
- | **Resume Uploads** | Interrupted? Run `tas resume` to pick up where you left off |
227
- | **Atomic Transactions** | Upload pipeline uses SQLite transactions — pipeline failure = clean rollback, zero orphaned DB rows |
228
- | **Graceful Shutdown** | SIGINT/SIGTERM handled cleanly — zero data corruption risk |
229
- | **Self-Diagnostics** | `tas doctor` validates your entire setup in seconds |
318
+ | **Rate Limiting** | Built-in 1 msg/sec — never trips Telegram's rate limits |
319
+ | **Integrity Verification** | SHA-256 hash verified after every single download |
320
+ | **Resume Uploads** | `tas resume` picks up interrupted multi-chunk uploads |
321
+ | **Graceful Shutdown** | SIGINT/SIGTERM handled — zero corruption risk on Ctrl-C |
322
+ | **Self-Diagnostics** | `tas doctor` validates your entire setup end-to-end |
230
323
 
231
- <br>
324
+ ---
232
325
 
233
326
  ## 📋 CLI Reference
234
327
 
@@ -236,16 +329,16 @@ Built like professional backup tools (inspired by restic, rclone, borg):
236
329
  <summary><strong>Core Commands</strong></summary>
237
330
 
238
331
  ```bash
239
- tas init # 🚀 Interactive setup wizard
240
- tas push <file> # ⬆️ Upload (encrypt + compress + upload)
241
- tas pull <file|hash> # ⬇️ Download (download + decrypt + verify)
242
- tas list [-l] [--json] # 📋 List all files
243
- tas delete <file|hash> # 🗑️ Remove from index (--hard to delete from Telegram)
244
- tas status [--json] # 📊 Storage stats
245
- tas search <query> # 🔍 Find files by name or tag
246
- tas resume # 🔄 Resume interrupted uploads
247
- tas verify # ✅ Verify all files exist & are intact
248
- tas doctor # 🩺 System health check
332
+ tas init # 🚀 Interactive setup wizard (create bot in ~60s)
333
+ tas push <file> [file2...] # ⬆️ Encrypt + compress + upload
334
+ tas pull <file|hash> # ⬇️ Download + decrypt + verify
335
+ tas list [-l] [--json] # 📋 List all stored files
336
+ tas delete <file|hash> # 🗑️ Remove from index (--hard removes from Telegram)
337
+ tas status [--json] # 📊 Storage stats & database health
338
+ tas search <query> [-t tag] # 🔍 Find by filename or tag
339
+ tas resume # 🔄 Resume interrupted uploads
340
+ tas verify # ✅ Verify every file still exists and is intact
341
+ tas doctor # 🩺 Full system health check
249
342
  ```
250
343
 
251
344
  </details>
@@ -254,15 +347,15 @@ tas doctor # 🩺 System health check
254
347
  <summary><strong>Mount & Sync</strong></summary>
255
348
 
256
349
  ```bash
257
- # FUSE Mount (use Telegram like a local folder)
258
- tas mount <path> # Mount
259
- tas unmount <path> # Unmount
260
-
261
- # Folder Sync (Dropbox-style auto-upload)
262
- tas sync add <folder> # Register a folder to sync
263
- tas sync start # Start watching for changes
264
- tas sync pull # Download all synced files
265
- tas sync status # Show sync status
350
+ # FUSE Mount
351
+ tas mount <path> # Mount Telegram storage as a local folder
352
+ tas unmount <path> # Clean unmount
353
+
354
+ # Dropbox-style Folder Sync
355
+ tas sync add <folder> # Register folder for auto-sync
356
+ tas sync start # Start watching for changes
357
+ tas sync pull # Download all synced files locally
358
+ tas sync status # Show sync queue and status
266
359
  ```
267
360
 
268
361
  </details>
@@ -271,107 +364,158 @@ tas sync status # Show sync status
271
364
  <summary><strong>Share & Tags</strong></summary>
272
365
 
273
366
  ```bash
274
- # Temporary Share Links
275
- tas share create <file> [--expire 24h] [--max-downloads 3]
276
- tas share list # Active shares
277
- tas share revoke <token> # Revoke a share link
278
-
279
- # File Tags
280
- tas tag add <file> <tags...>
281
- tas tag remove <file> <tags...>
282
- tas tag list [tag] # List tags or files with a specific tag
367
+ # Expiring Share Links
368
+ tas share create <file> [--expire 1h|24h|7d] [--max-downloads N]
369
+ tas share list # Active links with expiry countdown
370
+ tas share revoke <token> # Instantly revoke a share
371
+
372
+ # File Tagging
373
+ tas tag add <file> <tag> [tag2...]
374
+ tas tag remove <file> <tag>
375
+ tas tag list [tag] # List all tags, or files with a specific tag
283
376
  ```
284
377
 
285
378
  </details>
286
379
 
287
- <br>
380
+ <details>
381
+ <summary><strong>Environment Variables</strong></summary>
382
+
383
+ ```bash
384
+ TAS_PASSWORD="..." # Skip password prompts (CI/CD, cron, Docker)
385
+ TAS_DATA_DIR="/custom/path" # Override default ~/.tas data directory
386
+ ```
387
+
388
+ </details>
389
+
390
+ ---
288
391
 
289
392
  ## 🏗️ Architecture
290
393
 
291
394
  ```
292
395
  src/
293
- ├── cli.js # Commander-based CLI — all commands
294
- ├── index.js # Streaming upload/download pipeline
396
+ ├── cli.js # Commander-based CLI — all commands defined here
397
+ ├── index.js # Core streaming upload/download pipeline
295
398
  ├── crypto/
296
- │ └── encryption.js # AES-256-GCM + PBKDF2-SHA512 key derivation
399
+ │ └── encryption.js # AES-256-GCM + PBKDF2-SHA512 (600k iterations)
297
400
  ├── db/
298
- │ └── index.js # SQLite index (files, chunks, tags, shares, sync)
401
+ │ └── index.js # SQLite index: files, chunks, tags, shares, sync
299
402
  ├── telegram/
300
- │ └── client.js # Bot API wrapper — retry, rate-limit, streaming
403
+ │ └── client.js # Bot API wrapper — retry, rate-limit, streaming
301
404
  ├── fuse/
302
- │ └── mount.js # FUSE filesystem — mount Telegram as a folder
405
+ │ └── mount.js # FUSE filesystem — mount Telegram as a local folder
303
406
  ├── share/
304
- │ └── server.js # HTTP server — expiring download links
407
+ │ └── server.js # HTTP server — expiring encrypted share links
305
408
  ├── sync/
306
- │ └── sync.js # Folder watcher — Dropbox-style auto-sync
409
+ │ └── sync.js # fs.watch folder watcher — Dropbox-style auto-sync
307
410
  └── utils/
308
- ├── compression.js # Smart gzip (skips already-compressed formats)
309
- ├── chunker.js # 49MB chunking with custom WAS1 file headers
310
- ├── progress.js # Terminal progress bar with speed + ETA
311
- ├── throttle.js # Bandwidth limiter (stream transform)
312
- ├── branding.js # ASCII art + version (auto-synced from package.json)
313
- └── cli-helpers.js # Password management + config resolution
411
+ ├── download-stream.js # Shared Telegram→Decrypt→Decompress pipeline
412
+ ├── compression.js # Smart gzip (skips already-compressed formats)
413
+ ├── chunker.js # 49 MB chunks + WAS1 binary file headers
414
+ ├── progress.js # Terminal progress bars with MB/s + ETA
415
+ ├── throttle.js # Bandwidth limiter (stream transform)
416
+ ├── branding.js # ASCII art + version display
417
+ └── cli-helpers.js # Password management + config resolution
314
418
  ```
315
419
 
316
- **Tech stack:** Node.js · better-sqlite3 · node-telegram-bot-api · fuse-native · Commander · Chalk · Ora · Inquirer
420
+ **Tech stack:** Node.js 18+ · better-sqlite3 · node-telegram-bot-api · fuse-native · Commander · Chalk · Ora · Inquirer
421
+
422
+ ---
317
423
 
318
- <br>
424
+ ## 💡 Perfect For
425
+
426
+ | Use Case | Example |
427
+ |---|---|
428
+ | 📄 **Personal document vault** | Taxes, contracts, scans, receipts — encrypted |
429
+ | 🔑 **Secrets & credentials** | `.env` files, SSH private keys, API tokens |
430
+ | 🗝️ **Password manager sync** | KeePass `.kdbx`, 1Password vaults, Bitwarden exports |
431
+ | 📦 **Code project backups** | Git bundles, build artifacts, config files |
432
+ | 🎬 **Private media archive** | Photos, videos, music — encrypted & searchable |
433
+ | 🔗 **Ephemeral file sharing** | Burn-after-read links with download limits |
434
+ | 💾 **Offsite backup** | Nightly database dumps, system configs via cron |
435
+ | 🤖 **CI/CD artifacts** | Store build outputs, test reports, deployment keys |
436
+
437
+ **Not ideal for:** Mission-critical business data (use professional backup tools alongside this), team collaboration (no multi-user support yet), or replacing full backup systems — **Telegram can theoretically delete old messages.**
438
+
439
+ ---
440
+
441
+ ## ❓ Is This Allowed? (The Legal Question)
442
+
443
+ ### Will Telegram ban me?
444
+
445
+ **No.** Here's the complete picture:
446
+
447
+ - ✅ **Bot API is a public, documented feature** — Telegram designed file uploads into the Bot API intentionally
448
+ - ✅ **You're sending to your own private bot chat** — not a public channel, not spamming
449
+ - ✅ **Content is encrypted** — Telegram cannot detect what you're storing
450
+ - ✅ **No published storage limits** — individual files cap at 2 GB (TAS chunks automatically)
451
+ - ✅ **Strong precedent** — thousands of file-sharing bots, backup tools, and media archives use this API
452
+ - ⚠️ **Worst case** — Telegram might prune old messages to free infrastructure space. They won't ban you for using a documented API
453
+
454
+ **Your responsibility:** Don't store illegal content. Telegram's ToS prohibits copyright infringement, malware, CSAM, etc. Use responsibly. See [FAQ.md](FAQ.md) for the full legal breakdown.
455
+
456
+ ---
319
457
 
320
458
  ## ⚠️ Good to Know
321
459
 
322
460
  | | |
323
461
  |---|---|
324
- | 📌 **Not a backup solution** | Telegram can delete content. Use TAS alongside proper backups, not instead of them. |
325
- | 📌 **49 MB chunks** | Files are automatically split due to Telegram Bot API limits. Fully transparent. |
326
- | 📌 **Single-user** | Designed for personal use. Not multi-tenant. |
327
- | 📌 **FUSE = Linux/macOS** | Mount feature requires `libfuse`. CLI works everywhere Node.js runs. |
462
+ | 📌 **Not a replacement for backups** | Telegram can purge old messages. Use TAS alongside, not instead of, real backup solutions. |
463
+ | 📌 **49 MB chunk size** | Files are split automatically — fully transparent to you. Telegram's Bot API limit is 50 MB. |
464
+ | 📌 **Single-user** | Designed for personal use. No multi-tenant or shared-account support. |
465
+ | 📌 **FUSE = Linux/macOS only** | Mount requires `libfuse`. The CLI itself works anywhere Node.js 18+ runs. |
328
466
  | 📌 **No versioning (yet)** | Overwriting a file replaces the previous version. |
467
+ | 📌 **Internet required** | Telegram-backed — offline access requires files pulled locally first. |
329
468
 
330
- <br>
469
+ ---
331
470
 
332
471
  ## 🛠️ Development
333
472
 
334
473
  ```bash
335
474
  git clone https://github.com/ixchio/tas
336
475
  cd tas && npm install
337
- npm test # 83 tests across 16 suites, all passing
476
+
477
+ npm test # Run all 71 tests (encryption, WAS1 headers, tags, sync, shares)
478
+ npm test -- --watch # Watch mode for active development
338
479
  ```
339
480
 
340
- For the full developer guide (architecture, testing, conventions, gotchas), see **[docs/development.md](docs/development.md)**.
481
+ **Test coverage:** streaming encrypt/decrypt roundtrips · cross-API compat (buffer↔stream) · small-chunk stress testing · truncation/corruption error paths · Unicode filename handling · WAS1 binary header parsing · timing-safe comparison paths
341
482
 
342
- PRs welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
483
+ PRs welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
343
484
 
344
- <br>
485
+ ---
345
486
 
346
- ## 📚 Documentation
487
+ ## 🌟 Contributing
347
488
 
348
- | Doc | What's in it |
349
- |-----|-------------|
350
- | [docs/development.md](docs/development.md) | Developer onboarding — project structure, how to add commands, testing, conventions |
351
- | [docs/security.md](docs/security.md) | Threat model — what TAS protects against, cipher details, file format specs |
352
- | [CHANGELOG.md](CHANGELOG.md) | Version history with all changes documented |
353
- | [CONTRIBUTING.md](CONTRIBUTING.md) | How to contribute — fork, branch, PR |
354
- | [SECURITY.md](SECURITY.md) | Security vulnerability reporting |
489
+ TAS is open source and contributions are genuinely appreciated:
355
490
 
356
- <br>
491
+ - 🐛 **Found a bug?** [Open an issue](https://github.com/ixchio/tas/issues) — include `tas doctor` output
492
+ - 💡 **Have a feature idea?** [Start a discussion](https://github.com/ixchio/tas/discussions)
493
+ - 🔧 **Want to contribute code?** Fork → branch → PR → 🎉
494
+ - ⭐ **Just want to help?** A GitHub star dramatically increases discoverability
357
495
 
358
- ## 🌟 Contributing
496
+ ---
359
497
 
360
- TAS is open source and we love contributions:
498
+ ## 📄 License
499
+
500
+ MIT — use it, fork it, ship it, sell it. Do whatever you want with it.
361
501
 
362
- - 🐛 **Found a bug?** [Open an issue](https://github.com/ixchio/tas/issues)
363
- - 💡 **Have an idea?** [Start a discussion](https://github.com/ixchio/tas/issues)
364
- - 🔧 **Want to contribute?** Fork → Branch → PR → 🎉
502
+ ---
365
503
 
366
- <br>
504
+ ## Related Projects
367
505
 
368
- ## 📄 License
506
+ If TAS fits your workflow, you might also find these useful:
369
507
 
370
- MIT — use it, fork it, ship it, sell it. Do whatever you want.
508
+ - [rclone](https://github.com/rclone/rclone) — rsync for cloud storage (dozens of backends)
509
+ - [restic](https://github.com/restic/restic) — encrypted, deduplicated backup program
510
+ - [age](https://github.com/FiloSottile/age) — simple, modern file encryption tool
511
+ - [magic-wormhole](https://github.com/magic-wormhole/magic-wormhole) — encrypted file transfer between machines
371
512
 
372
513
  ---
373
514
 
374
515
  <p align="center">
375
516
  <sub>Built with ☕ and stubbornness by <a href="https://github.com/ixchio">@ixchio</a></sub><br>
376
- <sub>If TAS saved you money, consider giving it a ⭐</sub>
517
+ <sub>If TAS saved you money, a ⭐ on GitHub is the best way to say thanks — it helps others find the project.</sub><br><br>
518
+ <a href="https://github.com/ixchio/tas/stargazers">
519
+ <img src="https://img.shields.io/github/stars/ixchio/tas?style=for-the-badge&logo=github&label=Star%20TAS&color=ffd700" alt="Star TAS on GitHub">
520
+ </a>
377
521
  </p>