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
23 lines
986 B
JavaScript
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;
|
|
`);
|