vinterliste/server
Ole-Morten Duesund 9b825bfe1d External profile links (max 5 per user)
Users can attach up to 5 labelled URLs to their profile — social
handles, blog, anything. They're shown on /<username>/list (the
opt-in public list), behind target="_blank" rel="noopener noreferrer
ugc" anchors so the destination tab can't script back into our
window.

Schema:
  - user_links(id, user_id, label, url, position, created_at)
    UNIQUE(user_id, position) to keep ordering stable, ON DELETE
    CASCADE so user deletion sweeps links.

Wire:
  - UserLink type (id/label/url)
  - MeResponse.links: UserLink[]
  - PublicListResponse.links: UserLink[]
  - ProfileUpdateRequest.links?: { label, url }[]  — bulk replace
  - USER_LINK_LIMITS exported so frontend constraints match server

Validation (server/auth.ts):
  - Label 1-40 chars, trimmed
  - URL parseable + http:// or https:// only (no javascript:, data:,
    mailto:, etc.)
  - URL ≤ 500 chars
  - Max 5 links per user

Bulk replace semantics with up-front validation, then DELETE +
INSERT inside the same transaction as the user UPDATE. A username
UNIQUE violation rolls back the link changes too — no half-applied
state. Empty rows in the request are silently dropped so users
can leave half-typed entries without a server rejection.

Frontend Profile gets an "Eksterne lenker" section between the
FriendsPanel and the Eksporter section. Five label+URL row pairs
with add/remove buttons, save button, error → Bokmål mapping
(link_label_required, link_url_bad_protocol, etc.).

93 tests still pass; typecheck clean; build ok.
2026-05-25 16:20:04 +02:00
..
activities.ts Friends + friends-only visibility + blocking 2026-05-25 14:47:20 +02:00
admin.ts Admin role, root/home URL split, activity permalinks 2026-05-25 13:23:13 +02:00
auth.ts External profile links (max 5 per user) 2026-05-25 16:20:04 +02:00
db.ts External profile links (max 5 per user) 2026-05-25 16:20:04 +02:00
feedback.ts fix(feedback): stop exposing done_by user id in API responses 2026-05-25 13:54:07 +02:00
friends.ts Friends + friends-only visibility + blocking 2026-05-25 14:47:20 +02:00
index.ts OpenGraph meta on the SPA's shareable routes 2026-05-25 16:05:43 +02:00
invites.ts Self-registry toggle, invite links with attribution, first-user-admin 2026-05-25 13:45:32 +02:00
og.ts OpenGraph meta on the SPA's shareable routes 2026-05-25 16:05:43 +02:00
roles.ts Admin role, root/home URL split, activity permalinks 2026-05-25 13:23:13 +02:00
session.ts Scaffold Vinterliste — end-to-end encrypted winter activity list 2026-05-25 12:27:14 +02:00
settings.ts Self-registry toggle, invite links with attribution, first-user-admin 2026-05-25 13:45:32 +02:00
tags.ts Scaffold Vinterliste — end-to-end encrypted winter activity list 2026-05-25 12:27:14 +02:00
users.ts External profile links (max 5 per user) 2026-05-25 16:20:04 +02:00