create-authhero 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/dist/cloudflare-multitenant/.dev.vars.example +20 -4
  2. package/dist/cloudflare-multitenant/README.md +238 -89
  3. package/dist/cloudflare-multitenant/drizzle.config.ts +8 -0
  4. package/dist/cloudflare-multitenant/migrations/0000_init.sql +782 -0
  5. package/dist/cloudflare-multitenant/migrations/meta/_journal.json +13 -0
  6. package/dist/cloudflare-multitenant/seed-helper.js +75 -0
  7. package/dist/cloudflare-multitenant/src/app.ts +3 -22
  8. package/dist/cloudflare-multitenant/src/db/schema.ts +845 -0
  9. package/dist/cloudflare-multitenant/src/index.ts +61 -55
  10. package/dist/cloudflare-multitenant/src/seed.ts +64 -0
  11. package/dist/cloudflare-multitenant/src/types.ts +17 -17
  12. package/dist/cloudflare-multitenant/wrangler.toml +40 -28
  13. package/dist/cloudflare-simple/.dev.vars.example +20 -0
  14. package/dist/cloudflare-simple/README.md +246 -10
  15. package/dist/cloudflare-simple/drizzle.config.ts +8 -0
  16. package/dist/cloudflare-simple/migrations/0000_init.sql +782 -0
  17. package/dist/cloudflare-simple/migrations/meta/0000_snapshot.json +5325 -0
  18. package/dist/cloudflare-simple/migrations/meta/_journal.json +13 -0
  19. package/dist/cloudflare-simple/seed-helper.js +75 -0
  20. package/dist/cloudflare-simple/src/app.ts +10 -0
  21. package/dist/cloudflare-simple/src/db/schema.ts +845 -0
  22. package/dist/cloudflare-simple/src/index.ts +64 -13
  23. package/dist/cloudflare-simple/src/seed.ts +64 -0
  24. package/dist/cloudflare-simple/src/types.ts +18 -0
  25. package/dist/cloudflare-simple/wrangler.toml +29 -0
  26. package/dist/create-authhero.js +199 -131
  27. package/package.json +1 -1
  28. package/dist/cloudflare-multitenant/src/database-factory.ts +0 -220
@@ -1,9 +1,25 @@
1
- # Cloudflare API credentials for multi-tenant database management
2
- CLOUDFLARE_ACCOUNT_ID=your_account_id_here
3
- CLOUDFLARE_API_TOKEN=your_api_token_here
1
+ # ============================================================================
2
+ # Development Environment Variables
3
+ # ============================================================================
4
+ # Copy this file to .dev.vars and fill in your values.
5
+ # The .dev.vars file is used by wrangler for local development.
6
+ # ============================================================================
7
+
8
+ # ============================================================================
9
+ # OPTIONAL: Analytics Engine Configuration
10
+ # ============================================================================
11
+ # Required for Analytics Engine logging. Get these from your Cloudflare Dashboard:
12
+ # - Account ID: Found in the URL when logged into Cloudflare Dashboard
13
+ # - API Token: Create at https://dash.cloudflare.com/profile/api-tokens
14
+ # Required permissions: Account > Workers R2 Storage > Edit (for logs)
15
+ #
16
+ # CLOUDFLARE_ACCOUNT_ID=your_account_id_here
17
+ # CLOUDFLARE_API_TOKEN=your_api_token_here
4
18
 
5
19
  # Optional: Separate token for Analytics Engine (if different from main token)
6
20
  # ANALYTICS_ENGINE_API_TOKEN=your_analytics_token_here
7
21
 
8
- # Optional: Base domain for subdomain routing
22
+ # ============================================================================
23
+ # OPTIONAL: Other Configuration
24
+ # ============================================================================
9
25
  # BASE_DOMAIN=auth.example.com
@@ -2,9 +2,9 @@
2
2
 
3
3
  A production-grade multi-tenant AuthHero authentication server using Cloudflare Workers with:
