FTStore now holds both halves of the product:
ios/ the swift app — the fork of claration/Feather, unchanged apart
from its new home
web/ FTStore Admin, formerly its own repository. serves the
dashboard at /admin, the ftstore.json feed and IPA downloads
app-repo.json and Images/ stay at the repo root on purpose: the former is
a published AltStore source whose raw.githubusercontent URL is what
installed copies resolve updates through, so moving it would break every
subscriber.
The admin server is renamed throughout: package ftstore-admin, images
ghcr.io/<owner>/ftstore-admin-{app,worker}, postgres role/db ftstore,
session cookie ftstore_session, temp dir /tmp/ftstore, backup type
ftstore-settings, outbound user-agent FTStoreAdmin. backups written under the old
name still import, and compose is pinned to name: ftstore so the
volume prefix does not follow the directory name.
apply-rebrand.sh gains a relocation step: upstream's tree is rooted at
the repo root while ours lives in ios/, so a merge drops Feather's files
next to ios/ and the script folds them in before renaming. it never
touches web/. still idempotent.
release tags are namespaced — v* for the app, web-v* for the server —
so a server release no longer triggers a macOS build or rewrites
app-repo.json. workflows are prefixed ios-/web- and path-filtered.
2.8 KiB
2.8 KiB
Authentication
FTStore Admin uses a session-based authentication system with user approval flow.
How It Works
- Sessions: HTTP-only cookies (
ftstore_session) with 30-day expiry - Passwords: Hashed with scrypt (Node.js
cryptomodule, no external dependencies) - Middleware: Cookie-presence check on all routes (Edge-compatible, no DB calls)
- Route protection: API routes wrapped with
withAuth()/withAdmin()for DB-level auth
First-User Setup
- Navigate to the application — you'll be redirected to
/login - Click "Register" to create the first account
- The first user is automatically an admin and approved
- All subsequent users require admin approval before they can log in
User Approval Flow
- New user registers at
/register - They see a "pending approval" message
- An admin goes to Settings > Users tab
- Admin clicks the checkmark to approve the user
- The user can now log in
User Roles
| Role | Permissions |
|---|---|
admin |
Full access + user management (approve, role change, delete) |
user |
Access to all dashboard features |
Settings > Users Tab
Admins see a "Users" tab in Settings with:
- User list with role/status badges
- Approve/reject buttons
- Role toggle (admin/user)
- Delete user (with confirmation dialog)
Admins cannot demote themselves or delete their own account.
CLI User Management
For Docker deployments, manage users via CLI:
# Create a user
docker exec -it <container> npx tsx scripts/manage-users.ts create <username> <password>
# Create an admin user
docker exec -it <container> npx tsx scripts/manage-users.ts create <username> <password> --admin
# List all users
docker exec -it <container> npx tsx scripts/manage-users.ts list
# Approve a pending user
docker exec -it <container> npx tsx scripts/manage-users.ts approve <username>
# Change user role
docker exec -it <container> npx tsx scripts/manage-users.ts set-role <username> admin
# Reset password
docker exec -it <container> npx tsx scripts/manage-users.ts reset-password <username> <new-password>
# Delete a user
docker exec -it <container> npx tsx scripts/manage-users.ts delete <username>
API Endpoints
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /api/auth/register |
Public | Register new user |
| POST | /api/auth/login |
Public | Login |
| POST | /api/auth/logout |
Public | Logout (clears session) |
| GET | /api/auth/me |
Session | Current user info |
| GET | /api/users |
Admin | List users |
| PUT | /api/users |
Admin | Update user (approve, role) |
| DELETE | /api/users?id=N |
Admin | Delete user |
Session Cleanup
Expired sessions are automatically cleaned up when the cleanup action runs (Settings > Admin Actions > Run Cleanup, or via the worker's scheduled cleanup).