v0.12.43 minor protection added
This commit is contained in:
@@ -241,10 +241,18 @@ router.get('/:id', authMiddleware, async (req, res) => {
|
||||
WHERE eug.event_id=$1 AND ugm.user_id=$2
|
||||
`, [event.id, req.user.id]));
|
||||
if (event.track_availability && (itm || isMember)) {
|
||||
event.availability = await query(req.schema, `
|
||||
SELECT ea.response, ea.note, ea.updated_at, u.id AS user_id, u.name, u.first_name, u.last_name, u.display_name, u.avatar
|
||||
// User responses
|
||||
const userAvail = await query(req.schema, `
|
||||
SELECT ea.response, ea.note, ea.updated_at, u.id AS user_id, u.name, u.first_name, u.last_name, u.display_name, u.avatar, FALSE AS is_alias
|
||||
FROM event_availability ea JOIN users u ON u.id=ea.user_id WHERE ea.event_id=$1
|
||||
`, [req.params.id]);
|
||||
// Alias responses (Guardian Only mode)
|
||||
const aliasAvail = await query(req.schema, `
|
||||
SELECT eaa.response, eaa.note, eaa.updated_at, ga.id AS alias_id, ga.first_name, ga.last_name, ga.avatar, ga.guardian_id, TRUE AS is_alias
|
||||
FROM event_alias_availability eaa JOIN guardian_aliases ga ON ga.id=eaa.alias_id WHERE eaa.event_id=$1
|
||||
`, [req.params.id]);
|
||||
event.availability = [...userAvail, ...aliasAvail];
|
||||
|
||||
if (itm) {
|
||||
const assignedRows = await query(req.schema, `
|
||||
SELECT DISTINCT u.id AS user_id, u.name, u.first_name, u.last_name, u.display_name
|
||||
@@ -253,11 +261,42 @@ router.get('/:id', authMiddleware, async (req, res) => {
|
||||
JOIN users u ON u.id=ugm.user_id
|
||||
WHERE eug.event_id=$1
|
||||
`, [req.params.id]);
|
||||
const respondedIds = new Set(event.availability.map(r => r.user_id));
|
||||
const noResponseRows = assignedRows.filter(r => !respondedIds.has(r.user_id));
|
||||
// Also include alias members
|
||||
const assignedAliases = await query(req.schema, `
|
||||
SELECT DISTINCT ga.id AS alias_id, ga.first_name, ga.last_name
|
||||
FROM event_user_groups eug
|
||||
JOIN alias_group_members agm ON agm.user_group_id=eug.user_group_id
|
||||
JOIN guardian_aliases ga ON ga.id=agm.alias_id
|
||||
WHERE eug.event_id=$1
|
||||
`, [req.params.id]);
|
||||
const respondedUserIds = new Set(userAvail.map(r => r.user_id));
|
||||
const respondedAliasIds = new Set(aliasAvail.map(r => r.alias_id));
|
||||
const noResponseRows = [
|
||||
...assignedRows.filter(r => !respondedUserIds.has(r.user_id)),
|
||||
...assignedAliases.filter(r => !respondedAliasIds.has(r.alias_id)).map(r => ({ ...r, is_alias: true })),
|
||||
];
|
||||
event.no_response_count = noResponseRows.length;
|
||||
event.no_response_users = noResponseRows;
|
||||
}
|
||||
|
||||
// Detect if event targets the players group (for responder select dropdown)
|
||||
const playersRow = await queryOne(req.schema, "SELECT value FROM settings WHERE key='feature_players_group_id'");
|
||||
const playersGroupId = parseInt(playersRow?.value);
|
||||
event.has_players_group = !!(playersGroupId && event.user_groups?.some(g => g.id === playersGroupId));
|
||||
|
||||
// Detect if event targets the guardians group (so guardian shows own name in select)
|
||||
const guardiansRow = await queryOne(req.schema, "SELECT value FROM settings WHERE key='feature_guardians_group_id'");
|
||||
const guardiansGroupId = parseInt(guardiansRow?.value);
|
||||
event.in_guardians_group = !!(guardiansGroupId && event.user_groups?.some(g => g.id === guardiansGroupId) &&
|
||||
(await queryOne(req.schema, 'SELECT 1 FROM user_group_members WHERE user_group_id=$1 AND user_id=$2', [guardiansGroupId, req.user.id])));
|
||||
|
||||
// Return current user's aliases for the responder dropdown (Guardian Only)
|
||||
if (event.has_players_group) {
|
||||
event.my_aliases = await query(req.schema,
|
||||
'SELECT id,first_name,last_name,avatar FROM guardian_aliases WHERE guardian_id=$1 ORDER BY first_name,last_name',
|
||||
[req.user.id]
|
||||
);
|
||||
}
|
||||
}
|
||||
const mine = await queryOne(req.schema, 'SELECT response, note FROM event_availability WHERE event_id=$1 AND user_id=$2', [req.params.id, req.user.id]);
|
||||
event.my_response = mine?.response || null;
|
||||
@@ -564,19 +603,31 @@ router.put('/:id/availability', authMiddleware, async (req, res) => {
|
||||
const event = await queryOne(req.schema, 'SELECT * FROM events WHERE id=$1', [req.params.id]);
|
||||
if (!event) return res.status(404).json({ error: 'Not found' });
|
||||
if (!event.track_availability) return res.status(400).json({ error: 'Availability tracking not enabled' });
|
||||
const { response, note } = req.body;
|
||||
const { response, note, aliasId } = req.body;
|
||||
if (!['going','maybe','not_going'].includes(response)) return res.status(400).json({ error: 'Invalid response' });
|
||||
const trimmedNote = note ? String(note).trim().slice(0, 20) : null;
|
||||
const itm = await isToolManagerFn(req.schema, req.user);
|
||||
const inGroup = await queryOne(req.schema, `
|
||||
SELECT 1 FROM event_user_groups eug JOIN user_group_members ugm ON ugm.user_group_id=eug.user_group_id
|
||||
WHERE eug.event_id=$1 AND ugm.user_id=$2
|
||||
`, [event.id, req.user.id]);
|
||||
if (!inGroup && !itm) return res.status(403).json({ error: 'You are not assigned to this event' });
|
||||
await exec(req.schema, `
|
||||
INSERT INTO event_availability (event_id,user_id,response,note,updated_at) VALUES ($1,$2,$3,$4,NOW())
|
||||
ON CONFLICT (event_id,user_id) DO UPDATE SET response=$3, note=$4, updated_at=NOW()
|
||||
`, [event.id, req.user.id, response, trimmedNote]);
|
||||
|
||||
if (aliasId) {
|
||||
// Alias response (Guardian Only mode) — verify alias belongs to current user
|
||||
const alias = await queryOne(req.schema, 'SELECT id FROM guardian_aliases WHERE id=$1 AND guardian_id=$2', [aliasId, req.user.id]);
|
||||
if (!alias) return res.status(403).json({ error: 'Alias not found or not yours' });
|
||||
await exec(req.schema, `
|
||||
INSERT INTO event_alias_availability (event_id,alias_id,response,note,updated_at) VALUES ($1,$2,$3,$4,NOW())
|
||||
ON CONFLICT (event_id,alias_id) DO UPDATE SET response=$3, note=$4, updated_at=NOW()
|
||||
`, [event.id, aliasId, response, trimmedNote]);
|
||||
} else {
|
||||
// Regular user response
|
||||
const itm = await isToolManagerFn(req.schema, req.user);
|
||||
const inGroup = await queryOne(req.schema, `
|
||||
SELECT 1 FROM event_user_groups eug JOIN user_group_members ugm ON ugm.user_group_id=eug.user_group_id
|
||||
WHERE eug.event_id=$1 AND ugm.user_id=$2
|
||||
`, [event.id, req.user.id]);
|
||||
if (!inGroup && !itm) return res.status(403).json({ error: 'You are not assigned to this event' });
|
||||
await exec(req.schema, `
|
||||
INSERT INTO event_availability (event_id,user_id,response,note,updated_at) VALUES ($1,$2,$3,$4,NOW())
|
||||
ON CONFLICT (event_id,user_id) DO UPDATE SET response=$3, note=$4, updated_at=NOW()
|
||||
`, [event.id, req.user.id, response, trimmedNote]);
|
||||
}
|
||||
res.json({ success: true, response, note: trimmedNote });
|
||||
} catch (e) { res.status(500).json({ error: e.message }); }
|
||||
});
|
||||
@@ -593,7 +644,14 @@ router.patch('/:id/availability/note', authMiddleware, async (req, res) => {
|
||||
|
||||
router.delete('/:id/availability', authMiddleware, async (req, res) => {
|
||||
try {
|
||||
await exec(req.schema, 'DELETE FROM event_availability WHERE event_id=$1 AND user_id=$2', [req.params.id, req.user.id]);
|
||||
const { aliasId } = req.query;
|
||||
if (aliasId) {
|
||||
const alias = await queryOne(req.schema, 'SELECT id FROM guardian_aliases WHERE id=$1 AND guardian_id=$2', [aliasId, req.user.id]);
|
||||
if (!alias) return res.status(403).json({ error: 'Alias not found or not yours' });
|
||||
await exec(req.schema, 'DELETE FROM event_alias_availability WHERE event_id=$1 AND alias_id=$2', [req.params.id, aliasId]);
|
||||
} else {
|
||||
await exec(req.schema, 'DELETE FROM event_availability WHERE event_id=$1 AND user_id=$2', [req.params.id, req.user.id]);
|
||||
}
|
||||
res.json({ success: true });
|
||||
} catch (e) { res.status(500).json({ error: e.message }); }
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user