Skip to content

Frontend Account Service and Auth Integration

Heindrich Jansen edited this page May 19, 2026 · 1 revision

Frontend Authentication Integration Guide

Overview

The frontend communicates exclusively with the API Gateway — never directly with the Accounts Service or Auth0. The gateway handles JWT validation and forwards requests to the correct service.

Base URL: http://localhost:3001/api (development)


Endpoints

POST /accounts/auth/register

Registers a new user. No authentication required.

Request body:

{
  "email": "user@example.com",
  "password": "Password123!",
  "name": "John Doe"
}

Success response (201):

{
  "message": "Registration successful",
  "userId": "uuid-here"
}

Error responses:

Code Reason
400 Missing or invalid fields
409 Email already registered
500 Server error

POST /accounts/auth/login

Logs in a user and returns a JWT access token. No authentication required.

Request body:

{
  "email": "user@example.com",
  "password": "Password123!"
}

Success response (200):

{
  "access_token": "eyJhbGci...",
  "expires_in": 86400
}

Error responses:

Code Reason
400 Missing or invalid fields
401 Wrong email or password

GET /accounts/auth/me

Returns the currently authenticated user's info. JWT required.

Headers: Authorization: Bearer <access_token>

Success response (200):

{
  "auth0Id": "auth0|abc123",
  "email": "user@example.com",
  "role": "user"
}

Error responses:

Code Reason
401 Missing, invalid, or expired token

React Implementation

Register

const register = async (email: string, password: string, name?: string) => {
  const response = await fetch('http://localhost:3001/api/accounts/auth/register', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ email, password, name }),
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(error.message);
  }

  return response.json();
};

Login

const login = async (email: string, password: string) => {
  const response = await fetch('http://localhost:3001/api/accounts/auth/login', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ email, password }),
  });

  if (!response.ok) {
    throw new Error('Invalid credentials');
  }

  const { access_token, expires_in } = await response.json();

  // Store the token
  localStorage.setItem('access_token', access_token);
  localStorage.setItem('token_expiry', String(Date.now() + expires_in * 1000));

  return access_token;
};

Making authenticated requests

const authFetch = async (url: string, options: RequestInit = {}) => {
  const token = localStorage.getItem('access_token');

  return fetch(url, {
    ...options,
    headers: {
      ...options.headers,
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json',
    },
  });
};

// Example usage
const getProfile = async () => {
  const response = await authFetch('http://localhost:3001/api/accounts/auth/me');
  return response.json();
};

Logout

const logout = () => {
  localStorage.removeItem('access_token');
  localStorage.removeItem('token_expiry');
  // redirect to login page
};

Checking if token is expired

const isTokenExpired = () => {
  const expiry = localStorage.getItem('token_expiry');
  if (!expiry) return true;
  return Date.now() > parseInt(expiry);
};

Notes

  • Tokens expire after 24 hours — redirect to login when expired
  • Roles returned from /me are: user, analyst, admin
  • Use the Swagger UI at http://localhost:3001/api-docs to explore and manually test endpoints during development

Clone this wiki locally