@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 +347 -203
- package/package.json +4 -4
- package/src/cli.js +3 -1
- package/src/crypto/encryption.js +15 -2
- package/src/fuse/mount.js +137 -173
- package/src/index.js +126 -192
- package/src/share/server.js +19 -80
- package/src/sync/sync.js +23 -159
- package/src/telegram/client.js +9 -3
- package/src/utils/branding.js +1 -8
- package/src/utils/download-stream.js +87 -0
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="
|
|
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
|
|
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-
|
|
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="
|
|
24
|
-
<a href="
|
|
25
|
-
<a href="#-
|
|
26
|
-
<a href="
|
|
27
|
-
<a href="#-
|
|
28
|
-
<a href="#-
|
|
25
|
+
<a href="QUICKSTART.md"><strong>📚 Quick Start</strong></a> •
|
|
26
|
+
<a href="FAQ.md">FAQ</a> •
|
|
27
|
+
<a href="#-why-tas">Why TAS?</a> •
|
|
28
|
+
<a href="#-features">Features</a> •
|
|
29
|
+
<a href="#-security-model">Security</a> •
|
|
30
|
+
<a href="#-cli-reference">CLI Docs</a> •
|
|
31
|
+
<a href="#-docker--cicd">Docker / CI</a> •
|
|
32
|
+
<a href="CHANGELOG.md">Changelog</a>
|
|
29
33
|
</p>
|
|
30
34
|
|
|
31
35
|
---
|
|
32
36
|
|
|
33
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
47
|
-
|
|
48
|
-
│
|
|
49
|
-
│
|
|
50
|
-
│
|
|
51
|
-
│
|
|
52
|
-
│
|
|
53
|
-
│
|
|
54
|
-
│
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
77
|
+
---
|
|
60
78
|
|
|
61
79
|
## ⚡ Quick Start
|
|
62
80
|
|
|
63
|
-
Three commands.
|
|
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
|
-
|
|
69
|
-
tas
|
|
70
|
-
|
|
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
|
-
|
|
96
|
+
> **Need a Telegram bot?** Open Telegram → search `@BotFather` → `/newbot` → copy the token. That's it.
|
|
74
97
|
|
|
75
|
-
|
|
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
|
-
###
|
|
94
|
-
-
|
|
95
|
-
-
|
|
96
|
-
-
|
|
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
|
-
-
|
|
103
|
-
-
|
|
104
|
-
-
|
|
105
|
-
-
|
|
106
|
-
-
|
|
107
|
-
-
|
|
108
|
-
-
|
|
109
|
-
-
|
|
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
|
-
|
|
131
|
+
---
|
|
116
132
|
|
|
117
133
|
## 🔥 Features
|
|
118
134
|
|
|
119
|
-
### 🗂️ Mount as a Local Folder
|
|
120
|
-
|
|
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
|
|
124
|
-
#
|
|
125
|
-
|
|
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
|
-
>
|
|
146
|
+
> **Requirements:** `apt install fuse libfuse-dev` (Linux) · `brew install macfuse` (macOS)
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
### 🔄 Auto-Sync Folders (Dropbox-style)
|
|
129
151
|
|
|
130
|
-
|
|
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
|
|
135
|
-
tas sync start
|
|
136
|
-
tas sync pull
|
|
137
|
-
tas sync status
|
|
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
|
-
|
|
141
|
-
|
|
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
|
|
145
|
-
# → http://localhost:3000/d/
|
|
168
|
+
tas share create report.pdf --expire 24h --max-downloads 5
|
|
169
|
+
# → http://localhost:3000/d/a1b2c3d4e5f6...
|
|
146
170
|
|
|
147
|
-
tas share
|
|
148
|
-
tas share
|
|
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
|
-
|
|
152
|
-
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
### 🏷️ Tags & Full-Text Search
|
|
153
179
|
|
|
154
180
|
```bash
|
|
155
|
-
tas tag add report.pdf work Q4
|
|
156
|
-
tas
|
|
157
|
-
tas search
|
|
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
|
|
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
|
-
|
|
174
|
-
|
|
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
|
-
|
|
178
|
-
export
|
|
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
|
-
|
|
181
|
-
|
|
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
|
-
#
|
|
224
|
+
# JSON machine output everywhere
|
|
225
|
+
tas status --json
|
|
226
|
+
tas list --json
|
|
185
227
|
```
|
|
186
228
|
|
|
187
|
-
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## 🐳 Docker & CI/CD
|
|
188
232
|
|
|
189
|
-
|
|
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
|
-
|
|
273
|
+
## 🛡️ Security Model
|
|
192
274
|
|
|
193
|
-
|
|
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
|
-
|
|
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
|
-
📦
|
|
293
|
+
📦 a7f3b2c1e9d4f820.tas — 12.4 MB — application/octet-stream
|
|
211
294
|
```
|
|
212
295
|
|
|
213
|
-
|
|
296
|
+
An opaque, encrypted blob. No filename. No content type. No metadata. Just noise.
|
|
214
297
|
|
|
215
|
-
|
|
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
|
|
313
|
+
Built with the same philosophy as professional backup tools (restic, borg, rclone):
|
|
220
314
|
|
|
221
|
-
| Feature |
|
|
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
|
|
225
|
-
| **Integrity Verification** | SHA-256 hash
|
|
226
|
-
| **Resume Uploads** |
|
|
227
|
-
| **
|
|
228
|
-
| **
|
|
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
|
-
|
|
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
|
|
240
|
-
tas push <file>
|
|
241
|
-
tas pull <file|hash>
|
|
242
|
-
tas list [-l] [--json]
|
|
243
|
-
tas delete <file|hash>
|
|
244
|
-
tas status [--json]
|
|
245
|
-
tas search <query>
|
|
246
|
-
tas resume
|
|
247
|
-
tas verify
|
|
248
|
-
tas doctor
|
|
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
|
|
258
|
-
tas mount <path>
|
|
259
|
-
tas unmount <path>
|
|
260
|
-
|
|
261
|
-
#
|
|
262
|
-
tas sync add <folder>
|
|
263
|
-
tas sync start
|
|
264
|
-
tas sync pull
|
|
265
|
-
tas 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
|
-
#
|
|
275
|
-
tas share create <file> [--expire 24h] [--max-downloads
|
|
276
|
-
tas share list
|
|
277
|
-
tas share revoke <token>
|
|
278
|
-
|
|
279
|
-
# File
|
|
280
|
-
tas tag add <file> <
|
|
281
|
-
tas tag remove <file> <
|
|
282
|
-
tas tag list [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
|
-
<
|
|
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
|
|
294
|
-
├── index.js
|
|
396
|
+
├── cli.js # Commander-based CLI — all commands defined here
|
|
397
|
+
├── index.js # Core streaming upload/download pipeline
|
|
295
398
|
├── crypto/
|
|
296
|
-
│ └── encryption.js
|
|
399
|
+
│ └── encryption.js # AES-256-GCM + PBKDF2-SHA512 (600k iterations)
|
|
297
400
|
├── db/
|
|
298
|
-
│ └── index.js
|
|
401
|
+
│ └── index.js # SQLite index: files, chunks, tags, shares, sync
|
|
299
402
|
├── telegram/
|
|
300
|
-
│ └── client.js
|
|
403
|
+
│ └── client.js # Bot API wrapper — retry, rate-limit, streaming
|
|
301
404
|
├── fuse/
|
|
302
|
-
│ └── mount.js
|
|
405
|
+
│ └── mount.js # FUSE filesystem — mount Telegram as a local folder
|
|
303
406
|
├── share/
|
|
304
|
-
│ └── server.js
|
|
407
|
+
│ └── server.js # HTTP server — expiring encrypted share links
|
|
305
408
|
├── sync/
|
|
306
|
-
│ └── sync.js
|
|
409
|
+
│ └── sync.js # fs.watch folder watcher — Dropbox-style auto-sync
|
|
307
410
|
└── utils/
|
|
308
|
-
├──
|
|
309
|
-
├──
|
|
310
|
-
├──
|
|
311
|
-
├──
|
|
312
|
-
├──
|
|
313
|
-
|
|
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
|
-
|
|
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
|
|
325
|
-
| 📌 **49 MB
|
|
326
|
-
| 📌 **Single-user** | Designed for personal use.
|
|
327
|
-
| 📌 **FUSE = Linux/macOS** | Mount
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
483
|
+
PRs welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
343
484
|
|
|
344
|
-
|
|
485
|
+
---
|
|
345
486
|
|
|
346
|
-
##
|
|
487
|
+
## 🌟 Contributing
|
|
347
488
|
|
|
348
|
-
|
|
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
|
-
|
|
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
|
-
|
|
496
|
+
---
|
|
359
497
|
|
|
360
|
-
|
|
498
|
+
## 📄 License
|
|
499
|
+
|
|
500
|
+
MIT — use it, fork it, ship it, sell it. Do whatever you want with it.
|
|
361
501
|
|
|
362
|
-
|
|
363
|
-
- 💡 **Have an idea?** [Start a discussion](https://github.com/ixchio/tas/issues)
|
|
364
|
-
- 🔧 **Want to contribute?** Fork → Branch → PR → 🎉
|
|
502
|
+
---
|
|
365
503
|
|
|
366
|
-
|
|
504
|
+
## Related Projects
|
|
367
505
|
|
|
368
|
-
|
|
506
|
+
If TAS fits your workflow, you might also find these useful:
|
|
369
507
|
|
|
370
|
-
|
|
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,
|
|
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>
|