Address code review: fix escaping, guard nested groups, clarify error message

This commit is contained in:
copilot-swe-agent[bot] 2026-07-02 14:48:39 +00:00 committed by GitHub
parent 44ad3addf0
commit edd5dcab70
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 7 additions and 3 deletions

View file

@ -598,10 +598,10 @@ function renderLogsList(logs) {
const li = document.createElement('li'); const li = document.createElement('li');
li.className = 'acl-entry'; li.className = 'acl-entry';
const granted = !!log.granted; const granted = !!log.granted;
const cards = log.cardNumbers ? `, cards: ${log.cardNumbers}` : ''; const cards = log.cardNumbers ? `, cards: ${escapeHtml(log.cardNumbers)}` : '';
li.innerHTML = ` li.innerHTML = `
<span class="badge type-badge" style="background:${granted ? 'var(--success)' : 'var(--danger)'};">${granted ? 'Granted' : 'Denied'}</span> <span class="badge type-badge" style="background:${granted ? 'var(--success)' : 'var(--danger)'};">${granted ? 'Granted' : 'Denied'}</span>
<span class="acl-description">${escapeHtml(log.scannedAt)} user: ${escapeHtml(log.userId || 'unknown')}${escapeHtml(cards)}</span> <span class="acl-description">${escapeHtml(log.scannedAt)} user: ${escapeHtml(log.userId || 'unknown')}${cards}</span>
`; `;
list.appendChild(li); list.appendChild(li);
}); });

View file

@ -127,6 +127,10 @@ router.get('/:placeId/:accessPointId/onScan', async (req, res) => {
} }
const byGroup = {}; const byGroup = {};
for (const member of members) { for (const member of members) {
// Groups can only contain direct credentials (types 0-4); the API rejects
// nested groups on write, but skip any type 5 here too as defense-in-depth
// against infinite recursion if the database is ever modified directly.
if (member.type === 5) continue;
if (!byGroup[member.groupId]) byGroup[member.groupId] = []; if (!byGroup[member.groupId]) byGroup[member.groupId] = [];
byGroup[member.groupId].push(member); byGroup[member.groupId].push(member);
} }

View file

@ -407,7 +407,7 @@ router.post('/places/:placeId/access-groups/:groupId/members', loadOwnedPlace, l
} }
// Groups cannot contain other groups, to avoid nested/circular resolution. // Groups cannot contain other groups, to avoid nested/circular resolution.
if (parseInt(type, 10) === 5) { if (parseInt(type, 10) === 5) {
return res.status(400).json({ success: false, message: "An access group cannot contain another access group" }); return res.status(400).json({ success: false, message: "An access group cannot contain another access group, to prevent circular/nested resolution" });
} }
db.run(`INSERT INTO access_group_members (groupId, type, data) VALUES (?, ?, ?)`, [req.accessGroup.id, type, data], function (err) { db.run(`INSERT INTO access_group_members (groupId, type, data) VALUES (?, ?, ?)`, [req.accessGroup.id, type, data], function (err) {