Skip to main content

Authentication Quick Reference

Token Expiry Configuration​

Current Settings​

// attunelogic-api/constants/index.js
TOKEN_EXPIRE: "4h"; // Access tokens last 4 hours
REFRESH_TOKEN_EXPIRES_WEB: "8h"; // Web refresh tokens last 8 hours
REFRESH_TOKEN_EXPIRES_MOBILE: "10d"; // Mobile refresh tokens last 10 days

To Change Token Expiry​

  1. Edit attunelogic-api/constants/index.js
  2. Update both JWT expiry (TOKEN_EXPIRE) and cookie TTL (TOKEN_EXPIRE_TTL)
  3. Restart API server
  4. All existing tokens remain valid until their current expiry

Key Files​

Backend​

  • constants/index.js - Token configuration
  • models/User.js - Token generation methods
  • models/Token.js - Token storage schema
  • controllers/account/login.js - Login flow
  • controllers/account/tokens.js - Refresh logic
  • middlewares/verifyToken.js - Token validation

Frontend​

  • redux/api.ts - Automatic refresh logic
  • hooks/useAuth.jsx - Auth context & state
  • pages/Login/index.jsx - Login UI

Common Tasks​

Debug Token Issues​

// Check if refresh token exists in database
db.tokens.findOne({
userId: ObjectId("..."),
type: "refresh",
isRevoked: false,
});

// Clean up expired tokens
db.tokens.deleteMany({ expiresAt: { $lt: new Date() } });

// Revoke all tokens for a user
db.tokens.updateMany({ userId: ObjectId("...") }, { isRevoked: true });

Add Logging to Track Refresh​

// In controllers/account/tokens.js refresh function
console.log("Token refresh:", {
userId: decoded.id,
userEmail: decoded.email,
oldJti: decoded.jti,
newJti: jwt.decode(newRefreshToken).jti,
timestamp: new Date().toISOString(),
});

Test Authentication Flow​

# Login
curl -X POST http://localhost:3001/api/v1/account/login \
-H "Content-Type: application/json" \
-d '{"user":{"email":"test@example.com","password":"password"}}' \
-c cookies.txt -v

# Make authenticated request
curl -X GET http://localhost:3001/api/v1/account/current \
-b cookies.txt -v

# Check cookies
cat cookies.txt

Error Code Reference​

CodeTriggerFrontend Action
TOKEN_EXPIREDNo access token, has refresh tokenAuto refresh
TOKEN_INVALID_WITH_REFRESHInvalid access token, has refresh tokenAuto refresh
NO_TOKENNo access token, no refresh tokenRedirect to login
AUTHENTICATION_FAILEDInvalid access token, no refresh tokenRedirect to login

Security Checklist​

  • βœ… Tokens are HTTP-only cookies
  • βœ… Secure flag enabled in production
  • βœ… SameSite protection against CSRF
  • βœ… Refresh tokens rotated on each use
  • βœ… Old refresh tokens immediately revoked
  • βœ… Database cleanup of expired tokens
  • βœ… Multi-tenant isolation via parentCompany

Performance Notes​

  • Access token verification is stateless (no DB lookup)
  • Refresh token requires DB lookup for validation
  • Token cleanup should run daily via cron job
  • Consider token indices for large user bases:
    db.tokens.createIndex({ userId: 1, type: 1 });
    db.tokens.createIndex({ jti: 1 }, { unique: true });
    db.tokens.createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 });