pediatric-ai-scribe-v3/migrations/1781400000000_resource-share-links.js
Daniel c7864f763e
Some checks failed
Forgejo Docker Build / Root app tests (push) Successful in 56s
Forgejo Docker Build / Build Docker image (push) Successful in 10s
Forgejo Docker Build / End-to-end (browser) (push) Failing after 12s
feat: sharing is by link — follow it, accept, and it is in your resources
The author presses "Copy a share link" and sends it however they like.
Whoever follows it (app.pedshub.com/#share=<token>) is signed in first if
need be — the token survives the trip through the SSO — then shown what it
is and who from, and adds it with one press. Only the token's hash is
stored; a link lasts 30 days and can be withdrawn; accepting twice is
harmless; the owner following their own link changes nothing. Sharing by
email is gone: nobody is looked up by address. "Everyone signed in" stays
as a switch.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU
2026-09-13 15:20:35 +02:00

23 lines
986 B
JavaScript

// Sharing by link. The author makes a link; whoever follows it, signed in,
// accepts, and the resource joins their library as a share (a row in
// user_resource_shares, exactly as before). Only the hash of the token is
// stored, so a database read does not hand out working links; a link can be
// given an expiry and withdrawn.
exports.up = pgm => pgm.sql(`
CREATE TABLE IF NOT EXISTS user_resource_share_links (
id SERIAL PRIMARY KEY,
resource_id INTEGER NOT NULL REFERENCES user_resources(id) ON DELETE CASCADE,
token_hash TEXT NOT NULL UNIQUE,
created_by INTEGER REFERENCES users(id) ON DELETE SET NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
expires_at TIMESTAMPTZ,
revoked_at TIMESTAMPTZ,
accepted_count INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX IF NOT EXISTS idx_resource_share_links_resource ON user_resource_share_links (resource_id);
`);
exports.down = pgm => pgm.sql(`
DROP TABLE IF EXISTS user_resource_share_links;
`);