QuickZTNA User Guide
Home Authentication & Account Security Email/Password Signup & Login

Email/Password Signup & Login

What We’re Testing

Email/password is the primary authentication method. The backend (handlers/auth.ts) implements:

  • Signup: POST /api/auth/signup — creates user + credentials, issues JWT token pair
  • Login: POST /api/auth/login — validates password, checks MFA, issues tokens
  • Rate limiting: 5 signups per IP per 5 minutes; 10 logins per IP per 5 minutes; 10 per email per 5 minutes
  • Account lockout: After 10 failed login attempts, account locked for 15 minutes
  • Token pair: Access token (1 hour TTL) + refresh token (30 day TTL)

Password hashing uses PBKDF2 (with automatic migration from legacy SHA-256 hashes on login).

Your Test Setup

MachineRole
Win-A Browser + CLI testing

Use the dashboard at https://login.quickztna.com for browser tests and curl for API tests.


ST1 — Signup Flow (Dashboard)

What it verifies: A new user can create an account via the signup form and receives a valid JWT.

Steps:

  1. Open https://login.quickztna.com/auth in a browser (incognito/private window recommended).
  2. Click the Sign Up tab.
  3. Fill in:
    • Email: a test email address (e.g., testuser-YYYYMMDD@yourdomain.com)
    • Password: at least 8 characters
  4. Submit the form.

Expected behavior:

  • Success: redirected to /create-org (new user has no organization)
  • Browser dev tools → Application → Local Storage: access_token and refresh_token keys present

Pass: User is created, redirected to organization creation page, tokens stored in local storage.

Fail / Common issues:

  • “Too many signup attempts” — rate limit hit (5 per IP per 5 min). Wait 5 minutes or use a different IP.
  • “Email already in use” — that email is already registered. Use a different email.

ST2 — Login Flow (Dashboard)

What it verifies: An existing user can log in and receives fresh tokens.

Steps:

  1. Open https://login.quickztna.com/auth (incognito window).
  2. Enter the credentials from ST1 (or use vikas@networkershome.com / TestAdmin@123 for the superadmin account).
  3. Submit.

Expected behavior:

  • Success: redirected to /dashboard
  • Browser console (F12 → Console): no auth errors
  • Network tab: POST /api/auth/login returns 200 with body containing token, refresh_token, expires_in

Pass: Login succeeds, dashboard loads with real data, tokens issued.

Fail / Common issues:

  • “Invalid email or password” — check exact email and password. Passwords are case-sensitive.
  • “Account locked” — 10+ failed attempts. Wait 15 minutes for auto-unlock.

ST3 — Login via CLI (Interactive)

What it verifies: The ztna login --interactive command authenticates via email/password in the terminal.

Steps:

  1. On Win-A , log out first:
ztna logout
  1. Log in interactively:
ztna login --interactive
  1. Enter your email and password when prompted.

Expected output:

Email: vikas@networkershome.com
Password: ********
Login successful!
  1. Verify authentication:
ztna status

Should show Authenticated: true.

Pass: Login successful! message. ztna status shows Authenticated: true.

Fail / Common issues:

  • “login failed: invalid credentials” — wrong email or password.
  • “login failed: rate limited” — too many attempts. Wait 5 minutes.

ST4 — Account Lockout After Failed Attempts

What it verifies: After 10 failed login attempts, the account is locked for 15 minutes.

Steps:

  1. Use a test account for this (NOT your main admin account).
  2. Via curl, send 10 incorrect login requests:
for i in $(seq 1 10); do
  curl -s -X POST https://login.quickztna.com/api/auth/login \
    -H "Content-Type: application/json" \
    -d '{"email":"testuser@yourdomain.com","password":"wrong-password"}' \
    | python3 -c "import sys,json; d=json.load(sys.stdin); print(f'Attempt {}'': {d.get(\"error\",{}).get(\"message\",\"ok\")}')"
done
  1. On the 10th or 11th attempt, try with the correct password:
curl -s -X POST https://login.quickztna.com/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"testuser@yourdomain.com","password":"correct-password"}' | python3 -m json.tool

Expected:

  • Attempts 1-9: "Invalid email or password"
  • Attempt 10+: "Account locked" or similar lockout message
  • Correct password during lockout: still rejected

Pass: Account is locked after 10 failures. Even correct password is rejected during lockout period.

Fail / Common issues:

  • Account never locks — check that the user_credentials table has failed_login_attempts and locked_until columns (migration 001+).
  • Lockout happens too early — rate limit (10/IP/5min) may trigger before account lockout.

ST5 — Token Response Structure

What it verifies: Login response contains the correct token pair structure with expected TTLs.

Steps:

  1. Via curl, perform a successful login:
curl -s -X POST https://login.quickztna.com/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"vikas@networkershome.com","password":"TestAdmin@123"}' | python3 -m json.tool

Expected response structure:

{
  "success": true,
  "data": {
    "token": "eyJhbGciOiJFUzI1NiIs...",
    "refresh_token": "a1b2c3d4e5f6...",
    "expires_in": 3600,
    "user": {
      "id": "...",
      "email": "vikas@networkershome.com"
    }
  }
}
  1. Verify the JWT is ES256:
# Decode the JWT header (first segment, base64)
echo "eyJhbGciOiJFUzI1NiIs..." | cut -d. -f1 | base64 -d 2>/dev/null

Expected JWT header:

{"alg":"ES256","typ":"JWT"}

Pass: Response contains token (JWT), refresh_token, expires_in: 3600 (1 hour). JWT algorithm is ES256.

Fail / Common issues:

  • expires_in is not 3600 — the constant may have changed. Check auth.ts line 48.
  • JWT alg is HS256 instead of ES256 — the signing key configuration may be wrong.

Summary

Sub-testWhat it provesPass condition
ST1Signup worksNew user created, redirected to org creation
ST2Login worksDashboard loads, tokens in local storage
ST3CLI login worksztna login --interactive succeeds
ST4Account lockoutLocked after 10 failures, rejects correct password
ST5Token structureES256 JWT, 1h access + 30d refresh