Маленький приватный сервис для обмена файлами: залил файл → сгенерировал ссылку на скачивание → отправил. Устанавливается как PWA, удобно с телефона.
- Регистрация email + пароль с подтверждением по почте, восстановление пароля, опциональный TOTP 2FA (включается в профиле).
- Загрузка нескольких файлов разом, с прогресс-баром; файл живёт, пока владелец не удалит его вручную — авто-удаления по TTL нет.
- Ссылка на скачивание — самостоятельная сущность: генерируется заново при каждом Copy/Share со своим сроком жизни (пресеты 1ч/24ч/7д/30д, дефолт настраивается в профиле). У одного файла может быть одновременно несколько активных ссылок с разными сроками — например, разным получателям разный TTL на один и тот же файл. Список файлов показывает число активных ссылок и число скачиваний, а не обратный отсчёт.
- Скачивание по ссылке — без регистрации и авторизации.
- Список файлов: фильтр по имени, сортировка по имени/размеру/дате, множественное выделение и bulk-удаление.
- Квота на аккаунт (объём хранилища и число файлов) — с дефолтами и настраивается администратором глобально.
- Admin-панель (Users/Files/Settings): бан/удаление пользователей, удаление любых файлов, изменение квот. Первый админ бутстрапится из переменных окружения
ADMIN_EMAIL/ADMIN_PASSWORD. - Rate limiting на login/register/password-reset/download (защита от брутфорса и подбора токена скачивания); на upload лимита нет — он и так ограничен квотой аккаунта.
- PWA: устанавливается на телефон/десктоп, offline app-shell через service worker.
- Хранилище — S3-совместимое (MinIO), доступ к файлам только через backend-прокси (стриминг upload/download), отдельного домена/presigned-URL на файлы нет.
- Backend: Node.js + TypeScript, Fastify, Prisma + SQLite,
@aws-sdk/client-s3/lib-storageдля потокового upload/download в S3. - Frontend: Vite + vanilla TypeScript (без фреймворка), устанавливаемый PWA.
cd deploy
cp .env.example .env # задать MINIO_ROOT_PASSWORD
docker compose up -d # поднимает MinIO
cd backend
cp .env.example .env # подставить S3/JWT/SMTP значения под локальный MinIO
npm install
npm run prisma:migrate
npm run dev # tsx watch, http://localhost:3000
cd frontend
npm install
npm run dev # vite, проксирует /auth, /files, /d на backend
Домен filestash.undoo.ru, деплой через GitLab CI (.gitlab-ci.yml) на сервер savant: backend — Docker-контейнер в /opt/filestash, статика фронтенда — /var/www/filestash, за NPM (nginx-proxy-manager) + host nginx.
Архитектура, история решений и разбор инцидентов — в проекте filestash в Marrow.