diff --git a/CHANGELOG.md b/CHANGELOG.md index 24ccec0..30c40db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.30.3] - 2026-04-28 + +### Changed +- Birthdays: all family members can now view, edit, and delete any birthday entry regardless of who created it + ## [0.30.2] - 2026-04-28 ### Fixed diff --git a/package-lock.json b/package-lock.json index 87fdda9..422ea6f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "oikos", - "version": "0.30.2", + "version": "0.30.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "oikos", - "version": "0.30.2", + "version": "0.30.3", "license": "MIT", "dependencies": { "bcrypt": "^6.0.0", diff --git a/package.json b/package.json index c7d4466..b1618cf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "oikos", - "version": "0.30.2", + "version": "0.30.3", "description": "Self-hosted family planner - calendar, tasks, shopping, meal planning, budget and more. Private, open-source, no subscription.", "main": "server/index.js", "type": "module", diff --git a/server/routes/birthdays.js b/server/routes/birthdays.js index 6b80e71..f1b7337 100644 --- a/server/routes/birthdays.js +++ b/server/routes/birthdays.js @@ -22,9 +22,6 @@ function loadBirthday(id) { return db.get().prepare('SELECT * FROM birthdays WHERE id = ?').get(id); } -function loadBirthdayForUser(id, userId) { - return db.get().prepare('SELECT * FROM birthdays WHERE id = ? AND created_by = ?').get(id, userId); -} function sortHydrated(rows) { return rows @@ -37,8 +34,8 @@ router.get('/', (req, res) => { const userId = req.authUserId || req.session.userId; syncAllBirthdayReminders(db.get(), userId); - let sql = 'SELECT * FROM birthdays WHERE created_by = ?'; - const params = [userId]; + let sql = 'SELECT * FROM birthdays WHERE 1=1'; + const params = []; if (req.query.q) { sql += ' AND name LIKE ?'; @@ -60,7 +57,7 @@ router.get('/upcoming', (req, res) => { const userId = req.authUserId || req.session.userId; syncAllBirthdayReminders(db.get(), userId); const limit = Math.min(Math.max(parseInt(req.query.limit, 10) || 5, 1), 50); - const rows = db.get().prepare('SELECT * FROM birthdays WHERE created_by = ? ORDER BY name COLLATE NOCASE ASC').all(userId); + const rows = db.get().prepare('SELECT * FROM birthdays ORDER BY name COLLATE NOCASE ASC').all(); res.json({ data: sortHydrated(rows).slice(0, limit) }); } catch (err) { log.error('GET /upcoming error:', err); @@ -95,7 +92,7 @@ router.put('/:id', (req, res) => { try { const userId = req.authUserId || req.session.userId; const id = parseInt(req.params.id, 10); - const existing = loadBirthdayForUser(id, userId); + const existing = loadBirthday(id); if (!existing) return res.status(404).json({ error: 'Birthday not found.', code: 404 }); const checks = []; @@ -137,7 +134,7 @@ router.delete('/:id', (req, res) => { try { const userId = req.authUserId || req.session.userId; const id = parseInt(req.params.id, 10); - const existing = loadBirthdayForUser(id, userId); + const existing = loadBirthday(id); if (!existing) return res.status(404).json({ error: 'Birthday not found.', code: 404 }); db.transaction(() => {