Promptzy v2.0.0
Accounts, RLS, and Backup/Restore (security release, migration required)
Security release. Closes GHSA-x56f-9fqg-f568.
⚠️ Read before upgrading
Promptzy will look completely empty after you upgrade. Your prompts are still in your database, but they carry the old identifier and won't match your new account until you run one UPDATE. Nothing is deleted. Back up first:
CREATE TABLE prompts_backup_1x AS SELECT * FROM prompts;Then follow DOCS/MIGRATION-2.0.md. Takes about five minutes.
What happened
1.x let the browser pick its own user_id string, and the database policy that shipped with it allowed every operation to everyone (FOR ALL USING (true)). The app-side filter was a convenience, not a boundary. On top of that, 1.x shipped a hardcoded fallback Supabase project in the client bundle, so any install that never configured credentials was reading and writing a shared database with a key published in the npm package.
What changed
- Supabase Auth email/password accounts. Ownership is a verified JWT identity now, not a string the browser picks.
- Four ownership-scoped RLS policies, one per operation, each
TO authenticatedand checkingauth.uid()::text = user_id, withWITH CHECKon insert and update. REVOKE ALL ON prompts FROM anon, so unauthenticated requests are refused before RLS is consulted.- Hardcoded fallback project removed. No credentials means a setup screen, not a silent connection somewhere else.
- Delete now filters by owner as well as id.
- New: Backup & Restore in Settings. One-click JSON export, and an importer that reads both Promptzy's format and raw Supabase table rows.
- New: RLS enforcement probe in Settings → Diagnose, so you can confirm the old policy is gone.
VITE_SUPABASE_URL/VITE_SUPABASE_ANON_KEYare actually read now. Docker builds that set them were previously still landing on the fallback project.- 96-test Vitest suite covering credential resolution, prompt mapping, signed-out guards, error classification, backup/restore parsing, and the shipped SQL.
Breaking
- A Supabase project must be configured. There is no built-in database.
- An account is required, and existing rows must be re-pointed at it.
setCustomUserIdremoved.getPromptsFromSupabase/savePromptToSupabase/deletePromptFromSupabaserenamed togetPrompts/savePrompt/deletePrompt, with the writes returning{ ok, error }.getCurrentUserIdreturnsstring | null.
Full detail in the CHANGELOG.
Reported by @Tanjot-Singh-cyber.