Accounts Service

Login and Session

Where the unified login entry, OAuth callback, sessions, me, and logout sit in the downcity flow of @downcity/services.

The accounts service owns the shared account tables, better-auth runtime, OAuth callback, sessions, profiles, and City user_token issuance. Concrete login methods are provider-driven.

How to think about login entry points

Product login is a unified state machine:

  • providers
  • login/start
  • login/continue
  • login/result

In a typical downcity flow, providers tells the frontend which login methods are actually enabled on the current City and whether each method uses the oauth or input flow. login/start creates a login attempt and returns the next step. login/continue submits input for input-based methods. login/result is the single place to read the final user_token.

GET /v1/accounts/providers is a client-facing enabled list. Providers that are mounted in code but missing required env or runtime configuration are not returned. Use the Federation env catalog or admin workspace to discover what still needs to be configured.

The oauth flow returns an authorization URL from login/start. The input flow returns the current step inputs from login/start; email uses email/password. Local Account is also an input flow, but with an empty inputs array, and login/start immediately returns status: "done". In every case, read the token from login/result.

The official accounts service can expose email, GitHub, Google, and WeChat Website App login depending on mounted providers and server-side configuration. The frontend should always trust providers instead of hardcoding login buttons.

If you want to actually wire up Google login next, continue with Google Login Setup.

If you want to actually wire up WeChat website login next, continue with WeChat Login Setup.

me and logout

These already belong to logged-in user context, not guest access.

const me = await user.service("accounts").get("me");

await user.service("accounts").action("logout").invoke();

Why session still matters here

Even if the downcity mainly uses user_token to call City later, the account system still needs:

  • better-auth auth tables
  • a session table
  • login-state facts
  • downcity-facing profile data

That is why the service is not just "a few routes," but a minimal account infrastructure layer.

Mounting AccountsService does not make every login method available. Email login requires an email provider with a verification-email sender. OAuth login requires the matching OAuth provider and its client credentials.

What me returns now

GET /v1/accounts/me no longer returns only the runtime user. It also returns:

  • profile: downcity-facing display data such as display name and avatar

That keeps product clients and admin tools from reconstructing user state directly from auth rows.