~james/core

core/web/src/lib/api/handle.ts -rw-r--r-- 1.8 KiB
452f17b7 — james chore(import): snapshot james.dad.town/core at f70c71c7696a 15 hours ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import { ClientResponseError, ok } from "@atcute/client";
import { mainSchema as describeServerSchema } from "@atcute/atproto/types/server/describeServer";
import { mainSchema as updateHandleSchema } from "@atcute/atproto/types/identity/updateHandle";
import type { Handle } from "@atcute/lexicons/syntax";
import type { OAuthUserAgent } from "@atcute/oauth-browser-client";
import { createClient } from "#lib/auth/agent.ts";
import { missingPermissions, type Permission } from "#lib/auth/scopes.ts";
import { clear } from "#lib/api/cache.ts";
import { sentence } from "#lib/format.ts";

const HANDLE_PERMISSION: Permission = { resource: "identity", attr: "handle" };

export const canChangeHandle = (agent: OAuthUserAgent): boolean =>
	missingPermissions(agent.session.token.scope, [HANDLE_PERMISSION]).length === 0;

export const handleDomains = async (agent: OAuthUserAgent): Promise<string[]> => {
	const { availableUserDomains } = await ok(createClient(agent).call(describeServerSchema, {}));
	return availableUserDomains.map((domain) => (domain.startsWith(".") ? domain : `.${domain}`));
};

export const HANDLE_TAKEN = "This handle is taken. Choose another one.";

const updateHandleError = (cause: ClientResponseError): string => {
	if (cause.error === "HandleNotAvailable") return HANDLE_TAKEN;
	if (cause.error === "InvalidHandle") return "This handle isn't allowed. Choose another one.";
	if (cause.description) return sentence(cause.description);
	return "Could not change your handle. Try again.";
};

export const updateHandle = async (agent: OAuthUserAgent, handle: Handle): Promise<void> => {
	try {
		await ok(createClient(agent).call(updateHandleSchema, { input: { handle } }));
	} catch (cause) {
		if (cause instanceof ClientResponseError) {
			throw new Error(updateHandleError(cause), { cause });
		}
		throw cause;
	}
	clear();
};