Skip to content

Commit 55deade

Browse files
authored
Merge Add JWKS support, OIDC compliance, and scalability enhancements pull request #7 from mjunaidca/auth-server
feat(auth): Add JWKS support, OIDC compliance, and scalability enhancements
2 parents fa6a7a3 + f9587e4 commit 55deade

File tree

84 files changed

+13184
-27
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+13184
-27
lines changed

.claude/skills/engineering/better-auth-setup/SKILL.md

Lines changed: 576 additions & 0 deletions
Large diffs are not rendered by default.

.mcp.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
"@playwright/mcp@latest"
2121
],
2222
"env": {}
23+
},
24+
"better-auth": {
25+
"type": "http",
26+
"url": "https://mcp.chonkie.ai/better-auth/better-auth-builder/mcp"
2327
}
2428
}
2529
}

auth-server/.env.example

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Database (Neon Postgres)
2+
DATABASE_URL=postgresql://user:[email protected]/dbname?sslmode=require
3+
4+
# Better Auth
5+
BETTER_AUTH_SECRET=your-secret-key-minimum-32-characters-long
6+
BETTER_AUTH_URL=http://localhost:3001
7+
8+
# CORS - Allowed origins (comma-separated)
9+
ALLOWED_ORIGINS=http://localhost:3000,https://your-production-domain.com
10+
11+
# Auth server URL (for client-side)
12+
NEXT_PUBLIC_BETTER_AUTH_URL=http://localhost:3001
13+
14+
# OAuth: Pre-configured public client callback URL (for production)
15+
# Default: http://localhost:3000/auth/callback (development)
16+
# ROBOLEARN_INTERFACE_CALLBACK_URL=https://your-production-domain.com/auth/callback
17+
18+
# Email Configuration (choose one provider)
19+
# Common: FROM address used by all providers
20+
21+
22+
# Option 1: Google SMTP (free tier: 500/day)
23+
# Get app password: Google Account > Security > 2-Step Verification > App passwords
24+
# SMTP_HOST=smtp.gmail.com
25+
# SMTP_PORT=587
26+
27+
# SMTP_PASS=your-16-char-app-password
28+
# SMTP_SECURE=false
29+
30+
# Option 2: Resend (free tier: 100/day)
31+
# RESEND_API_KEY=re_xxxxxxxxx
32+
33+
34+
# Note: If both are configured, SMTP is used first (priority)
35+
36+
# Node environment
37+
NODE_ENV=development

auth-server/.gitignore

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Dependencies
2+
node_modules/
3+
4+
# Next.js
5+
.next/
6+
out/
7+
8+
# Environment
9+
.env
10+
.env.local
11+
.env.*.local
12+
13+
# IDE
14+
.vscode/
15+
.idea/
16+
17+
# OS
18+
.DS_Store
19+
Thumbs.db
20+
21+
# Debug
22+
npm-debug.log*
23+
24+
# TypeScript
25+
*.tsbuildinfo
26+
27+
# Drizzle
28+
drizzle/meta/
29+
.vercel

