Secure flashcards
https://pwdflash.vitapavlik.cz/
- HTML 41.9%
- Python 25.7%
- CSS 16%
- JavaScript 15%
- Shell 0.8%
- Other 0.6%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| static | ||
| templates | ||
| .gitignore | ||
| app.py | ||
| auth.py | ||
| config.py | ||
| docker-compose.yml | ||
| Dockerfile | ||
| entrypoint.sh | ||
| flashcards.py | ||
| LICENSE.txt | ||
| models.py | ||
| prompt.txt | ||
| README.md | ||
| requirements.txt | ||
pwdflash
pwdflash is a secure, containerized web application for flashcards that supports both regular flashcards and secret flashcards containing sensitive data (such as passwords, API keys, or PIN codes).
Live Deployment: https://pwdflash.vitapavlik.cz/
Features
- Secret & Regular Flashcards:
- Secret Cards: Values are salted with a 256-bit hex string and hashed server-side using Argon2id. Cleartext values are never stored or logged, and hashes are strictly hidden from client responses. Server-side rate limiting throttles failed verification attempts (default max 2 attempts per 20 minutes).
- Regular Cards: Checked client-side with cleartext input and immediate answer feedback.
- Collections & Multi-Select: Group flashcards into collections, bulk-select cards to add/remove from collections, or bulk-import via CSV.
- Interactive Study Session: Default card shuffling,
Alt+Xtemporary secret text reveal shortcut, auto-focus next card progression, and completion summary statistics. - Account Security: Multi-user support, Argon2 hard password hashing, and optional TOTP 2FA (32-byte Base32 secret, SHA256 algorithm).
- Responsive Aesthetics: Glassmorphic dark/light UI, responsive mobile navigation with hamburger menu, and custom configurable app branding.
Technology Stack
- Backend: Python 3.12, Flask, Flask-SQLAlchemy, Flask-Login, Argon2 (
argon2-cffi), PyOTP, Gunicorn - Database: SQLite
- Frontend: HTML5, Vanilla CSS, Vanilla JavaScript (zero JS external dependencies)
- Container: Docker based on
debian:trixie-slim
Deployment Steps
1. Clone the Repository
git clone https://github.com/example/pwdflash.git
cd pwdflash
2. Create Data Directory
mkdir -p pwdflash_data
3. Run with Docker Compose
docker compose up --build -d
The container starts Gunicorn listening on port 5000 (mapped to host port 5050 by default in docker-compose.yml). On startup, it automatically generates a 32-byte Flask secret key (pwdflash_data/secret_key) and configuration file (pwdflash_data/config.py).
4. Reverse Proxy Setup (Nginx Example)
Configure your reverse proxy (such as Nginx or Caddy) to proxy HTTP traffic to the application container:
server {
server_name pwdflash.vitapavlik.cz;
location / {
proxy_pass http://127.0.0.1:5050;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Configuration
Custom settings can be configured in ./pwdflash_data/config.py:
APP_NAME = "pwdflash"
VIBE_CODED_TEXT = "vibe-coded with gemini flash"
SOURCE_CODE_URL = "https://github.com/example/pwdflash"
SECRET_CHECK_MAX_ATTEMPTS = 2
SECRET_CHECK_WINDOW_MINUTES = 20