~ knotless Search/
↑↓ move↵ open⇧↵ all results

grain.social/grain

photography-focused photo sharing platform

grain.social
1 collaborator
0
2
22 lines · 1.2 KB Raw History
import { defineProcedure, InvalidRequestError } from "$hatk";
import { callGroupHost } from "../helpers/groupHost.ts";
import { acceptMembership, forgetRefusal } from "../helpers/membership.ts";

/** The first time Grain talks to a group host directly: ask to join. */
export default defineProcedure("social.grain.unspecced.joinGroup", async (ctx) => {
  const { input, ok, viewer } = ctx;
  if (!viewer) throw new InvalidRequestError("Sign in to join a group");
  const r = await callGroupHost(ctx.pds, input.group, "fyi.opensocial.requestJoin", {
    group: input.group,
    ...(input.message ? { message: input.message } : {}),
  });
  if (!r.ok)
    throw new InvalidRequestError(r.body?.message ?? `join failed (${r.status})`, r.body?.error);
  if (r.body.status !== "admitted") return ok({ status: "pending" });
  forgetRefusal(viewer.did, input.group);
  // The member's half of membership, and what lets grain find this group
  // again from their own PDS. A request that is still pending gets its
  // acceptance when the group page next sees them admitted (getGroup).
  await acceptMembership(ctx.pds, viewer.did, input.group).catch(() => {});
  return ok({ status: "admitted" });
});