🔐 Authentication & Authorization

JWT Authentication

Detailed documentation on how JWT (JSON Web Token) authentication works in the Ever Gauzy platform.

How JWT Works

Diagram; its source is available below
Diagram source
sequenceDiagram
    participant Client
    participant Server
    Client->>Server: POST /auth/login {email, password}
    Server->>Client: {token, refreshToken}
    Client->>Server: GET /api/employee (Authorization: Bearer xxx)
    Server->>Client: {data}

Token Structure

A Gauzy JWT access token contains:

{
  "id": "user-uuid",
  "email": "user@example.com",
  "tenantId": "tenant-uuid",
  "employeeId": "employee-uuid",
  "role": "ADMIN",
  "iat": 1704067200,
  "exp": 1704153600
}

Claims

ClaimDescription
idUser ID
emailUser email
tenantIdUser's tenant ID
employeeIdAssociated employee ID (if applicable)
roleUser's role name
iatIssued at (Unix timestamp)
expExpiry (Unix timestamp)

Configuration

Environment Variables

# JWT secret for signing access tokens
JWT_SECRET=your-very-secure-secret-key

# Access token expiration in seconds (default: 24 hours)
JWT_TOKEN_EXPIRATION_TIME=86400

# Refresh token secret
JWT_REFRESH_TOKEN_SECRET=your-refresh-token-secret

# Refresh token expiration in seconds (default: 7 days)
JWT_REFRESH_TOKEN_EXPIRATION_TIME=604800
Warning

Always use strong, unique secrets in production. Never commit secrets to version control.

Token Lifecycle

1. Obtain Tokens

# Login request
POST /api/auth/login
Content-Type: application/json

{
  "email": "admin@ever.co",
  "password": "admin"
}

Response:

{
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "refreshToken": "eyJhbGciOiJIUzI1NiIs...",
  "user": { ... }
}

2. Use Access Token

Include the access token in Authorization header:

GET /api/employee
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

3. Refresh Token

When the access token expires, use the refresh token to get a new pair:

POST /api/auth/refresh-token
Content-Type: application/json

{
  "refreshToken": "eyJhbGciOiJIUzI1NiIs..."
}

Response:

{
  "token": "new-access-token",
  "refreshToken": "new-refresh-token"
}

4. Token Expiry Flow

Diagram; its source is available below
Diagram source
graph LR
    A["Login"] --> B["Access Token Valid (24h)<br/>Normal API calls"]
    B --> C["Token Expires → 401"]
    C --> D["Use Refresh Token → New Tokens"]
    D --> B
    A --> E["Refresh Token Valid (7d)"]
    E --> F["Refresh Token Expires → Re-login"]

Passport Strategy

The JWT strategy validates tokens on every authenticated request:

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(
    private readonly configService: ConfigService,
    private readonly userService: UserService,
  ) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: configService.get("JWT_SECRET"),
    });
  }

  async validate(payload: JwtPayload): Promise<IUser> {
    const { id, tenantId } = payload;
    const user = await this.userService.findOneById(id);
    if (!user) throw new UnauthorizedException();
    return user;
  }
}

Token Storage

Web Application

Tokens are stored in:

  • Local Storage — persists across browser sessions
  • Session Storage — cleared when browser is closed

Desktop Application

Tokens are stored using:

  • Electron Store — secure, encrypted local storage
  • Keychain/Credential Manager — OS-level secure storage

Best Practices

ApproachSecurityUX
Local Storage⚠️ XSS vulnerable✅ Persistent sessions
Session Storage✅ Session-scoped⚠️ Lost on close
HTTP-Only Cookies✅ XSS protected✅ Automatic
Electron Store✅ Encrypted✅ Native

Error Responses

ErrorStatusDescription
Missing token401No Authorization header
Invalid token401Token signature invalid
Expired token401Token past exp time
User not found401Token user deleted/disabled
Refresh token expired401Must re-authenticate

Edit this page

Copyright © 2023-Present Ever Co. LTD.Docs by Sourcey