Skip to content

atosz33/formatlane

Repository files navigation

Formatlane

Formatlane is a privacy-first browser toolkit for developers working with structured text, API payloads, snippets, and credentials. Most tools run entirely in the browser, while the optional backend provides account login, cloud snippet sync, and encrypted secret storage.

Features

  • JSON formatter, validator, path extractor, JSON Schema checker, CSV converter, YAML converter, and TypeScript interface generator.
  • YAML formatter, validator, path extractor, and JSON converter for common configuration-style YAML.
  • Text utilities for search, replace, casing, Base64, ROT13, word counts, and line/column inspection.
  • HTML formatter, sandboxed preview, entity encode/decode, XML-style validation, and basic accessibility checks.
  • SQL formatter, heuristic validator, dialect hints, table/parameter extraction, and SQL command cheatsheet.
  • XML validator, formatter, XPath runner, XSLT transformer, and implemented-subset XSD checker.
  • JWT decoder, registered claim inspector, timestamp checks, HS256 verification, and JWKS verification for common RSA/ECDSA algorithms.
  • Markdown previewer with tables, task lists, footnotes, generated table of contents, HTML export, and word count.
  • CSV formatter, delimiter switcher, row-length validator, table preview, and CSV-to-JSON conversion.
  • Regex tester with JavaScript execution, capture group inspection, engine compatibility notes, pattern library, and copyable snippets for several languages.
  • Diff checker with content type detection, structured formatting, line diff, character diff, and JSON structural diff.
  • Account workspace for local/cloud/mixed snippet storage, encrypted snippet passphrases, ZIP import/export, and account profile updates.

Architecture

The project is split into a React frontend and a FastAPI backend.

src/
  App.jsx                    App shell, routing, auth session checks
  tools/                     Workspace UI components
  utils/                     Parsers, validators, formatters, encryption helpers
  hooks/useLocalStorageState.js
  services/backendClient.js  Cookie-based API client
backend/
  app/main.py                FastAPI routes
  app/security.py            Argon2 password hashing and JWT helpers
  app/models.py              SQLAlchemy models
  app/schemas.py             Pydantic request/response schemas
docs/
  deployment/README.md       Production deployment details
  project-implementation-hu.md

Frontend state is stored in localStorage per workspace. Snippet encryption passphrases are stored only in sessionStorage, so users need to re-enter them in a new browser session.

Tech Stack

  • Frontend: React 19, Vite 7, JavaScript ES modules.
  • Backend: FastAPI, SQLAlchemy, Uvicorn, Pydantic.
  • Auth: HTTP-only cookie containing an HS256 JWT.
  • Password hashing: Argon2 via passlib.
  • Client-side encryption: WebCrypto AES-GCM with PBKDF2-SHA256.
  • Database: SQLite by default, configurable with DATABASE_URL.
  • Production deployment: GitHub Actions, nginx, Docker, certbot.

Getting Started

Prerequisites

  • Node.js 22 or compatible modern Node version.
  • npm.
  • Python 3.12.
  • Docker, optional but recommended for running the backend like production.

Install dependencies

npm install
python3 -m pip install -r backend/requirements.txt

Run the frontend

npm run dev

The Vite dev server normally runs at:

http://localhost:5173

Run the backend with Docker Compose

docker compose up --build

The backend is exposed locally at:

http://localhost:8001

Health check:

curl http://localhost:8001/health

Expected response:

{"status":"ok"}

Run the backend without Docker

DATABASE_URL=sqlite:///./tool_site.db \
JWT_SECRET=dev-only-change-me \
COOKIE_SECURE=false \
CORS_ORIGINS=http://localhost:5173,http://127.0.0.1:5173 \
uvicorn backend.app.main:app --reload --host 0.0.0.0 --port 8001

If the frontend should call a different backend URL, set:

VITE_API_BASE_URL=http://localhost:8001 npm run dev

Scripts

npm run dev       # start Vite
npm run build     # build frontend into dist/
npm run preview   # preview production frontend build
npm test          # run frontend utility tests and backend API tests

The test command runs:

  • node --test
  • python3 -m unittest discover backend/tests

Environment Variables

Frontend:

Variable Default Purpose
VITE_API_BASE_URL http://localhost:8001 Backend API base URL used by the browser client.

Backend:

