Skip to content
34 linesCodeBlameRaw
1/**
2 * Deleting accounts, as a person's page and the Deleted accounts page show
3 * it: what went with an account, what stands in the way of deleting one,
4 * and what staff type to confirm. Identity checks all of it again. No
5 * Workers imports, so it can be tested under Node.
6 */
7import type { AccountDeletion, AccountWent } from "@g1t/contracts";
8
9const plural = (n: number, one: string, many: string) => `${n} ${n === 1 ? one : many}`;
10
11/** What went with an account, in a line: "2 workspaces, 1 team, 3 repositories, 4 tokens, 1 SSH key". */
12export function accountWentSummary(went: AccountWent): string {
13 return [
14 plural(went.workspaces, "workspace", "workspaces"),
15 plural(went.teams, "team", "teams"),
16 plural(went.repositories, "repository", "repositories"),
17 plural(went.tokens, "token", "tokens"),
18 plural(went.sshKeys, "SSH key", "SSH keys"),
19 ].join(", ");
20}
21
22/** Why staff cannot delete the account, in a sentence about it, or null. */
23export function staffDeletionRefusal(deletion: AccountDeletion): string | null {
24 if (deletion.protected) return `${deletion.username} is protected and can never be deleted.`;
25 const slugs = deletion.sole_owner_of.map((workspace) => workspace.slug);
26 if (slugs.length === 0) return null;
27 return `${deletion.username} is the only owner of ${slugs.length === 1 ? "1 workspace" : `${slugs.length} workspaces`}. Each needs another owner, or to be deleted by its owner, first.`;
28}
29
30/** Whether what staff typed is the username. Identity checks it again. */
31export function confirmsUsername(username: string, typed: string): boolean {
32 const value = typed.trim();
33 return value !== "" && value.toLowerCase() === username.toLowerCase();
34}