Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions apps/key-manager/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
# Key Manager

WebAuthn key management service using `Handler.keyManager` from `tempo.ts`.
WebAuthn key management service using `Handler.webAuthn` from `accounts/server`.

## Endpoints

| Endpoint | Method | Purpose |
|----------|--------|---------|
| `/challenge` | GET | Generate a new WebAuthn challenge |
| `/:id` | GET | Retrieve the public key for a credential |
| `/:id` | POST | Register a new credential with its public key |
| `/register/options` | POST | Generate credential creation options |
| `/register` | POST | Verify registration and store a credential |
| `/login/options` | POST | Generate credential request options |
| `/login` | POST | Verify authentication |

## Development

Expand Down
9 changes: 7 additions & 2 deletions apps/key-manager/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "key-manager",
"type": "module",
"private": true,
"scripts": {
"build": "echo 'noop'",
Expand All @@ -8,15 +9,19 @@
"dev": "wrangler dev",
"deploy": "wrangler deploy",
"postinstall": "pnpm gen:types",
"gen:types": "wrangler types --env-interface='CloudflareBindings'"
"gen:types": "wrangler types --env-interface='CloudflareBindings'",
"test": "vitest --run"
},
"dependencies": {
"tempo.ts": "catalog:"
"accounts": "catalog:"
},
"devDependencies": {
"@cloudflare/vitest-pool-workers": "catalog:",
"@cloudflare/workers-types": "catalog:",
"@types/node": "catalog:",
"typescript": "catalog:",
"vite": "catalog:",
"vitest": "catalog:",
"wrangler": "catalog:"
}
}
8 changes: 6 additions & 2 deletions apps/key-manager/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { env } from 'cloudflare:workers'
import { Handler, Kv } from 'tempo.ts/server'
import { Handler, Kv } from 'accounts/server'

export default Handler.keyManager({
const origins = env.ALLOWED_ORIGINS.split(',').map((origin) => origin.trim())

export default Handler.webAuthn({
kv: Kv.cloudflare(env.KEY_STORE),
origin: origins.length === 1 ? origins[0] : origins,
rpId: env.RP_ID,
})
43 changes: 43 additions & 0 deletions apps/key-manager/test/routes.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { exports } from 'cloudflare:workers'
import { describe, expect, it } from 'vitest'

describe('key manager WebAuthn routes', () => {
it('serves register options on the route used by wagmi/tempo', async () => {
const response = await exports.default.fetch(
new Request('https://keys.test/register/options', {
method: 'POST',
headers: {
'content-type': 'application/json',
origin: 'https://tempo.xyz',
},
body: JSON.stringify({ name: 'alice' }),
}),
)

expect(response.status).toBe(200)
const body = (await response.json()) as {
options?: {
publicKey?: {
challenge?: string
rp?: { id?: string; name?: string }
user?: { name?: string }
}
}
}

expect(body.options?.publicKey?.challenge).toEqual(expect.any(String))
expect(body.options?.publicKey?.rp).toEqual({
id: 'tempo.xyz',
name: 'tempo.xyz',
})
expect(body.options?.publicKey?.user?.name).toBe('alice')
})

it('does not expose the legacy challenge route', async () => {
const response = await exports.default.fetch(
new Request('https://keys.test/challenge'),
)

expect(response.status).toBe(404)
})
})
15 changes: 15 additions & 0 deletions apps/key-manager/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { cloudflareTest } from '@cloudflare/vitest-pool-workers'
import { defineConfig } from 'vitest/config'

export default defineConfig({
test: {
include: ['test/**/*.test.ts'],
},
plugins: [
cloudflareTest({
wrangler: {
configPath: './wrangler.json',
},
}),
],
})
4 changes: 4 additions & 0 deletions apps/key-manager/wrangler.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
"workers_dev": true,
"preview_urls": true,
"keep_vars": true,
"vars": {
"ALLOWED_ORIGINS": "*",
"RP_ID": "tempo.xyz"
},
"observability": {
"enabled": true,
"logs": {
Expand Down
Loading
Loading