fix: let user add ical

This commit is contained in:
Nathan FONTEYNE 2026-07-09 18:26:25 +02:00
parent 6de6cfacf2
commit 23fc039ac3
6 changed files with 257 additions and 19 deletions

View file

@ -166,6 +166,18 @@ async function removeFeed(feedId) {
await pool.query('DELETE FROM calendar_feeds WHERE id = $1', [feedId]);
}
// Scoped delete for the self-service "my calendars" endpoints — a user must
// only ever be able to delete their own feeds, never guess another user's
// feed id. Returns whether a row actually matched (both wrong id and
// someone-else's feed look identical from the caller's side: nothing deleted).
async function removeFeedForUser(feedId, userId) {
const { rowCount } = await pool.query('DELETE FROM calendar_feeds WHERE id = $1 AND user_id = $2', [
feedId,
userId,
]);
return rowCount > 0;
}
// Every app user (not just ones already on the calendar) with their
// registered feeds attached — lets an admin give someone their first feed,
// not just manage existing entries. The public getPeople() above deliberately
@ -227,6 +239,7 @@ module.exports = {
findFeedsForUser,
addFeed,
removeFeed,
removeFeedForUser,
getUsersWithFeeds,
getSlotSettings,
updateSlotSettings,

View file

@ -75,6 +75,43 @@ router.post(
})
);
// Self-service: any authenticated user manages their own calendar feeds here
// (no requireAdmin) — distinct from the /people/:id/feeds admin routes below,
// which let an admin manage anyone's feeds on their behalf.
router.get(
'/my-feeds',
asyncHandler(async (req, res) => {
const feeds = await calendarRepo.findFeedsForUser(req.user.id);
res.json(feeds.map((f) => ({ id: f.id, label: f.label, icsUrl: f.ics_url })));
})
);
router.post(
'/my-feeds',
asyncHandler(async (req, res) => {
const { label, icsUrl } = req.body || {};
if (!icsUrl || !icsUrl.trim()) {
return res.status(400).json({ error: 'ics_url_required' });
}
const feed = await calendarRepo.addFeed(req.user.id, {
label: label ? label.trim() : null,
icsUrl: icsUrl.trim(),
});
res.status(201).json({ id: feed.id, label: feed.label, icsUrl: feed.ics_url });
})
);
router.delete(
'/my-feeds/:feedId',
asyncHandler(async (req, res) => {
const deleted = await calendarRepo.removeFeedForUser(parseInt(req.params.feedId, 10), req.user.id);
if (!deleted) {
return res.status(404).json({ error: 'feed_not_found' });
}
res.status(204).end();
})
);
router.get(
'/people/admin',
requireAdmin,