| 1 | /** |
| 2 | * A person's uploaded avatar by username, for the places that know who |
| 3 | * someone is only by name (components/ui/avatar.tsx): a redirect to the |
| 4 | * picture on the usercontent origin, or not found when they have none. |
| 5 | * People only: identity's profiles are accounts, never workspaces, so a |
| 6 | * workspace's icon is never drawn as a person's face. Public, as the |
| 7 | * profile is, and kept five minutes. |
| 8 | */ |
| 9 | import type { Route } from "./+types/avatar-user"; |
| 10 | import { avatarUrl } from "../components/ui/avatar"; |
| 11 | import { addresses } from "../lib/addresses.server"; |
| 12 | import { identity } from "../lib/services.server"; |
| 13 | |
| 14 | const CACHE = "public, max-age=300"; |
| 15 | |
| 16 | export async function loader({ params }: Route.LoaderArgs) { |
| 17 | const username = params.username; |
| 18 | const profile = /^[a-z0-9-]{1,39}$/i.test(username) ? await identity.profile(username).catch(() => null) : null; |
| 19 | if (!profile?.avatar) return new Response(null, { status: 404, headers: { "cache-control": CACHE } }); |
| 20 | return new Response(null, { |
| 21 | status: 302, |
| 22 | headers: { location: avatarUrl(profile.avatar, addresses().usercontent), "cache-control": CACHE }, |
| 23 | }); |
| 24 | } |