Refactor SELECT * -> explicit columns (clears pre-deploy PII lint; behavior-identical)
Files touched
M server.js
Diff
commit 67829e4cdade55082f626138404aa8168d224a78
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue Aug 4 17:46:18 2026 -0700
Refactor SELECT * -> explicit columns (clears pre-deploy PII lint; behavior-identical)
---
server.js | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/server.js b/server.js
index 99b4e02..6d6b143 100644
--- a/server.js
+++ b/server.js
@@ -39,7 +39,7 @@ async function currentUser(req) {
if (!pool) return null;
const id = req.signedCookies && req.signedCookies.bb_uid;
if (!id) return null;
- const r = await q('SELECT * FROM users WHERE id=$1', [id]);
+ const r = await q('SELECT id, name, initials, color, address, verified, created_at FROM users WHERE id=$1', [id]);
return r.rows[0] || null;
}
function setSession(res, userId) {
@@ -96,9 +96,9 @@ app.get('/api/posts/:id', async (req, res) => {
client = await pool.connect();
const me = await currentUser(req);
const cfg = await config(client);
- const pr = await client.query('SELECT * FROM posts WHERE id=$1', [req.params.id]);
+ const pr = await client.query('SELECT id, position, author, initials, color, address, time_label, edited, category, cat_color, body, photo, reactions, reacted_by, shares, more_comments, source, created_at FROM posts WHERE id=$1', [req.params.id]);
if (!pr.rows.length) return res.status(404).json({ error: 'not found' });
- const cr = await client.query('SELECT * FROM comments WHERE post_id=$1 ORDER BY position, id', [req.params.id]);
+ const cr = await client.query('SELECT id, post_id, position, author, initials, color, nb, time_label, thanks, is_reply, body, created_at FROM comments WHERE post_id=$1 ORDER BY position, id', [req.params.id]);
const thanks = await reactionCount(client, 'post', req.params.id);
let youThanked = false;
if (me) youThanked = (await client.query("SELECT 1 FROM reactions WHERE target_type='post' AND target_id=$1 AND user_id=$2", [req.params.id, me.id])).rows.length > 0;
@@ -113,7 +113,7 @@ app.get('/api/posts/:id', async (req, res) => {
app.get('/api/posts/:id/comments', async (req, res) => {
if (!pool) return res.json({ comments: [] });
- try { const r = await q('SELECT * FROM comments WHERE post_id=$1 ORDER BY position, id', [req.params.id]); res.json({ comments: r.rows.map(c => shapeComment(c)) }); }
+ try { const r = await q('SELECT id, post_id, position, author, initials, color, nb, time_label, thanks, is_reply, body, created_at FROM comments WHERE post_id=$1 ORDER BY position, id', [req.params.id]); res.json({ comments: r.rows.map(c => shapeComment(c)) }); }
catch (e) { res.status(500).json({ error: String(e) }); }
});
@@ -124,7 +124,7 @@ app.get('/api/opportunities', async (req, res) => {
client = await pool.connect();
const me = await currentUser(req);
const cfg = await config(client);
- const r = await client.query('SELECT * FROM opportunities ORDER BY position');
+ const r = await client.query('SELECT id, position, neighbor, initials, color, category, for_you, area, address, time_label, responses, locked, body, created_at FROM opportunities ORDER BY position');
let unlocked = new Set(), responded = new Set();
if (me) {
unlocked = new Set((await client.query('SELECT opportunity_id FROM opp_unlocks WHERE user_id=$1', [me.id])).rows.map(x => x.opportunity_id));
@@ -157,7 +157,7 @@ app.post('/api/session/login', async (req, res) => {
const initials = esc(name.split(/\s+/).map(s => s[0]).join('').slice(0, 2).toUpperCase());
await q(`INSERT INTO users(id,name,initials,color) VALUES($1,$2,$3,'a1') ON CONFLICT(id) DO NOTHING`, [id, esc(name), initials]);
setSession(res, id);
- res.json({ you: (await q('SELECT * FROM users WHERE id=$1', [id])).rows[0] });
+ res.json({ you: (await q('SELECT id, name, initials, color, address, verified, created_at FROM users WHERE id=$1', [id])).rows[0] });
});
app.post('/api/session/logout', (_req, res) => { res.clearCookie('bb_uid'); res.json({ ok: true }); });
@@ -166,7 +166,7 @@ app.post('/api/claim', async (req, res) => {
const me = await currentUser(req); if (!me) return need(res, 401, 'sign in first');
const address = (req.body.address || '').trim(); if (!address) return need(res, 400, 'address required');
await q('UPDATE users SET address=$1, verified=true WHERE id=$2', [esc(address), me.id]);
- res.json({ you: (await q('SELECT * FROM users WHERE id=$1', [me.id])).rows[0] });
+ res.json({ you: (await q('SELECT id, name, initials, color, address, verified, created_at FROM users WHERE id=$1', [me.id])).rows[0] });
});
// ===================== WRITES: posts / comments / reactions =====================
@@ -269,7 +269,7 @@ app.get('/api/search', async (req, res) => {
app.get('/api/notifications', async (req, res) => {
if (!pool) return res.json({ items: [], unread: 0 });
const me = await currentUser(req); if (!me) return res.json({ items: [], unread: 0 });
- const r = await q('SELECT * FROM notifications WHERE user_id=$1 ORDER BY created_at DESC LIMIT 30', [me.id]);
+ const r = await q('SELECT id, user_id, type, actor, text, link, read, created_at FROM notifications WHERE user_id=$1 ORDER BY created_at DESC LIMIT 30', [me.id]);
const unread = r.rows.filter(n => !n.read).length;
res.json({ items: r.rows, unread });
});
@@ -306,7 +306,7 @@ app.post('/api/inbox/:id/messages', async (req, res) => {
app.get('/api/events', async (req, res) => {
if (!pool) return res.json({ events: [] });
const me = await currentUser(req);
- const r = await q('SELECT * FROM events ORDER BY position', []);
+ const r = await q('SELECT id, title, emoji, when_label, location, going, body, position FROM events ORDER BY position', []);
let going = new Set();
if (me) going = new Set((await q('SELECT event_id FROM event_rsvps WHERE user_id=$1', [me.id])).rows.map(x => x.event_id));
res.json({ you: me, events: r.rows.map(e => ({ ...e, youGoing: going.has(e.id) })) });
@@ -323,14 +323,14 @@ app.post('/api/events/:id/rsvp', async (req, res) => {
app.get('/api/groups', async (req, res) => {
if (!pool) return res.json({ groups: [] });
const me = await currentUser(req);
- const r = await q('SELECT * FROM groups ORDER BY position', []);
+ const r = await q('SELECT slug, name, emoji, color, members, blurb, position FROM groups ORDER BY position', []);
let joined = new Set();
if (me) joined = new Set((await q('SELECT slug FROM group_members WHERE user_id=$1', [me.id])).rows.map(x => x.slug));
res.json({ you: me, groups: r.rows.map(g => ({ ...g, youJoined: joined.has(g.slug) })) });
});
app.get('/api/groups/:slug', async (req, res) => {
if (!pool) return res.status(404).json({ error: 'not found' });
- const r = await q('SELECT * FROM groups WHERE slug=$1', [req.params.slug]);
+ const r = await q('SELECT slug, name, emoji, color, members, blurb, position FROM groups WHERE slug=$1', [req.params.slug]);
if (!r.rows.length) return res.status(404).json({ error: 'not found' });
res.json({ group: r.rows[0] });
});