4
4
 
5
- - Per-tenant D1 databases (dynamically created via REST API)
6
- - Analytics Engine for centralized logging
7
- - Subdomain-based tenant routing (optional)
5
+ - Multi-tenant support with tenant isolation at the data level
6
+ - Multiple tenants in a single D1 database
7
+ - Easy setup similar to single-tenant
8
8
 
9
9
  ## Architecture
10
10
 
@@ -14,34 +14,20 @@ A production-grade multi-tenant AuthHero authentication server using Cloudflare
14
14
  │ │
15
15
  │ ┌─────────────────────────────────┐ │
16
16
  │ │ AuthHero Multi-Tenant │ │
17
- └─────────────────────────────────┘
18
-
19
- │ ▼ │
20
- │ ┌─────────────────────────────────┐ │
21
- │ │ Multi-Tenancy Plugin │ │
22
- │ │ - Access Control │ │
23
- │ │ - Subdomain Routing │ │
24
- │ │ - Database Resolution │ │
17
+ - Multiple tenants per DB
18
+ - Tenant isolation via API
25
19
  │ └─────────────────────────────────┘ │
26
20
  │ │ │
27
21
  └──────────────┼──────────────────────────┘
28
22
 
29
- ┌────────────────────────┼────────────────────────┐
30
- │ │ │
31
- ▼ ▼ ▼
32
- ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
33
- Main D1 │ │ Tenant D1 │ Analytics │
34
- │ Database │ │ Databases │ │ Engine │
35
- │ (Bound) │ │ (via REST) │ │ (Logs) │
36
- └─────────────┘ └─────────────┘ └─────────────┘
23
+
24
+ ┌─────────────┐
25
+ │ D1 │
26
+ │ Database
27
+ (All Tenants)
28
+ └─────────────┘
37
29
  ```
38
30
 
39
- ## Prerequisites
40
-
41
- - [Cloudflare Account](https://dash.cloudflare.com/sign-up) with Workers Paid plan
42
- - [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/install-and-update/)
43
- - Cloudflare API Token with D1 and Workers permissions
44
-
45
31
  ## Getting Started
46
32
 
47
33
  1. Install dependencies:
@@ -50,96 +36,76 @@ A production-grade multi-tenant AuthHero authentication server using Cloudflare
50
36
  npm install
51
37
  ```
52
38
 
53
- 2. Create the main D1 database:
54
-
55
- ```bash
56
- wrangler d1 create authhero-main-db
57
- ```
58
-
59
- 3. Update `wrangler.toml` with your database ID.
60
-
61
- 4. Create `.dev.vars` from the example:
39
+ 2. Run local database migrations:
62
40
 
63
41
  ```bash
64
- cp .dev.vars.example .dev.vars
42
+ npm run migrate
65
43
  ```
66
44
 
67
- 5. Update `.dev.vars` with your Cloudflare credentials.
68
-
69
- 6. Run local database migrations:
45
+ 3. Seed the database with an admin user:
70
46
 
71
47
  ```bash
72
- npm run db:migrate
48
+ ADMIN_EMAIL=admin@example.com ADMIN_PASSWORD=yourpassword npm run seed
73
49
  ```
74
50
 
75
- 7. Start the development server:
51
+ 4. Start the development server:
76
52
  ```bash
77
53
  npm run dev
78
54
  ```
79
55
 
80
- ## Cloudflare API Token
81
-
82
- Create an API token with the following permissions:
56
+ The server will be available at `https://localhost:3000`.
83
57
 
84
- - **Account** > D1 > Edit
85
- - **Account** > Workers Analytics Engine > Edit
86
- - **Zone** > Workers Routes > Edit (if using custom domains)
58
+ ## Production Deployment
87
59
 
