fix(invites): build share URL on the client, not the server
server/invites.ts derived the share URL from c.req.url — i.e., from the API request's host. In production the API and SPA share an origin so this happened to work; in dev where the SPA runs on :5173 and the API on :3000, the generated link pointed at the API (http://localhost:3000/invite/<token>) which serves nothing. Fix: the server no longer returns a `url` field. The token is the canonical artefact; the SPA builds the share link itself via `${window.location.origin}/invite/${token}`, which is always the right origin regardless of split-process dev or single-process prod. - shared/types.ts: InviteEntry.url removed - server/invites.ts: drop originOf() and the URL field in toEntry() - frontend Profile.svelte: new inviteUrl() helper; the displayed <code> and the clipboard payload both use it - tests/social.test.ts: assertion checks token shape instead of the URL field 93 tests still pass.
This commit is contained in:
parent
9b825bfe1d
commit
e64d5450f8
4 changed files with 27 additions and 16 deletions
|
|
@ -167,13 +167,22 @@
|
|||
}
|
||||
}
|
||||
|
||||
/** Build the shareable invite URL using the SPA's own origin. The server
|
||||
* used to compute this but in dev that yielded the API host (port 3000),
|
||||
* not the SPA host (port 5173). The token is the canonical artefact;
|
||||
* the URL is just a presentation concern the SPA owns. */
|
||||
function inviteUrl(inv: InviteEntry): string {
|
||||
return `${window.location.origin}/invite/${inv.token}`;
|
||||
}
|
||||
|
||||
async function copyInviteUrl(inv: InviteEntry) {
|
||||
const url = inviteUrl(inv);
|
||||
try {
|
||||
await navigator.clipboard.writeText(inv.url);
|
||||
await navigator.clipboard.writeText(url);
|
||||
copiedToken = inv.token;
|
||||
setTimeout(() => { copiedToken = null; }, 1500);
|
||||
} catch {
|
||||
window.prompt('Kopier denne lenken:', inv.url);
|
||||
window.prompt('Kopier denne lenken:', url);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -372,7 +381,7 @@
|
|||
{#each invites as inv (inv.token)}
|
||||
<article class="card" style="margin-top: 0.5rem; {inv.claimed_at ? 'opacity: 0.7;' : ''}">
|
||||
<div class="row" style="justify-content: space-between;">
|
||||
<code style="font-size: 0.8rem; word-break: break-all;">{inv.url}</code>
|
||||
<code style="font-size: 0.8rem; word-break: break-all;">{inviteUrl(inv)}</code>
|
||||
<span class="muted" style="white-space: nowrap;">{formatDate(inv.created_at)}</span>
|
||||
</div>
|
||||
<div class="row" style="margin-top: 0.5rem;">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue