mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-12 20:16:15 -08:00
feat(settings): add PIN-protected parental lock for categories (#285)
Locks are per category (Xtream category ids, Stalker genre ids, M3U group titles) and kept in one renderer lock store persisted to app_state / localStorage; `categories.locked` is the SQLite index re-stamped from it. While the lock is active the DB worker filters every content read, the PWA data source, the Stalker store and the M3U channel list filter in memory, and the enforcement service reloads the stores and steps off withheld selections. Settings → Parental lock sets the PIN (PBKDF2, never in Settings), the relock timeout and Lock now; lock toggles live in the Xtream/M3U management dialogs and a new Stalker lock dialog, all behind the PIN. Backups carry the locks per playlist entry. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
17b8aa309d
commit
83e70a52c5
130 files changed
+6254
-278
No files matched your search
@@ -170,6 +170,7 @@ const CREATE_TABLE_STATEMENTS = [
|
||||
type TEXT NOT NULL CHECK (type IN ('live', 'movies', 'series')),
|
||||
xtream_id INTEGER NOT NULL,
|
||||
hidden INTEGER DEFAULT 0,
|
||||
locked INTEGER DEFAULT 0,
|
||||
UNIQUE(playlist_id, type, xtream_id),
|
||||
FOREIGN KEY (playlist_id) REFERENCES playlists (id) ON DELETE CASCADE
|
||||
)`,
|
||||
@@ -377,6 +378,8 @@ const CREATE_TABLE_STATEMENTS = [
|
||||
const COLUMN_MIGRATION_STATEMENTS = [
|
||||
// v1.0.0 -> v1.1.0: Add hidden column to categories for category management
|
||||
`ALTER TABLE categories ADD COLUMN hidden INTEGER DEFAULT 0`,
|
||||
// Parental lock: per-category lock index (issue #285)
|
||||
`ALTER TABLE categories ADD COLUMN locked INTEGER DEFAULT 0`,
|
||||
// v1.1.0 -> v1.2.0: Add playlist metadata/payload columns for M3U + unified playlist persistence
|
||||
`ALTER TABLE playlists ADD COLUMN portal_url TEXT`,
|
||||
`ALTER TABLE playlists ADD COLUMN count INTEGER`,
|
||||
|
||||
@@ -75,6 +75,11 @@ export const categories = sqliteTable(
|
||||
type: text('type', { enum: ['live', 'movies', 'series'] }).notNull(),
|
||||
xtreamId: integer('xtream_id').notNull(),
|
||||
hidden: integer('hidden', { mode: 'boolean' }).default(false),
|
||||
// Parental lock index: derived from the renderer's lock store (the
|
||||
// source of truth, keyed by provider category id) and re-stamped by
|
||||
// DB_SET_CATEGORY_LOCKS. While the lock is active every content read
|
||||
// in the worker filters on it — see parental-lock-state.ts.
|
||||
locked: integer('locked', { mode: 'boolean' }).default(false),
|
||||
},
|
||||
(table) => ({
|
||||
playlistIdx: index('idx_categories_playlist').on(table.playlistId),
|
||||
|
||||
Reference in new issue
Block a user