auth-server/README.md

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# RoboLearn Auth Server
2+
3+
OAuth 2.1 / OIDC authentication server using Better Auth.
4+
5+
## Setup
6+
7+
```bash
8+
cd auth-server
9+
npm install
10+
cp .env.example .env.local
11+
# Edit .env.local with your values
12+
npm run db:push
13+
# Seed the trusted public client (see below)
14+
npm run dev # http://localhost:3001
15+
```
16+
17+
### Seed Trusted Public Client
18+
19+
After running `db:push`, you **must** seed the trusted public client (`robolearn-public-client`) in your database. This client is pre-configured in the code but needs to exist in the database for OAuth flows to work.
20+
21+
**Option 1: Run SQL directly (recommended)**
22+
23+
Execute this SQL in your database (via psql, pgAdmin, or your database tool):
24+
25+
```sql
26+
INSERT INTO oauth_application (
27+
id,
28+
client_id,
29+
client_secret,
30+
name,
31+
redirect_urls,
32+
type,
33+
disabled,
34+
metadata,
35+
created_at,
36+
updated_at
37+
) VALUES (
38+
'robolearn-public-client-id',
39+
'robolearn-public-client',
40+
NULL, -- No secret for public client (PKCE only)
41+
'RoboLearn Public Client',
42+
'http://localhost:3000/auth/callback,https://robolearn.github.io/auth/callback', -- Comma-separated: dev + prod URLs
43+
'public',
44+
false,
45+
'{"token_endpoint_auth_method":"none","grant_types":["authorization_code","refresh_token"]}',
46+
NOW(),
47+
NOW()
48+
)
49+
ON CONFLICT (client_id) DO UPDATE SET
50+
name = EXCLUDED.name,
51+
redirect_urls = EXCLUDED.redirect_urls,
52+
type = EXCLUDED.type,
53+
disabled = EXCLUDED.disabled,
54+
metadata = EXCLUDED.metadata,
55+
updated_at = NOW();
56+
```
57+
58+
**Option 2: Use the seed script**
59+
60+
If you have `DATABASE_URL` set in `.env.local`:
61+
62+
```bash
63+
npx tsx scripts/seed-public-client.ts
64+
```
65+
66+
**Option 3: Use the API endpoint (admin only)**
67+
68+
If you're logged in as admin:
69+
70+
```bash
71+
curl -X POST http://localhost:3001/api/admin/seed-public-client \
72+
-H "Cookie: your-session-cookie"
73+
```
74+
75+
## Environment Variables
76+
77+
```env
78+
# Required
79+
DATABASE_URL=postgresql://user:[email protected]/db?sslmode=require
80+
BETTER_AUTH_SECRET=your-32-char-secret # openssl rand -base64 32
81+
BETTER_AUTH_URL=http://localhost:3001
82+
ALLOWED_ORIGINS=http://localhost:3000
83+
NEXT_PUBLIC_BETTER_AUTH_URL=http://localhost:3001
84+
85+
# Optional: Email verification
86+
# Option 1: Resend (free tier: 100/day)
87+
# RESEND_API_KEY=re_xxxxxxxxx
88+
89+
90+
# Option 2: SMTP (Gmail, custom SMTP, etc.)
91+
# SMTP_HOST=smtp.gmail.com
92+
# SMTP_PORT=587
93+
94+
# SMTP_PASS=app-password
95+
96+
97+
98+
# Optional: Production OAuth client callback URL
99+
# ROBOLEARN_INTERFACE_CALLBACK_URL=https://yourdomain.com/auth/callback
100+
```
101+
102+
## Features
103+
104+
- OAuth 2.1 with PKCE (no client secrets in browser)
105+
- JWKS (JSON Web Key Set) for client-side token verification
106+
- Dynamic client registration (`POST /api/auth/oauth2/register`)
107+
- Optional email verification via Resend or SMTP
108+
- Role-based access (admin/user)
109+
- 7-day sessions with auto-refresh
110+
111+
## Endpoints
112+
113+
| Endpoint | Description |
114+
|----------|-------------|
115+
| `/.well-known/openid-configuration` | OIDC discovery document |
116+
| `/api/auth/jwks` | JWKS public keys for token verification |
117+
| `/api/auth/oauth2/authorize` | Start OAuth flow |
118+
| `/api/auth/oauth2/token` | Exchange code for tokens |
119+
| `/api/auth/oauth2/userinfo` | Get user info |
120+
| `/api/auth/oauth2/register` | Register new OAuth client |
121+
122+
## Register New OAuth Client
123+
124+
```bash
125+
curl -X POST http://localhost:3001/api/auth/oauth2/register \
126+
-H "Content-Type: application/json" \
127+
-d '{
128+
"client_name": "My App",
129+
"redirect_uris": ["http://localhost:4000/callback"],
130+
"token_endpoint_auth_method": "none"
131+
}'
132+
```
133+
134+
Returns `client_id` to use in your OAuth flow.
135+
136+
## Create Admin User
137+
138+
```sql
139+
-- After signing up via UI:
140+
UPDATE "user" SET role = 'admin' WHERE email = '[email protected]';
141+
```
142+
143+
## Deploy to Vercel
144+
145+
1. Push to GitHub
146+
2. Import in Vercel, set root to `auth-server`
147+
3. Add environment variables
148+
4. Deploy

0 commit comments

Comments
 (0)