-- Phase 2: Subsonic REST API support. -- -- Adds the Subsonic permission model to users, per-user music folder -- restrictions, and a recoverable (encrypted, not plaintext) copy of the -- password for legacy token/salt authentication (t = md5(password+salt)), -- which is mathematically impossible to verify against a one-way Argon2id -- hash alone. ALTER TABLE users ADD COLUMN role_settings INTEGER NOT NULL DEFAULT 1; ALTER TABLE users ADD COLUMN role_stream INTEGER NOT NULL DEFAULT 1; ALTER TABLE users ADD COLUMN role_download INTEGER NOT NULL DEFAULT 1; ALTER TABLE users ADD COLUMN role_upload INTEGER NOT NULL DEFAULT 0; ALTER TABLE users ADD COLUMN role_playlist INTEGER NOT NULL DEFAULT 1; ALTER TABLE users ADD COLUMN role_cover_art INTEGER NOT NULL DEFAULT 1; ALTER TABLE users ADD COLUMN role_comment INTEGER NOT NULL DEFAULT 1; ALTER TABLE users ADD COLUMN role_podcast INTEGER NOT NULL DEFAULT 0; ALTER TABLE users ADD COLUMN role_share INTEGER NOT NULL DEFAULT 1; ALTER TABLE users ADD COLUMN role_jukebox INTEGER NOT NULL DEFAULT 0; ALTER TABLE users ADD COLUMN role_video_conversion INTEGER NOT NULL DEFAULT 0; -- Encrypted (AES-GCM, server-side key) copy of the current password, -- refreshed whenever the plaintext is available (login, password set/ -- change). Never store the plaintext itself. NULL for accounts with no -- local password (external-auth-only), which therefore cannot use -- Subsonic token/password authentication until a local password is set. ALTER TABLE users ADD COLUMN subsonic_auth_secret TEXT; -- Per-user music folder restriction. No rows for a user means -- unrestricted (sees every folder) -- the common case. CREATE TABLE user_music_folders ( user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE, music_folder_id TEXT NOT NULL REFERENCES music_folders(id) ON DELETE CASCADE, PRIMARY KEY (user_id, music_folder_id) );