Browser dashboard
Opaque HttpOnly sessions authenticate account, project, channel, and dashboard-message routes. Every mutation also sends an in-memory, session-bound CSRF token.
A Spring Boot API separates session-authenticated browser management from project-key-authenticated external messaging, backed by durable relational resources and expiring Redis queue data.
Security boundaries
Opaque HttpOnly sessions authenticate account, project, channel, and dashboard-message routes. Every mutation also sends an in-memory, session-bound CSRF token.
Only /messages and /messages/poll accept a project Bearer key. Raw keys are shown once; the backend persists their SHA-256 hashes.
Request flow
Browser dashboard External service
Session cookie + CSRF Bearer project key
│ │
└──────────────┬──────────────────┘
▼
Spring Boot API
│ │
▼ ▼
MySQL resources Redis queue data
users/projects payload string + TTL
channels/key hash sorted-set member IDs
│
▼
inspect or poll (non-destructive)Storage
| Store | Use in BlinkQ |
|---|---|
| MySQL | Durable users, projects, channel definitions, and hashed project API keys |
| Redis sessions | Opaque browser sessions used by dashboard routes |
| Redis strings | Message payload records with millisecond TTL expiry |
| Redis sorted sets | Per-channel retained member IDs ordered by priority and timestamp |
| Redis cache | Short-lived API-key-hash to project lookups |
| Redis Pub/Sub | Internal new-message wake-up signal; not a browser or consumer subscription API |
Queue semantics
Priority 5 sorts first; older timestamps sort first among records with the same priority.
Payload keys expire in Redis. The browser receives an approximate remaining TTL in milliseconds.
Dashboard inspection and external polling do not consume, acknowledge, or remove live records.
The sorted-set count can temporarily include IDs whose payload keys have expired.
Missing and foreign project/channel IDs both appear as not found to avoid leaking ownership.
Project creation and rotation are the only responses that reveal a raw API key.
API surface
| Method | Path | Behavior |
|---|---|---|
| GET | /auth/csrf | Bootstrap a session-bound CSRF token |
| POST | /auth/signup · /auth/signin | Create or authenticate a user session |
| GET | /projects · /channels | Read owned dashboard resources |
| POST | /projects · /channels | Create owned resources with session + CSRF |
| GET | /channels/{id}/messages | Inspect up to 100 retained records non-destructively |
| POST | /channels/{id}/messages | Publish from the authenticated dashboard |
| GET | /channels/{id}/stats | Read approximate retained membership |
| POST | /messages | External Bearer-key publish |
| GET | /messages/poll | External Bearer-key non-destructive poll |
The current API does not provide acknowledgement/consume operations, retries, dead-letter queues, bulk publishing, external WebSocket/SSE delivery, per-key rate limiting, or durable message history. Polling can return the same retained record more than once.
Create an account and project, save its one-time key, add a channel, and publish from the dashboard or external API.
Create account