88
- ## Multi-Tenant Features
89
-
90
- ### Per-Tenant Database Isolation
91
-
92
- Each tenant gets its own D1 database, created dynamically when the tenant is provisioned:
93
-
94
- - Main tenant uses the bound D1 database (low latency)
95
- - Other tenants use D1 databases via REST API
96
-
97
- ### Access Control
98
-
99
- - Users authenticate against the main tenant
100
- - Organization membership grants access to specific tenants
101
- - Tokens with `org` claim can access the matching tenant
60
+ 1. Create a D1 database:
102
61
 
103
- ### Subdomain Routing (Optional)
62
+ ```bash
63
+ wrangler d1 create authhero-db
64
+ ```
104
65
 
105
- Enable subdomain routing to route requests based on subdomain:
66
+ 2. Update `wrangler.toml` with your database ID.
106
67
 
107
- - `tenant1.auth.example.com` tenant1
108
- - `tenant2.auth.example.com` → tenant2
68
+ 3. Run migrations on production:
109
69
 
110
- Configure in `wrangler.toml`:
70
+ ```bash
71
+ npm run db:migrate:remote
72
+ ```
111
73
 
112
- ```toml
113
- [vars]
114
- BASE_DOMAIN = "auth.example.com"
115
- ```
74
+ 4. Seed the production database:
116
75
 
117
- ### Analytics Engine Logs
76
+ ```bash
77
+ ADMIN_EMAIL=admin@example.com ADMIN_PASSWORD=yourpassword npm run seed:remote
78
+ ```
118
79
 
119
- All authentication events are logged to Analytics Engine for:
80
+ 5. Deploy:
81
+ ```bash
82
+ npm run deploy
83
+ ```
120
84
 
121
- - Centralized logging across all tenants
122
- - Real-time analytics
123
- - Low-latency writes
85
+ ## Multi-Tenant Features
124
86
 
125
- ## Deployment
87
+ ### Shared Database Model
126
88
 
127
- 1. Deploy to Cloudflare:
89
+ All tenants share a single D1 database, with data isolation enforced at the application level. This is simpler to manage and suitable for most use cases.
128
90
 
129
- ```bash
130
- npm run deploy
131
- ```
91
+ ### Creating Additional Tenants
132
92
 
133
- 2. Run production migrations:
93
+ You can create additional tenants using the Management API:
134
94
 
135
- ```bash
136
- npm run db:migrate:prod
137
- ```
95
+ ```bash
96
+ # Get an access token first
97
+ TOKEN=$(curl -s https://your-server/oauth/token \
98
+ -d grant_type=client_credentials \
99
+ -d client_id=default \
100
+ -d client_secret=your-secret \
101
+ -d audience=https://your-server/api/v2/ | jq -r '.access_token')
138
102
 
139
- 3. Set production secrets:
140
- ```bash
141
- wrangler secret put CLOUDFLARE_API_TOKEN
142
- ```
103
+ # Create a new tenant
104
+ curl -X POST https://your-server/api/v2/tenants \
105
+ -H "Authorization: Bearer $TOKEN" \
106
+ -H "Content-Type: application/json" \
107
+ -d '{"id": "tenant2", "name": "Tenant 2"}'
108
+ ```
143
109
 
144
110
  ## Project Structure
145
111
 
@@ -147,13 +113,26 @@ All authentication events are logged to Analytics Engine for:
147
113
  ├── src/
148
114
  │ ├── index.ts # Worker entry point
149
115
  │ ├── app.ts # AuthHero app configuration
116
+ │ ├── seed.ts # Database seeding worker
150
117
  │ ├── types.ts # TypeScript type definitions
151
- │ └── database-factory.ts # Multi-tenant database factory
118
+ │ └── db/
119
+ │ └── schema.ts # Drizzle schema for migrations
120
+ ├── migrations/ # Database migrations
152
121
  ├── wrangler.toml # Cloudflare Worker configuration
153
- ├── .dev.vars.example # Example environment variables
122
+ ├── drizzle.config.ts # Drizzle configuration
123
+ ├── seed-helper.js # Helper script to run seeds
154
124
  └── package.json
