An easy-to-host PDS on the ATProtocol, iPhone and MacOS. Maintain control of your keys and data, always.
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(relay): OAuth authorization endpoint + neobrutal consent UI (MM-76) #43

Summary#

  • Implements GET /oauth/authorize — validates client_id, redirect_uri, response_type, code_challenge_method; renders a neobrutal server-rendered consent page showing the client app name and requested scopes
  • Implements POST /oauth/authorize — re-validates all params against the DB (tamper-resistant hidden fields), generates a 43-char base64url auth code stored in oauth_authorization_codes with a 60-second TTL, redirects to redirect_uri?code=...&state=...; denial redirects with error=access_denied
  • Adds store_authorization_code and get_single_account_did to db/oauth.rs
  • Adds Bruno collection entries for GET and POST (seq: 13 and seq: 14)
  • 21 new tests across DB and route layers

![OAuth consent page](https://raw.githubusercontent.com/malpercio-dev/ezpds/refs/heads/malpercio/mm-76-oauth-authorization-endp oint-consent-ui/.playwright-mcp/oauth_consent_screenshot.png)

Yellow badge, cream background, thick black borders with offset shadow, monospaced scope tags, green APPROVE / white DENY buttons.

Security notes#

  • redirect_uri is validated against the client's registered redirect_uris before any redirect is issued — unknown clients and mismatched URIs return an HTML error page, never a redirect
  • POST handler re-validates client_id and redirect_uri from the DB regardless of form field values (hidden fields could be tampered)
  • PKCE code_challenge_method must be exactly S256; plain is rejected
  • Auth codes are single-use, expire after 60 seconds

Test plan#

  • cargo test -p relay oauth_authorize — 15 route tests pass
  • cargo test -p relay db::oauth — 6 DB tests pass
  • cargo clippy --workspace -- -D warnings — no warnings
  • GET /oauth/authorize with a registered client renders the consent page in a browser
  • Approving redirects back to redirect_uri with code= and state= params
  • Denying redirects back with error=access_denied
  • Unknown client_id returns 400 HTML error (no redirect)
  • Mismatched redirect_uri returns 400 HTML error (no redirect)
  • code_challenge_method=plain redirects with error=invalid_request
Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:web:malpercio.dev/sh.tangled.repo.pull/3mho55ybgqn22
Diff #0

No differences found between the selected revisions.

History

1 round 0 comments
sign up or login to add to the discussion
malpercio.dev submitted #0
patch application failed: error: No valid patches in input (allow with "--allow-empty")
expand 0 comments