From fdbb9326c174cf848417c6f05be71781a14796ad Mon Sep 17 00:00:00 2001 From: Daniel Date: Sun, 13 Sep 2026 15:29:50 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20accepting=20a=20share=20link=20failed=20?= =?UTF-8?q?=E2=80=94=20the=20insert=20helper=20adds=20RETURNING=20id=20and?= =?UTF-8?q?=20the=20shares=20table=20has=20no=20id?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU --- src/routes/myResources.js | 3 ++- test/backend-hardening.test.js | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/routes/myResources.js b/src/routes/myResources.js index 25e0db92..67d221a2 100644 --- a/src/routes/myResources.js +++ b/src/routes/myResources.js @@ -681,7 +681,8 @@ router.post('/my-resources/share-link/:token/accept', async function (req, res) var link = await liveShareLink(req.params.token); if (!link) return res.status(404).json({ error: 'That link is not valid any more' }); if (link.owner_id !== req.user.id) { - await db.run('INSERT INTO user_resource_shares (resource_id, user_id, shared_by) VALUES (?, ?, ?) ON CONFLICT DO NOTHING', + // db.run appends RETURNING id to an INSERT, and this table's key is (resource_id, user_id): no id column. + await db.query('INSERT INTO user_resource_shares (resource_id, user_id, shared_by) VALUES (?, ?, ?) ON CONFLICT DO NOTHING', [link.resource_id, req.user.id, link.owner_id]); await db.run('UPDATE user_resource_share_links SET accepted_count = accepted_count + 1 WHERE id = ?', [link.id]); logger.audit(req.user.id, 'resource_share_accept', 'Accepted a share of resource ' + link.resource_id, req, { category: 'clinical' }); diff --git a/test/backend-hardening.test.js b/test/backend-hardening.test.js index bef9d1ae..deecdd81 100644 --- a/test/backend-hardening.test.js +++ b/test/backend-hardening.test.js @@ -264,3 +264,9 @@ test('lockdown covers the sign-in provider too, and the exemption list names not assert.match(read('docs/authentication.md'), /## Lockdown: the admin panel as view-only/); assert.match(read('.env.example'), /# ADMIN_LOCKDOWN=false/); }); + +test('a share row is inserted through query, since run() appends RETURNING id and the table has no id', () => { + const src = read('src/routes/myResources.js'); + assert.doesNotMatch(src, /db\.run\(\s*'INSERT INTO user_resource_shares/); + assert.match(src, /db\.query\('INSERT INTO user_resource_shares/); +});