155
125
  ```
156
126
 
127
+ ## Database Schema Changes
128
+
129
+ To make schema changes:
130
+
131
+ 1. Edit `src/db/schema.ts`
132
+ 2. Generate migrations: `npm run db:generate`
133
+ 3. Apply locally: `npm run migrate`
134
+ 4. Apply to production: `npm run db:migrate:remote`
135
+
157
136
  ## API Documentation
158
137
 
159
138
  Visit your worker URL with `/docs` to see the Swagger UI documentation.
@@ -175,3 +154,173 @@ curl https://your-worker.workers.dev/management/tenants \
175
154
  ```
176
155
 
177
156
  For more information, visit [https://authhero.net/docs](https://authhero.net/docs).
157
+
158
+ ## Optional Features
159
+
160
+ ### Analytics Engine (Centralized Logging)
161
+
162
+ Cloudflare Analytics Engine provides centralized logging for your authentication events. To enable:
163
+
164
+ #### Via Cloudflare Dashboard:
165
+
166
+ 1. Go to **Workers & Pages** > **Analytics Engine**
167
+ 2. Click **Create a dataset**
168
+ 3. Name it `authhero_logs`
169
+ 4. Copy the dataset name for your wrangler.toml
170
+
171
+ #### Via Wrangler CLI:
172
+
173
+ ```bash
174
+ # There's no CLI command to create Analytics Engine datasets yet
175
+ # You must use the Cloudflare Dashboard
176
+ ```
177
+
178
+ #### Configuration Steps:
179
+
180
+ 1. **Create `.dev.vars` file** for local development:
181
+
182
+ ```env
183
+ CLOUDFLARE_ACCOUNT_ID=your_account_id
184
+ CLOUDFLARE_API_TOKEN=your_api_token
185
+ # Optional: separate token for Analytics Engine
186
+ ANALYTICS_ENGINE_API_TOKEN=your_analytics_token
187
+ ```
188
+
189
+ 2. **Update `wrangler.toml`** - uncomment the Analytics Engine section:
190
+
191
+ ```toml
192
+ [[analytics_engine_datasets]]
193
+ binding = "AUTH_LOGS"
194
+ dataset = "authhero_logs"
195
+ ```
196
+
197
+ 3. **Update `src/types.ts`** - uncomment the Analytics Engine types:
198
+
199
+ ```typescript
200
+ import { AnalyticsEngineDataset } from "@authhero/cloudflare-adapter";
201
+
202
+ export interface Env {
203
+ AUTH_DB: D1Database;
204
+ AUTH_LOGS: AnalyticsEngineDataset;
205
+ CLOUDFLARE_ACCOUNT_ID: string;
206
+ CLOUDFLARE_API_TOKEN: string;
207
+ ANALYTICS_ENGINE_API_TOKEN?: string;
208
+ }
209
+ ```
210
+
211
+ 4. **Update `src/index.ts`** - uncomment the Cloudflare adapter code:
212
+
213
+ ```typescript
214
+ import createCloudflareAdapters from "@authhero/cloudflare-adapter";
215
+ // ... in the fetch handler:
216
+ const cloudflareAdapters = createCloudflareAdapters({
217
+ accountId: env.CLOUDFLARE_ACCOUNT_ID,
218
+ apiToken: env.CLOUDFLARE_API_TOKEN,
219
+ analyticsEngineLogs: {
220
+ analyticsEngineBinding: env.AUTH_LOGS,
221
+ accountId: env.CLOUDFLARE_ACCOUNT_ID,
222
+ apiToken: env.ANALYTICS_ENGINE_API_TOKEN || env.CLOUDFLARE_API_TOKEN,
223
+ dataset: "authhero_logs",
224
+ },
225
+ });
226
+ // ... spread into config:
227
+ const config: AuthHeroConfig = {
228
+ dataAdapter,
229
+ ...cloudflareAdapters,
230
+ };
231
+ ```
232
+
233
+ 5. **Install the package**:
234
+
235
+ ```bash
236
+ npm install @authhero/cloudflare-adapter
237
+ ```
238
+
239
+ 6. **Set secrets for production**:
240
+ ```bash
241
+ wrangler secret put CLOUDFLARE_ACCOUNT_ID
242
+ wrangler secret put CLOUDFLARE_API_TOKEN
243
+ # Optional:
244
+ wrangler secret put ANALYTICS_ENGINE_API_TOKEN
245
+ ```
246
+
247
+ ### Rate Limiting
248
+
249
+ Cloudflare Rate Limiting helps protect your authentication endpoints from abuse. **Requires Workers Paid plan ($5/month)**.
250
+
251
+ #### Via Cloudflare Dashboard:
252
+
253
+ Rate limiting bindings are configured in `wrangler.toml`, not in the Dashboard.
254
+
255
+ #### Configuration Steps:
256
+
257
+ 1. **Ensure you have a Workers Paid plan** - Rate limiting is not available on the free tier.
258
+
259
+ 2. **Update `wrangler.toml`** - uncomment the Rate Limiting section:
260
+
261
+ ```toml
262
+ [[unsafe.bindings]]
263
+ name = "RATE_LIMITER"
264
+ type = "ratelimit"
265
+ namespace_id = "1001" # Unique namespace ID for this limiter
266
+ simple = { limit = 100, period = 60 } # 100 requests per 60 seconds
267
+ ```
268
+
269
+ 3. **Update `src/types.ts`** - add the RateLimiter type:
270
+
271
+ ```typescript
272
+ export interface Env {
273
+ AUTH_DB: D1Database;
274
+ RATE_LIMITER: RateLimiter;
275
+ }
276
+ ```
277
+
278
+ 4. **Add rate limiting logic in `src/index.ts`**:
279
+
280
+ ```typescript
281
+ export default {
282
+ async fetch(request: Request, env: Env): Promise<Response> {
283
+ // Get client IP for rate limiting
284
+ const clientIp = request.headers.get("CF-Connecting-IP") || "unknown";
285
+
286
+ // Check rate limit
287
+ const { success } = await env.RATE_LIMITER.limit({ key: clientIp });
288
+ if (!success) {
289
+ return new Response(JSON.stringify({ error: "Rate limit exceeded" }), {
290
+ status: 429,
291
+ headers: { "Content-Type": "application/json" },
292
+ });
293
+ }
294
+
295
+ // ... rest of the handler
296
+ },
297
+ };
298
+ ```
299
+
300
+ #### Rate Limit Configuration Options:
301
+
302
+ | Option | Description | Example |
303
+ | -------------- | ---------------------------------- | -------- |
304
+ | `limit` | Max requests allowed | `100` |
305
+ | `period` | Time window in seconds | `60` |
306
+ | `namespace_id` | Unique ID (string) for the limiter | `"1001"` |
307
+
308
+ #### Advanced Rate Limiting:
309
+
310
+ For more granular control, you can rate limit by:
311
+
312
+ - **Tenant ID**: `{ key: tenantId }`
313
+ - **User ID**: `{ key: userId }`
314
+ - **Endpoint + IP**: `{ key: \`\${pathname}:\${clientIp}\` }`
315
+
316
+ ```typescript
317
+ // Rate limit login attempts more strictly
318
+ if (url.pathname.includes("/oauth/token")) {
319
+ const { success } = await env.LOGIN_RATE_LIMITER.limit({
320
+ key: `login:${clientIp}`,
321
+ });
322
+ if (!success) {
323
+ return new Response("Too many login attempts", { status: 429 });
324
+ }
325
+ }
326
+ ```
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from "drizzle-kit";
2
+
3
+ // SQLite/D1 configuration for Cloudflare Workers
4
+ export default defineConfig({
5
+ out: "./migrations",
6
+ schema: "./src/db/schema.ts",
7
+ dialect: "sqlite",
8
+ });