@authhero/cloudflare-adapter 2.11.1 → 2.13.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.
package/README.md CHANGED
@@ -215,7 +215,6 @@ In the Cloudflare Dashboard:
215
215
  ```json
216
216
  {
217
217
  "fields": [
218
- { "name": "id", "type": "string", "required": true },
219
218
  { "name": "tenant_id", "type": "string", "required": true },
220
219
  { "name": "type", "type": "string", "required": true },
221
220
  { "name": "date", "type": "string", "required": true },
@@ -238,8 +237,6 @@ In the Cloudflare Dashboard:
238
237
  { "name": "auth0_client", "type": "string", "required": false },
239
238
  { "name": "log_id", "type": "string", "required": true },
240
239
  { "name": "country_code", "type": "string", "required": false },
241
- { "name": "country_code3", "type": "string", "required": false },
242
- { "name": "country_name", "type": "string", "required": false },
243
240
  { "name": "city_name", "type": "string", "required": false },
244
241
  { "name": "latitude", "type": "string", "required": false },
245
242
  { "name": "longitude", "type": "string", "required": false },
@@ -443,71 +440,125 @@ The Cloudflare Geo adapter extracts geographic location information from Cloudfl
443
440
 
444
441
  ### Features
445
442
 
446
- - **Zero Latency**: Uses headers already provided by Cloudflare Workers
443
+ - **Zero Latency**: Uses headers already provided by Cloudflare
447
444
  - **No API Calls**: No external services or databases required
448
- - **Comprehensive Data**: Includes country, city, coordinates, timezone, and continent
449
- - **Automatic**: Cloudflare populates headers automatically for every request
445
+ - **Graceful Degradation**: Works with just country code or full location data
446
+ - **Free**: All features available on Cloudflare's free plan
447
+
448
+ ### Cloudflare Setup
449
+
450
+ The geo adapter requires specific Cloudflare settings to be enabled:
451
+
452
+ #### 1. Enable IP Geolocation (Required)
453
+
454
+ This provides the `cf-ipcountry` header with just the country code.
455
+
456
+ 1. Go to your Cloudflare dashboard
457
+ 2. Navigate to **Network** settings
458
+ 3. Enable **IP Geolocation**
459
+
460
+ #### 2. Enable "Add visitor location headers" Managed Transform (Recommended)
461
+
462
+ This provides full location data including city, coordinates, timezone, etc.
463
+
464
+ 1. Go to your Cloudflare dashboard
465
+ 2. Navigate to **Rules** > **Transform Rules** > **Managed Transforms**
466
+ 3. Enable **Add visitor location headers**
467
+
468
+ This is a **free feature** available on all Cloudflare plans.
450
469
 
451
470
  ### Configuration
452
471
 
453
- The geo adapter is automatically created when you provide the `getHeaders` function:
472
+ The geo adapter is automatically included when you create the Cloudflare adapters. Headers are passed at request time via `getGeoInfo(headers)`:
454
473
 
455
474
  ```typescript
475
+ import createAdapters from "@authhero/cloudflare-adapter";
476
+
477
+ // Create adapters once at startup
456
478
  const adapters = createAdapters({
457
479
  // ... other config
458
- getHeaders: () => Object.fromEntries(request.headers),
459
480
  });
460
481
 
461
- // Access the geo adapter
462
- const geoInfo = await adapters.geo?.getGeoInfo();
482
+ // The geo adapter is always available
483
+ // Headers are passed when calling getGeoInfo
484
+ const headers = Object.fromEntries(request.headers);
485
+ const geoInfo = await adapters.geo.getGeoInfo(headers);
463
486
  ```
464
487
 
488
+ When used with AuthHero, headers are automatically extracted from the Hono context in the logging helper.
489
+
465
490
  ### Cloudflare Headers Used
466
491
 
467
- The adapter reads these Cloudflare-provided headers:
492
+ | Header | Description | Example | Availability |
493
+ | ---------------- | ------------------------- | --------------------- | ------------------------------------ |
494
+ | `cf-ipcountry` | 2-letter ISO country code | `US` | Always (with IP Geolocation enabled) |
495
+ | `cf-ipcity` | City name | `San Francisco` | With Managed Transform |
496
+ | `cf-iplatitude` | Latitude coordinate | `37.7749` | With Managed Transform |
497
+ | `cf-iplongitude` | Longitude coordinate | `-122.4194` | With Managed Transform |
498
+ | `cf-timezone` | IANA timezone identifier | `America/Los_Angeles` | With Managed Transform |
499
+ | `cf-ipcontinent` | 2-letter continent code | `NA` | With Managed Transform |
468
500
 
469
- | Header | Description | Example |
470
- | ---------------- | ------------------------- | --------------------- |
471
- | `cf-ipcountry` | 2-letter ISO country code | `US` |
472
- | `cf-ipcity` | City name | `San Francisco` |
473
- | `cf-iplatitude` | Latitude coordinate | `37.7749` |
474
- | `cf-iplongitude` | Longitude coordinate | `-122.4194` |
475
- | `cf-timezone` | IANA timezone identifier | `America/Los_Angeles` |
476
- | `cf-ipcontinent` | 2-letter continent code | `NA` |
501
+ Additional headers available with Managed Transform (not currently mapped):
502
+
503
+ - `cf-region`: Region name
504
+ - `cf-region-code`: Region code
505
+ - `cf-metro-code`: Metro code
506
+ - `cf-postal-code`: Postal code
477
507
 
478
508
  ### Response Format
479
509
 
480
510
  ```typescript
481
511
  interface GeoInfo {
482
- country_code: string; // "US"
483
- country_code3: string; // "USA"
484
- country_name: string; // "United States"
485
- city_name: string; // "San Francisco"
486
- latitude: string; // "37.7749"
487
- longitude: string; // "-122.4194"
488
- time_zone: string; // "America/Los_Angeles"
489
- continent_code: string; // "NA"
512
+ country_code: string; // "US" - always available
513
+ city_name: string; // "San Francisco" or "" if not available
514
+ latitude: string; // "37.7749" or "" if not available
515
+ longitude: string; // "-122.4194" or "" if not available
516
+ time_zone: string; // "America/Los_Angeles" or "" if not available
517
+ continent_code: string; // "NA" or "" if not available
518
+ }
519
+ ```
520
+
521
+ **With only IP Geolocation enabled:**
522
+
523
+ ```json
524
+ {
525
+ "country_code": "US",
526
+ "city_name": "",
527
+ "latitude": "",
528
+ "longitude": "",
529
+ "time_zone": "",
530
+ "continent_code": ""
531
+ }
532
+ ```
533
+
534
+ **With "Add visitor location headers" Managed Transform enabled:**
535
+
536
+ ```json
537
+ {
538
+ "country_code": "US",
539
+ "city_name": "San Francisco",
540
+ "latitude": "37.7749",
541
+ "longitude": "-122.4194",
542
+ "time_zone": "America/Los_Angeles",
543
+ "continent_code": "NA"
490
544
  }
491
545
  ```
492
546
 
493
547
  ### Integration with AuthHero
494
548
 
495
- When configured in AuthHero, the geo adapter automatically enriches authentication logs:
549
+ When configured in AuthHero, the geo adapter automatically enriches authentication logs. The logging helper extracts headers from the Hono context automatically:
496
550
 
497
551
  ```typescript
498
- import { init } from "@authhero/authhero";
499
552
  import createAdapters from "@authhero/cloudflare-adapter";
500
553
 
501
554
  const cloudflareAdapters = createAdapters({
502
- getHeaders: () => Object.fromEntries(request.headers),
503
555
  // ... other config
504
556
  });
505
557
 
506
- const authhero = init({
507
- data: yourDatabaseAdapter,
558
+ const dataAdapter = {
559
+ ...yourDatabaseAdapter,
508
560
  geo: cloudflareAdapters.geo, // Add geo adapter
509
- // ... other config
510
- });
561
+ };
511
562
  ```
512
563
 
513
564
  Logs will automatically include `location_info`:
@@ -518,8 +569,6 @@ Logs will automatically include `location_info`:
518
569
  "date": "2025-11-28T12:00:00.000Z",
519
570
  "location_info": {
520
571
  "country_code": "US",
521
- "country_code3": "USA",
522
- "country_name": "United States",
523
572
  "city_name": "San Francisco",
524
573
  "latitude": "37.7749",
525
574
  "longitude": "-122.4194",
@@ -531,7 +580,7 @@ Logs will automatically include `location_info`:
531
580
 
532
581
  ### Alternative: IP Geolocation Databases
533
582
 
534
- If you're not using Cloudflare Workers or need more detailed location data, you can implement a custom `GeoAdapter` using IP geolocation databases like MaxMind GeoIP2:
583
+ If you're not using Cloudflare or need more detailed location data, you can implement a custom `GeoAdapter` using IP geolocation databases like MaxMind GeoIP2:
535
584
 
536
585
  ```typescript
537
586
  import maxmind from "maxmind";
@@ -549,16 +598,21 @@ class MaxMindGeoAdapter implements GeoAdapter {
549
598
  return new MaxMindGeoAdapter(reader);
550
599
  }
551
600
 
552
- async getGeoInfo(): Promise<GeoInfo | null> {
553
- const ip = this.getClientIP();
601
+ async getGeoInfo(headers: Record<string, string>): Promise<GeoInfo | null> {
602
+ // Extract IP from headers (e.g., x-forwarded-for, cf-connecting-ip)
603
+ const ip =
604
+ headers["cf-connecting-ip"] ||
605
+ headers["x-forwarded-for"]?.split(",")[0]?.trim() ||
606
+ headers["x-real-ip"];
607
+
608
+ if (!ip) return null;
609
+
554
610
  const lookup = this.reader.get(ip);
555
611
 
556
612
  if (!lookup) return null;
557
613
 
558
614
  return {
559
615
  country_code: lookup.country?.iso_code || "",
560
- country_code3: lookup.country?.iso_code3 || "",
561
- country_name: lookup.country?.names?.en || "",
562
616
  city_name: lookup.city?.names?.en || "",
563
617
  latitude: lookup.location?.latitude?.toString() || "",
564
618
  longitude: lookup.location?.longitude?.toString() || "",