Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh
24 linesCodeBlameRaw
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 */
9import type { Route } from "./+types/avatar-user";
10import { avatarUrl } from "../components/ui/avatar";
11import { addresses } from "../lib/addresses.server";
12import { identity } from "../lib/services.server";
13
14const CACHE = "public, max-age=300";
15
16export 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}