Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889import { ClientResponseError } from "@atcute/client";import type { Did } from "@atcute/lexicons/syntax";import type { OAuthUserAgent } from "@atcute/oauth-browser-client";import { getOrCreateDelegatedSession } from "#lib/api/actAs.ts";import { provisionDelegate, type DelegationService } from "#lib/api/delegation.ts";import { ensureProfile, PROFILE_COLLECTION } from "#lib/api/profile.ts";import type { ProfileRecord } from "#lib/api/records.ts";import { isValidSubdomain, SUBDOMAIN_MAX_LENGTH, SUBDOMAIN_MIN_LENGTH } from "#lib/subdomain.ts";
export const ORG_PROFILE_MARKER: ProfileRecord = { $type: PROFILE_COLLECTION, isOrganization: true};
export interface OrgAccount { did: Did; handle: string;}
export interface CreatedOrg extends OrgAccount { warnings: string[];}
const validateOrgHandle = (raw: string, handleDomain: string | undefined): string => { if (!handleDomain) throw new Error("Organization creation isn't set up on this server."); const label = raw.trim().toLowerCase(); if (label.length < SUBDOMAIN_MIN_LENGTH || label.length > SUBDOMAIN_MAX_LENGTH) { throw new Error( `Use ${SUBDOMAIN_MIN_LENGTH}–${SUBDOMAIN_MAX_LENGTH} characters for the organization name.` ); } if (!isValidSubdomain(label)) { throw new Error( "Use only lowercase letters, digits, and hyphens in the organization name, and start and end it with a letter or digit." ); } return `${label}.${handleDomain}`;};
export const createOrgAccount = async ( agent: OAuthUserAgent, rawHandle: string, service: DelegationService): Promise<OrgAccount> => { const handle = validateOrgHandle(rawHandle, service.handleDomain);
const account = await provisionDelegate(agent, handle, service); return { did: account.did, handle: account.handle };};
const SETUP_FAILURES = { "organization session": "Unable to sign in to the organization account", "profile write": "Unable to save the organization's profile"} as const;
const detailOf = (cause: unknown): string => { const detail = cause instanceof ClientResponseError ? (cause.description ?? cause.error) : cause instanceof Error ? cause.message : String(cause); return detail.trim().replace(/\.$/, "");};
export const createOrg = async ( controllerAgent: OAuthUserAgent, rawHandle: string, service: DelegationService, existingOrg?: OrgAccount): Promise<CreatedOrg> => { const org = existingOrg ?? (await createOrgAccount(controllerAgent, rawHandle, service)); let step: keyof typeof SETUP_FAILURES = "organization session"; try { const orgAgent = await getOrCreateDelegatedSession(controllerAgent, org.did).catch(() => getOrCreateDelegatedSession(controllerAgent, org.did) ); step = "profile write"; await ensureProfile(orgAgent, ORG_PROFILE_MARKER); } catch (cause) { console.error(`organization setup failed at ${step}`, org.did, cause); return { ...org, warnings: [`${SETUP_FAILURES[step]} (${detailOf(cause)}).`] }; } return { ...org, warnings: [] };};