Skip to content

laikhtman/ProtectedText_API

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

5 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ” ProtectedText API

A zero-dependency, self-hosted REST API for encrypted notes β€”
plus a tool to rescue your data from protectedtext.com.

License: MIT Node.js β‰₯20 Python β‰₯3.10 Tests PRs Welcome zero deps

Features Β· Quick Start Β· Export Tool Β· API Β· Docs Β· Contributing


πŸ€” Why this exists

ProtectedText is brilliant β€” encrypted notes, no account, just a URL and password.
This project gives you the same idea on your own server, and a CLI tool to export everything you already have on protectedtext.com to plain files.

The server never sees your plaintext. Ever.


✨ Features

πŸ”’ Zero plaintext storage Ciphertext, IV, and salt only β€” the key never leaves the client
πŸ“¦ Zero npm dependencies Pure Node.js 20 built-ins, nothing to npm install
πŸ”‘ Scrypt-hashed auth tokens Client-derived tokens; the server stores only a salted hash
⚑ Optimistic concurrency Version-gated writes prevent silent overwrites
πŸ›‘οΈ IP rate limiting In-memory sliding window, configurable per deployment
πŸ“€ protectedtext.com exporter Reverse-engineered Argon2id + AES decryption for all site types
πŸ§ͺ Fully tested 5 automated tests, pure Node.js built-in test runner

πŸš€ Quick Start

Requirements: Node.js β‰₯ 20 β€” no other dependencies.

git clone https://github.com/laikhtman/ProtectedText_API.git
cd ProtectedText_API
npm start
βœ…  Listening on http://127.0.0.1:3000

That's it. No npm install. No Docker required.

Testing

npm test
βœ” creates a new site
βœ” rejects wrong auth token
βœ” rejects version mismatch
βœ” rate limiter blocks over-limit requests
βœ” rate limiter resets after window
β–Ά 5 tests passed (373ms)

πŸ“€ Export your data

Pull every tab from any protectedtext.com site and save each one as a .txt file β€” one command, no browser needed.

Requirements: Python β‰₯ 3.10. Dependencies are installed automatically on first run.

Single site

python export_site.py mysite
Site ID: mysite
Password: β€’β€’β€’β€’β€’β€’β€’β€’

πŸ”“ Decrypting...  βœ”  33 tabs decrypted (legacy AES)

πŸ“ Saved to mysite/
   β”œβ”€β”€ Shopping list.txt
   β”œβ”€β”€ Project ideas.txt
   β”œβ”€β”€ Work notes.txt
   └── ... 30 more

Batch export from a CSV

python export_site.py --import sites.csv

CSV format β€” no header row required:

siteId,password[,masterDirectory]
Column Required Description
1 β€” siteId βœ… The protectedtext.com site identifier
2 β€” password βœ… The site password
3 β€” masterDirectory optional Parent folder for output. Files go to <masterDir>/<siteId>/ instead of ./<siteId>/

Example sites.csv:

mynotes,secret123
worknotes,pass456,backup
family,pa$$w0rd,D:\exports

Running --import sites.csv on the above would create:

backup\worknotes\*.txt
D:\exports\family\*.txt
mynotes\*.txt

Each site is fetched independently β€” a failure on one site is reported and the batch continues.

A folder named after the site ID is created in your working directory.
Each tab becomes a .txt file named after the tab's first line (the title).

βœ… Supports both legacy (AES + plain password) and modern (Argon2id-chain, up to 10 iterations) protectedtext.com encryption.


πŸ“‘ API Reference

Method Endpoint Description
GET /health Server health check
GET /api/v1/sites/:siteId Fetch an encrypted note
PUT /api/v1/sites/:siteId Create or update an encrypted note
DELETE /api/v1/sites/:siteId Delete a note
GET /api/v1/sites/:siteId
GET /api/v1/sites/my-note
{
  "siteId": "my-note",
  "version": 1,
  "createdAt": "2026-04-24T08:00:00.000Z",
  "updatedAt": "2026-04-24T08:00:00.000Z",
  "ciphertext": "base64...",
  "iv": "base64...",
  "salt": "base64...",
  "algorithm": "aes-256-gcm",
  "kdf": "argon2id",
  "noteHash": "sha256..."
}
PUT /api/v1/sites/:siteId β€” create or update
PUT /api/v1/sites/my-note
Content-Type: application/json
{
  "ciphertext": "base64...",
  "iv": "base64...",
  "salt": "base64...",
  "algorithm": "aes-256-gcm",
  "kdf": "argon2id",
  "authToken": "client-derived-secret",
  "expectedVersion": 0,
  "noteHash": "sha256..."
}
  • expectedVersion: 0 β†’ create a new site
  • expectedVersion: N β†’ update; returns 409 Conflict on mismatch
DELETE /api/v1/sites/:siteId
DELETE /api/v1/sites/my-note
Content-Type: application/json
{
  "authToken": "client-derived-secret",
  "expectedVersion": 1
}

βš™οΈ Configuration

All configuration is via environment variables:

Variable Default Description
HOST 127.0.0.1 Bind address
PORT 3000 Port
DATA_FILE data/sites.json Persistent storage path
RATE_LIMIT_WINDOW_MS 60000 Rate limit window (ms)
RATE_LIMIT_MAX_REQUESTS 60 Max requests per window per IP
PORT=8080 DATA_FILE=/var/data/sites.json npm start

πŸ”’ Security model

  • Client-side encryption only β€” the server derives nothing from the password
  • Auth tokens β€” clients derive a token from their secret; server stores only a scrypt hash
  • No accounts β€” notes are addressed by siteId, not user identity
  • Timing-safe equality β€” auth comparison uses crypto.timingSafeEqual
  • Optimistic concurrency β€” version field prevents blind overwrites

See docs/security.md for a full breakdown and production hardening checklist.


πŸ—ΊοΈ Roadmap

  • OpenAPI 3 spec + Swagger UI
  • SQLite / PostgreSQL storage adapter
  • Docker + docker-compose
  • Browser client reference implementation
  • Distributed rate limiting (Redis)
  • Structured logging

Have an idea? Open an issue or submit a PR!


🀝 Contributing

Contributions, issues, and feature requests are welcome!
See CONTRIBUTING.md to get started.

  1. Fork the repo
  2. Create a feature branch β€” git checkout -b feature/amazing-feature
  3. Commit your changes
  4. Push to your fork and open a PR

πŸ“„ License

MIT Β© laikhtman β€” see LICENSE for details.


If this project helped you, please consider giving it a ⭐ β€” it helps others find it!

About

πŸ” Zero-dependency self-hosted REST API for encrypted notes + CLI tool to export your protectedtext.com sites to local files

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors