Tasks 6.1–6.6. A local user can follow a user on another trails instance: WebFinger-resolve the handle, verify the target runs trails.cool via NodeInfo — checked against the ACTOR IRI's host, never the handle's domain (split-domain constraint) — record a Pending follow row, deliver a signed Follow. The §4 inbox listeners already settle (Accept) or drop (Reject) the row. - federation-outbound.server.ts: followRemoteActor / cancelRemoteFollow (Undo delivery) / listOutgoingRemoteFollows. Network steps (lookup, NodeInfo, delivery) injectable for offline integration tests. Software allowlist: trails-cool. - /follows/outgoing: follow-by-handle form + pending/accepted list + cancel; linked from the feed empty state; i18n en+de. Remote actors have no local profile page, so the remote Pending state lives here (the profile Pending button from locked accounts covers local). - /.well-known/trails-cool now publishes software: trails-cool (6.2). - Clear 4xx codes: invalid_handle, local_handle, remote_resolve_failed, not_trails (6.3). - Tests: handle-parser + allowlist units; integration suite for the Pending lifecycle (create/idempotent/refuse-non-trails/refuse- unresolvable/own-host/cancel+Undo) with injected network deps; e2e anonymous-redirect guard for the new page. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
23 lines
729 B
TypeScript
23 lines
729 B
TypeScript
import { API_VERSION } from "@trails-cool/api";
|
|
import { getOrigin } from "~/lib/config.server";
|
|
|
|
/**
|
|
* GET /.well-known/trails-cool
|
|
*
|
|
* Discovery endpoint for mobile apps and federation.
|
|
* Returns instance metadata including API version, name, and base URL.
|
|
*/
|
|
export function loader() {
|
|
const domain = process.env.DOMAIN ?? "localhost";
|
|
const origin = getOrigin();
|
|
|
|
return Response.json({
|
|
apiVersion: API_VERSION,
|
|
instanceName: domain,
|
|
apiBaseUrl: `${origin}/api/v1`,
|
|
// Software identity for trails-to-trails federation discovery
|
|
// (social-federation 6.2). NodeInfo (/nodeinfo/2.1) is the primary
|
|
// check; this is the trails-specific secondary signal.
|
|
software: "trails-cool",
|
|
});
|
|
}
|