Files
hub/devices.js
T
nmemmertandClaude Sonnet 5.5 301e8017d9
build-container / build (push) Successful in 3m52s
Parent controls for children, name-tile sign-in, restricted Learn search, simple mode
- Sign-in page shows name tiles on remembered devices; tap a name, then PIN or passkey
- Music and Movies are separate on the server; Plex can be locked to a child's managed profile
- Activity log, weekly summary and alerts to parents; per-area and weekend limits
- Requests from children (Ask button) answered in Settings; bonus screen time from rewards
- Restricted Learn search (Simple English Wikipedia, blocked words) replaces web search for children
- Simple mode (big-button home) for young children or grandparents
- Child usage kept in memory instead of read from disk on every request
- Tests and README updated

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-26 16:49:48 -04:00

14 lines
1.5 KiB
JavaScript

// Trusted devices: a browser that is remembered on the sign-in page, so it shows name tiles. A family device (kind 'family') is a shared screen that opens
// on the family board and signs people out quickly; a 'trusted' one is a person's own device. Family devices: shared screens (a kitchen tablet, the family computer) that open on the family board instead of a sign-in. An admin makes a device one
// while signed in on it; the device keeps a signed cookie, and this list is what lets an admin switch one off again. Kept in DATA_DIR/devices.json.
const fs = require('fs'), path = require('path'), crypto = require('crypto');
const atomicWrite = require('./atomic');
const FILE = () => path.join(process.env.DATA_DIR || path.join(__dirname, 'data'), 'devices.json');
const load = () => { try { const j = JSON.parse(fs.readFileSync(FILE(), 'utf8')); return Array.isArray(j.devices) ? j.devices : []; } catch { return []; } };
const save = l => { fs.mkdirSync(path.dirname(FILE()), { recursive: true }); atomicWrite(FILE(), JSON.stringify({ devices: l }), { mode: 0o600 }); };
const has = id => load().some(d => d.id === id);
const get = id => load().find(d => d.id === id) || null;
const add = (name, by, kind = 'family', byId = '') => { const d = { id: crypto.randomBytes(9).toString('base64url'), name: String(name || (kind === 'family' ? 'Family device' : 'My device')).slice(0, 40), by, byId, kind, created: Date.now() }; save([...load(), d]); return d; };
const remove = id => save(load().filter(d => d.id !== id));
module.exports = { load, has, get, add, remove };