# PropelAuth

Lightweight, dependency-free, in-memory fake of the **PropelAuth Backend API**
over HTTP/JSON. Exercise backend user/org management with zero cost and zero
side effects.

Default port: `4825`

## Quick start

```js
import { PropelauthServer } from "./services/propelauth/src/server.js";

const server = new PropelauthServer(4825);
await server.start();
// ... run your app/tests ...
await server.stop();
```

Point the `@propelauth/node` SDK at it via `PROPELAUTH_AUTH_URL=http://127.0.0.1:4825`
and `PROPELAUTH_API_KEY=parlel`. All backend routes use `Authorization: Bearer <api-key>`:

```js
const res = await fetch("http://127.0.0.1:4825/api/backend/v1/user/", {
  method: "POST",
  headers: { Authorization: "Bearer parlel", "Content-Type": "application/json" },
  body: JSON.stringify({ email: "pa@parlel.dev", first_name: "Pro", last_name: "Pel" }),
});
const { user_id } = await res.json();
```

## Implemented operations

All `/api/backend/v1` routes require `Authorization: Bearer <api-key>`. State is
in-memory and ephemeral; ids are deterministic UUIDs.

### Users

- `POST /api/backend/v1/user/` — create a user → `{ user_id }`.
- `GET /api/backend/v1/user/:userId` — retrieve → `{ user_id, email, email_confirmed, … }`.
- `GET /api/backend/v1/user/email?email=` — look up by email.
- `GET /api/backend/v1/user/query` — paginated search (`{ total_users, users:[], has_more_results, … }`).
- `PUT /api/backend/v1/user/:userId` — update name / email / metadata / properties → `{}`.
- `DELETE /api/backend/v1/user/:userId` — remove → `{}`.

### Orgs

- `GET /api/backend/v1/org/` — list orgs (`{ total_orgs, orgs:[], … }`).
- `POST /api/backend/v1/org/` — create → `{ org_id }`.
- `GET /api/backend/v1/org/:orgId` — retrieve.

### Service & control endpoints (parlel extensions)

- `GET /` — service metadata.
- `GET /health` — `{ status: "ok" }`.
- `POST /__parlel/reset` — reset all in-memory state.
- `OPTIONS *` — CORS preflight (`204`).

## Access via MCP / preview URL

PropelAuth is an HTTP service, so in a sandbox it is exposed at its own Daytona
preview URL (not via MCP `parlel_execute`). Use the preview URL from the Connect
panel with the preview token header, and set `PROPELAUTH_AUTH_URL` to that host.

## Surface coverage

This emulator faithfully replicates the API surface most application code and agents exercise. Anything below the supported lines is either an intentional design choice for a fast, zero-cost local emulator (✓ By design) or a candidate for a future release (⟳ Roadmap) — never a silent inaccuracy.

Legend: ✅ fully supported · ◐ accepted (stored, not strictly enforced) · ✓ by design · ⟳ on the roadmap.

| Feature | Status |
| --- | --- |
| Users create / get (by id & email) / query / update / delete | ✅ Supported |
| Orgs create / list / get | ✅ Supported |
| Deterministic UUIDs | ✅ Supported |
| Frontend JWT / access-token validation, JWKS | ✓ By design — Any non-empty credential is accepted — no real secrets needed |
| Org memberships / roles / RBAC enforcement | ◐ Stored, not enforced |
| Magic links / invitations / email delivery | ✓ By design — Accepted, never delivered |
| API key validity enforcement | ✓ By design — Intentional for a local, zero-cost test emulator |