Variable Default Purpose
DATABASE_URL sqlite:///./tool_site.db SQLAlchemy database URL.
JWT_SECRET dev-only-change-me HS256 JWT signing secret. Must be changed in production.
COOKIE_SECURE false Set to true behind HTTPS in production.
CORS_ORIGINS localhost Vite origins Comma-separated allowed browser origins.

Backend API

Main endpoints:

  • GET /health
  • POST /auth/register
  • POST /auth/login
  • POST /auth/logout
  • GET /me
  • PATCH /me/email
  • PATCH /me/password
  • GET /snippets
  • POST /snippets
  • PATCH /snippets/{snippet_id}
  • DELETE /snippets
  • DELETE /snippets/{snippet_id}
  • GET /secrets
  • POST /secrets
  • GET /export
  • DELETE /me

Authentication is cookie-based. Login and register set an HTTP-only formatlane_access_token cookie. The frontend tracks only whether a cookie-backed session appears valid; it does not read or store the JWT.

Privacy and Encryption

Formatlane is local-first by design.

  • Workspace input is stored in the browser's localStorage.
  • Local snippets are stored in browser localStorage.
  • Cloud snippets are stored through the backend only when the user is logged in and chooses cloud or mixed storage.
  • Snippet passphrases are session-only and are not uploaded.
  • Encrypted snippets and API secrets use AES-GCM in the browser before storage.
  • Cloud encrypted snippets and secrets upload ciphertext, salt, IV, and metadata only.

Encryption details:

  • KDF: PBKDF2-SHA256.
  • Iterations: 250,000.
  • Salt: 16 random bytes.
  • IV: 12 random bytes.
  • Cipher: AES-GCM with a 256-bit key.

Changing a passphrase does not re-encrypt existing snippets. Older encrypted snippets still require the passphrase used when they were saved. If that passphrase is lost, the app cannot recover the content.

ZIP export can contain plaintext snippets if the current passphrase can decrypt them during export.

Parser and Validator Notes

Several tools intentionally use lightweight built-in parsers or project-local parsers to keep the app small and browser-first.

  • JSON uses native JSON.parse plus extra heuristic error messages.
  • YAML is a custom subset parser for common config-style documents, not a full YAML 1.2 implementation.
  • Markdown is a custom renderer, not a full CommonMark implementation.
  • SQL formatting and validation are regex/heuristic based and do not replace a real database parser.
  • HTML formatting is token-based and XML-style validation is stricter than real browser HTML parsing.
  • CSV parsing supports common quoted fields, escaped quotes, CRLF/LF rows, multiline fields, and delimiters, but is not a full spreadsheet compatibility layer.
  • Curl import supports common request-building options, not every curl flag.

Use the built-in validators as fast developer feedback. For production-critical validation, verify with the official parser/runtime for the target format, database, or platform.

Deployment

Production deployment is automated with GitHub Actions in:

.github/workflows/deploy.yml

The deployment model:

  • Frontend is built by Vite and uploaded to /var/www/tool-site/current.
  • Backend source is uploaded to /opt/tool-site/backend.
  • Backend runs in Docker on 127.0.0.1:8001.
  • nginx serves the frontend and reverse-proxies /api/ to the backend.
  • certbot issues TLS certificates for the configured domain.
  • SQLite data is stored in a Docker named volume and is not synced from CI.

Required GitHub Actions secrets:

Secret Purpose
DEPLOY_HOST Server IP address or hostname.
DEPLOY_USER Linux deploy user.
DEPLOY_DOMAIN Public domain for nginx and TLS.
DEPLOY_ROOT_PASSWORD Root SSH password for first bootstrap.
DEPLOY_SSH_PRIVATE_KEY Private key used by Actions after bootstrap.
CERTBOT_EMAIL Let's Encrypt email.
JWT_SECRET Stable production JWT signing secret.

Server requirements:

  • Clean Ubuntu/Debian-like server.
  • DNS A record for DEPLOY_DOMAIN pointing at DEPLOY_HOST.
  • Ports 22, 80, and 443 open.
  • Root SSH password login available for the first bootstrap.

See the full deployment guide:

docs/deployment/README.md

Production Safety Checklist

  • Set a long, random JWT_SECRET.
  • Keep JWT_SECRET stable across deployments; changing it logs users out.
  • Set COOKIE_SECURE=true behind HTTPS.
  • Restrict CORS_ORIGINS to the production domain.
  • Back up the Docker volume containing /data/tool_site.db.
  • Disable root password SSH after bootstrap if deploy key access works.
  • Monitor nginx, Docker, disk usage, and certificate renewal.

Documentation

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors