Skip to content

feat(auth-service): add /_internal/account/create for community DIDs#6

Merged
daveselfsurf merged 1 commit into
mainfrom
feat/community-dids-rebased
Jun 11, 2026
Merged

feat(auth-service): add /_internal/account/create for community DIDs#6
daveselfsurf merged 1 commit into
mainfrom
feat/community-dids-rebased

Conversation

@daveselfsurf

Copy link
Copy Markdown
Collaborator

Adds a headless, no-OTP account-creation endpoint (POST /_internal/account/create) for service callers that provision accounts server-to-server (e.g. community DIDs). Gated by a new per-client can_create_directly permission, off by default. scripts/create-api-client.mjs gains --can-create-directly to grant it.

This supersedes the original feat/community-dids branch, which was cut from an old main and would have reverted ~1,740 lines of already-merged work (Mastodon OAuth, profile import, the pdsadmin/ CLI). This branch is that single feature commit rebased onto current main — net diff is 369 insertions / 6 deletions across 6 files, touching no merged work.

Reviewer note — migration ordering (load-bearing): on the old branch the can_create_directly column was migration v11, which now collides with main's Mastodon-tables v11 + profile v12. It has been moved to v13 and made idempotent (guards on PRAGMA table_info before the ALTER), matching the existing v12 Mastodon backstop. This is required: production DBs that already ran the old v11 (the column is already present on the live self.surf volume) would otherwise crash startup with "duplicate column name".

Verification

  • pnpm build clean (tsc --build all packages)
  • pnpm test — 1039 passed (73 files), incl. migration + new headless-account suites
  • lint + prettier clean on changed files

(Pre-existing on main, not addressed here: a require()-import lint error in db-mastodon.test.ts and 5 prettier warnings — flagging so they're not attributed to this PR.)

🤖 Generated with Claude Code

Adds a headless, no-OTP account-creation endpoint so service callers can
provision community DIDs — accounts that represent a community or group
rather than a single human, and so have no inbox to receive an OTP.

The endpoint mirrors the existing /_internal/otp/* and /_internal/recovery/*
handlers (same x-api-key auth, allowedOrigins, and rate limiting) and reuses
handleSignup() for the invite-mint + createAccount path. It is gated behind a
new can_create_directly permission — NOT can_signup — because skipping the
email-OTP step is a stronger capability than ordinary signup, so it is off by
default. A v11 migration adds the can_create_directly column to api_clients
(default 0), and create-api-client.mjs gains a --can-create-directly flag.

The handle is validated identically to the OAuth signup flow via
validateLocalPart (5-20 chars, single-label, ATProto-spec-valid); the caller-
supplied email is treated as opaque since no mail is sent for these accounts.
@daveselfsurf daveselfsurf merged commit 7a59664 into main Jun 11, 2026
0 of 5 checks passed
@daveselfsurf daveselfsurf deleted the feat/community-dids-rebased branch June 11, 2026 15:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant