HelloJohn / docs
hjctl CLI

hj debug

Diagnostic and debugging commands for HelloJohn — inspect tokens, test connectivity, forward webhooks locally, and diagnose configuration.

hj debug

The hj debug command group provides diagnostic tools for troubleshooting HelloJohn integrations — from JWT inspection to webhook forwarding to connectivity checks.


Commands

CommandDescription
hj debug tokenDecode and validate a JWT
hj debug pingTest connectivity to HelloJohn API
hj debug configValidate local environment configuration
hj debug webhookForward webhooks to a local endpoint
hj debug smtpTest SMTP connectivity and configuration
hj debug corsTest CORS configuration for an origin

hj debug token

Decode and validate a HelloJohn JWT without making an API call:

hj debug token eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9...

Output:

Header:
  alg: EdDSA
  typ: JWT
  kid: key_01HABCDEF001

Payload:
  sub: usr_01HABCDEF123456
  iss: https://api.hellojohn.dev
  aud: tnt_01HABCDEF654321
  iat: 2024-06-01T14:00:00Z
  exp: 2024-06-01T14:15:00Z  ✅ valid (expires in 8 minutes)

Signature: ✅ verified against JWKS

Flags:

FlagDescription
--jwks-url <url>Custom JWKS URL (default: tenant JWKS)
--skip-verifyDecode without signature verification
--format jsonOutput as JSON

If the token is expired:

exp: 2024-06-01T13:00:00Z  ❌ expired (1 hour 14 minutes ago)

If the signature is invalid:

Signature: ❌ invalid — token may have been tampered with or signed by a different key

hj debug ping

Test connectivity to the HelloJohn API:

hj debug ping
Pinging https://api.hellojohn.dev...

  DNS resolution:    12ms
  TCP connection:    24ms
  TLS handshake:     45ms
  API response:      89ms
  Total:             170ms

✅ Connected — HelloJohn API is reachable
   Version: 2.1.0
   Region:  us-east-1

Test connectivity to a self-hosted instance:

hj debug ping --url https://auth.example.com

hj debug config

Validate your local HelloJohn configuration and environment variables:

hj debug config

Output:

HelloJohn CLI Configuration

Active tenant:    tnt_01HABCDEF654321  (Production)
API key:          sk_live_***...abc123  ✅ valid
Config file:      ~/.hj/config.json

Environment Variables
  HELLOJOHN_DATABASE_URL   ✅ set (postgresql://user:***@host:5432/hj)
  HELLOJOHN_JWT_SIGNING_KEY ✅ set (Ed25519 key detected)
  HELLOJOHN_ENCRYPTION_KEY  ✅ set (256-bit key detected)
  HELLOJOHN_SMTP_HOST       ✅ set (smtp.resend.com)
  HELLOJOHN_REDIS_URL       ⬜ not set (optional — using in-memory fallback)

Connectivity
  HelloJohn API:            ✅ reachable
  Database:                 ✅ connected (latency: 5ms)
  Redis:                    ⬜ not configured
  SMTP:                     ✅ connected (smtp.resend.com:587)

Flags:

FlagDescription
--env-file <path>Load environment from a .env file
--check-dbInclude database connectivity check
--check-smtpInclude SMTP connectivity check

hj debug webhook

Forward webhook events from HelloJohn to a local endpoint during development.

This is the HelloJohn CLI's built-in webhook forwarding tunnel — no external tool (ngrok, Cloudflare Tunnel) required for basic development:

# Forward to local Express server
hj debug webhook --port 3001 --path /api/webhooks/hj
Webhook forwarding active

  Tunnel URL: https://hj-dev-abc123.tunnel.hellojohn.dev/webhooks
  Local:      http://localhost:3001/api/webhooks/hj

Listening for events...
  Add the tunnel URL as your webhook endpoint in the dashboard.
  Press Ctrl+C to stop.

Events appear in real-time:

[14:32:01] POST → user.sign_in
           user_id: usr_01HABCDEF123456
           → 200 OK (34ms)

[14:32:45] POST → user.mfa_enabled
           user_id: usr_01HABCDEF123456
           → 200 OK (12ms)

Flags:

FlagDescription
--port <n>Local port to forward to (required)
--path <path>Local path (default: /)
--events <list>Comma-separated event filter
--secret <secret>Webhook signing secret (for local verification)
--replay <event-id>Replay a specific past event

Replay a past event:

# Replay a specific delivery from the logs
hj debug webhook --replay del_01HABCDEF999999 --port 3001 --path /api/webhooks/hj

hj debug smtp

Test SMTP connectivity independently of the HelloJohn server:

hj debug smtp --to you@example.com

Uses HELLOJOHN_SMTP_* environment variables. Override specific values:

hj debug smtp \
  --host smtp.sendgrid.net \
  --port 587 \
  --user apikey \
  --password "SG.your_key" \
  --from noreply@example.com \
  --to you@example.com

Output:

Testing SMTP configuration...

  Host:         smtp.sendgrid.net:587
  TLS:          STARTTLS
  From:         noreply@example.com

  ✅ Connected
  ✅ Authenticated
  ✅ Test email sent to you@example.com
     Message-ID: <20240601143200.abc123@example.com>

Common failure output:

  ❌ Authentication failed (535 5.7.8)
     Hint: Check HELLOJOHN_SMTP_PASSWORD
           For SendGrid, use 'apikey' as the username

hj debug cors

Test whether a specific origin is allowed by your tenant's CORS configuration:

hj debug cors --origin https://app.example.com
CORS check for: https://app.example.com

  Allowed origins:
    ✅ https://app.example.com
    ✅ https://www.example.com
    ⬜ http://localhost:3000

  Result: ✅ Allowed — Access-Control-Allow-Origin will be set

Test an origin that is NOT allowed:

hj debug cors --origin https://evil.example.com
  Result: ❌ Blocked — No Access-Control-Allow-Origin header will be returned
          Fix: Add https://evil.example.com to allowed origins
               hj admin config set allowed_origins '[..., "https://evil.example.com"]'

hj debug log

Parse and format HelloJohn server logs (useful when reading raw JSON logs):

# Format JSON logs from Docker
docker compose logs hellojohn | hj debug log

# Format logs from a file
hj debug log --file hellojohn.log

# Filter by level
hj debug log --level error --file hellojohn.log

Output (formatted):

2024-06-01 14:32:01  INFO  POST /v1/auth/sign-in 200 (45ms)  user=usr_01HABCDEF123456
2024-06-01 14:32:45  INFO  POST /v1/auth/mfa/verify 200 (23ms)  user=usr_01HABCDEF123456
2024-06-01 14:35:00  WARN  Rate limit approaching  ip=192.168.1.5  requests=95/100
2024-06-01 14:40:00  ERROR Failed to deliver webhook  endpoint=https://app.example.com/webhooks  attempt=3

On this page