diff options
| -rw-r--r-- | lib/register.ts | 4 | ||||
| -rw-r--r-- | lib/reserved.ts | 31 | ||||
| -rw-r--r-- | routes/users.ts | 4 |
3 files changed, 35 insertions, 4 deletions
diff --git a/lib/register.ts b/lib/register.ts index e140947b..a9e9d7f7 100644 --- a/lib/register.ts +++ b/lib/register.ts @@ -4,6 +4,7 @@ import { db, s } from "$lib/db"; import { l, warn } from "$lib/logging"; import { fail } from "$lib/utils"; import { assertNameFree } from "$lib/names"; +import { isReserved } from "$lib/reserved"; import { bytesToHex, randomBytes } from "@noble/hashes/utils"; import { got } from "got"; import { getPublicKey, nip19 } from "nostr-tools"; @@ -16,12 +17,11 @@ export default async (user, ip) => { let { password, pubkey, username } = user; l("registering", username); - const reserved = ["ecash"]; if (!username) fail("Username required"); username = username.toLowerCase().replace(/\s/g, ""); if (!valid.test(username)) fail("Usernames can only have letters and numbers"); - if (reserved.includes(username)) fail("Invalid username"); + if (isReserved(username)) fail("Invalid username"); if (username.includes("undefined")) fail("Invalid username"); const id = v4(); diff --git a/lib/reserved.ts b/lib/reserved.ts new file mode 100644 index 00000000..df5f0d43 --- /dev/null +++ b/lib/reserved.ts @@ -0,0 +1,31 @@ +// Usernames nobody may register or rename into. A coinos username is also a +// lightning address, so a name that reads as ours lets an account collect +// payments meant for the service: "mint" was claimed within days of the ecash +// redesign freeing it (2026-09-18) and took payments addressed to +// [email protected] until it was renamed. +// +// Checked on registration (lib/register.ts) and on rename (routes/users.ts). +// Names already held by the v3 registrar are refused separately, by +// assertNameFree in lib/names.ts. +export const reserved = [ + "admin", + "administrator", + "ark", + "cash", + "coinos", + "ecash", + "fund", + "help", + "info", + "lightning", + "mint", + "pool", + "root", + "security", + "support", + "system", + "wallet", +]; + +export const isReserved = (username: string) => + reserved.includes(String(username || "").toLowerCase().replace(/\s/g, "")); diff --git a/routes/users.ts b/routes/users.ts index cbd2079d..431425b4 100644 --- a/routes/users.ts +++ b/routes/users.ts @@ -9,6 +9,7 @@ import { mail, templates } from "$lib/mail"; import { getNostrUser, getProfile, serverPubkey2 } from "$lib/nostr"; import register from "$lib/register"; import { assertNameFree } from "$lib/names"; +import { isReserved } from "$lib/reserved"; import { emit } from "$lib/sockets"; import upload from "$lib/upload"; import { bail, fail, fields, getUser, pick } from "$lib/utils"; @@ -271,11 +272,10 @@ export default { const { confirm, password, pin, newpin } = body; const username = body?.username?.toLowerCase().replace(/\s/g, ""); - const reserved = ["ecash"]; const valid = /^[\p{L}\p{N}]{2,24}$/u; if (!valid.test(username)) fail("Usernames can only have letters and numbers"); - if (reserved.includes(username)) fail("Invalid username"); + if (isReserved(username)) fail("Invalid username"); if (username?.includes("undefined")) fail("Invalid username"); let exists; |
