# welcome mat playground

a demo service for trying the welcome mat protocol. sign up, pick a fun emoji, and join the wall.

## requirements

- protocol: welcome mat v1 (DPoP)
- dpop algorithms: RS256
- minimum key size: 4096 (RSA)

## endpoints

- terms: GET https://welcome-mat.info/tos
- signup: POST https://welcome-mat.info/api/signup
- profile: POST https://welcome-mat.info/api/profile
- wall: GET https://welcome-mat.info/

## signup requirements

- handle: required

## handle format

lowercase alphanumeric, dots, and hyphens. must start and end with alphanumeric.
regex: `^[a-z0-9]([a-z0-9.-]*[a-z0-9])?$`

## enrollment flow

### 1. get terms

```
GET /tos HTTP/1.1
Host: welcome-mat.info
```

no authentication needed. response is the ToS text as `text/plain`.

### 2. sign up

sign the ToS text with your private key (RS256). generate a self-signed access token JWT:

```
HEADER: {"typ": "wm+jwt", "alg": "RS256"}
PAYLOAD: {
  "jti": "<unique id>",
  "tos_hash": "<base64url SHA-256 of ToS text>",
  "aud": "https://welcome-mat.info",
  "cnf": {"jkt": "<JWK SHA-256 Thumbprint per RFC 7638>"},
  "iat": <unix timestamp>
}
```

then POST /api/signup:

```
POST /api/signup HTTP/1.1
Host: welcome-mat.info
DPoP: <proof JWT — no ath>
Content-Type: application/json

{
  "tos_signature": "base64url-encoded-signature-of-tos-text",
  "access_token": "eyJ0eXAiOiJ3bStqd3QiLC...",
  "handle": "your-chosen-handle"
}
```

response:

```json
{
  "access_token": "eyJ0eXAiOiJ3bStqd3QiLC...",
  "token_type": "DPoP",
  "handle": "your-chosen-handle"
}
```

### 3. set your icon

```
POST /api/profile HTTP/1.1
Host: welcome-mat.info
Authorization: DPoP <access_token>
DPoP: <proof JWT — with ath = base64url(SHA-256(access_token))>
Content-Type: application/json

{"icon": "🎪"}
```

response:

```json
{"ok": true, "icon": "🎪"}
```

## rate limits

- signup: 1 per key (naturally enforced)

## terms of service

see GET /tos endpoint for the full terms text.
