# enejkr/certificatedemo architecture

> Architecture diagram of the GitHub repository enejkr/certificatedemo, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-30). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/enejkr/certificatedemo
- Repository: https://github.com/enejkr/certificatedemo

## Overview

CertificateDemo is a PHP demo of certificate-based login followed by bearer-token API access. The main flow is client mTLS login, server certificate verification and token issuance, then access-token API calls; expired access tokens are refreshed and saved by the client. README also documents certificate provisioning, JWT signing/verification, HTTPS/mTLS boundary, and rate limiting. The graph follows shown endpoint calls and README-described capabilities; unsampled normal API internals and certificate setup are represented only at their supported directory paths.

Main entry points: [`server/api/mtls/v1/login.php`](https://github.com/enejkr/certificatedemo/blob/main/server/api/mtls/v1/login.php) (mTLS login), [`server/api/normal/v1/refresh.php`](https://github.com/enejkr/certificatedemo/blob/main/server/api/normal/v1/refresh.php) (Refresh endpoint), [`client/classes/Client.php`](https://github.com/enejkr/certificatedemo/blob/main/client/classes/Client.php) (HTTPS client), [`server/bootstrap.php`](https://github.com/enejkr/certificatedemo/blob/main/server/bootstrap.php) (API bootstrap)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["PHP client"]
  node_client_ui["Client workflow<br/>[index.php]"]
  node_client_http["HTTPS client<br/>[Client.php]"]
  node_token_helper["Token cookies<br/>[token_helper.php]"]
end

subgraph group_auth["Authentication"]
  node_login["mTLS login<br/>[login.php]"]
  node_certificate["Certificate check<br/>[Certificate.php]"]
  node_jwt["JWT service<br/>[Jwt.php]"]
  node_refresh_service["Refresh tokens<br/>[RefreshToken.php]"]
end

subgraph group_api["Token API"]
  node_refresh_endpoint["Refresh endpoint<br/>[refresh.php]"]
  node_api_endpoint["Bearer API<br/>[api.php]"]
end

subgraph group_infra["Server internals"]
  node_rate_limiter["Rate limiting<br/>[RateLimiter.php]"]
  node_database[("MySQL database<br/>[Database.php]")]
  node_bootstrap["API bootstrap<br/>[bootstrap.php]"]
  node_api_helpers["Response helpers<br/>[apiHelper.php]"]
  node_api_exception["API errors<br/>[ApiException.php]"]
  node_logger["Server logging<br/>[Logger.php]"]
end

subgraph group_provision["Certificate setup"]
  node_cert_setup["Certificate provisioning"]
  node_https_server["HTTPS and mTLS"]
end

node_user(("Client user"))

node_user -->|"starts login"| node_client_ui
node_client_ui -->|"requests login"| node_client_http
node_client_ui -->|"saves tokens"| node_token_helper
node_client_ui -->|"requests API"| node_client_http
node_client_ui -->|"refreshes tokens"| node_token_helper
node_token_helper -->|"calls refresh"| node_client_http
node_client_http -->|"posts certificate"| node_login
node_client_http -->|"sends refresh token"| node_refresh_endpoint
node_client_http -->|"sends access token"| node_api_endpoint
node_login -->|"loads bootstrap"| node_bootstrap
node_login -->|"opens database"| node_database
node_login -->|"verifies certificate"| node_certificate
node_login -->|"checks limit"| node_rate_limiter
node_login -->|"creates access token"| node_jwt
node_login -->|"creates refresh token"| node_refresh_service
node_login -->|"returns token response"| node_api_helpers
node_refresh_endpoint -->|"loads bootstrap"| node_bootstrap
node_refresh_endpoint -->|"opens database"| node_database
node_refresh_endpoint -->|"verifies token"| node_refresh_service
node_refresh_endpoint -->|"checks limit"| node_rate_limiter
node_refresh_endpoint -->|"creates access token"| node_jwt
node_refresh_endpoint -->|"rotates token"| node_refresh_service
node_refresh_endpoint -->|"returns token response"| node_api_helpers
node_api_endpoint -->|"loads bootstrap"| node_bootstrap
node_api_endpoint -->|"opens database"| node_database
node_api_endpoint -->|"checks limit"| node_rate_limiter
node_bootstrap -->|"uses responses"| node_api_helpers
node_bootstrap -->|"logs failures"| node_logger
node_bootstrap -->|"handles exceptions"| node_api_exception
node_cert_setup -.->|"registers fingerprint"| node_database
node_https_server -.->|"requires mTLS"| node_login
node_https_server -.->|"serves HTTPS"| node_api_endpoint

click node_client_ui "https://github.com/enejkr/certificatedemo/blob/main/client/index.php"
click node_client_http "https://github.com/enejkr/certificatedemo/blob/main/client/classes/Client.php"
click node_token_helper "https://github.com/enejkr/certificatedemo/blob/main/client/functions/token_helper.php"
click node_login "https://github.com/enejkr/certificatedemo/blob/main/server/api/mtls/v1/login.php"
click node_certificate "https://github.com/enejkr/certificatedemo/blob/main/server/classes/Certificate.php"
click node_jwt "https://github.com/enejkr/certificatedemo/blob/main/server/classes/Jwt.php"
click node_refresh_service "https://github.com/enejkr/certificatedemo/blob/main/server/classes/RefreshToken.php"
click node_refresh_endpoint "https://github.com/enejkr/certificatedemo/blob/main/server/api/normal/v1/refresh.php"
click node_api_endpoint "https://github.com/enejkr/certificatedemo/blob/main/server/api/normal/v1/api.php"
click node_rate_limiter "https://github.com/enejkr/certificatedemo/blob/main/server/classes/RateLimiter.php"
click node_database "https://github.com/enejkr/certificatedemo/blob/main/server/classes/Database.php"
click node_bootstrap "https://github.com/enejkr/certificatedemo/blob/main/server/bootstrap.php"
click node_api_helpers "https://github.com/enejkr/certificatedemo/blob/main/server/functions/apiHelper.php"
click node_api_exception "https://github.com/enejkr/certificatedemo/blob/main/server/classes/ApiException.php"
click node_logger "https://github.com/enejkr/certificatedemo/blob/main/server/Logger.php"
click node_cert_setup "https://github.com/enejkr/certificatedemo/tree/main/certs/setup"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_client_ui,node_client_http,node_token_helper,node_user toneBlue
class node_login,node_certificate,node_jwt,node_refresh_service toneAmber
class node_refresh_endpoint,node_api_endpoint toneMint
class node_rate_limiter,node_database,node_bootstrap,node_api_helpers,node_api_exception,node_logger toneRose
class node_cert_setup,node_https_server toneIndigo
```

## Components

### PHP client

- [Client workflow](https://github.com/enejkr/certificatedemo/blob/main/client/index.php): `client/index.php`
- [HTTPS client](https://github.com/enejkr/certificatedemo/blob/main/client/classes/Client.php): `client/classes/Client.php`
- [Token cookies](https://github.com/enejkr/certificatedemo/blob/main/client/functions/token_helper.php): `client/functions/token_helper.php`

### Authentication

- [mTLS login](https://github.com/enejkr/certificatedemo/blob/main/server/api/mtls/v1/login.php): `server/api/mtls/v1/login.php`
- [Certificate check](https://github.com/enejkr/certificatedemo/blob/main/server/classes/Certificate.php): `server/classes/Certificate.php`
- [JWT service](https://github.com/enejkr/certificatedemo/blob/main/server/classes/Jwt.php): `server/classes/Jwt.php`
- [Refresh tokens](https://github.com/enejkr/certificatedemo/blob/main/server/classes/RefreshToken.php): `server/classes/RefreshToken.php`

### Token API

- [Refresh endpoint](https://github.com/enejkr/certificatedemo/blob/main/server/api/normal/v1/refresh.php): `server/api/normal/v1/refresh.php`
- [Bearer API](https://github.com/enejkr/certificatedemo/blob/main/server/api/normal/v1/api.php): `server/api/normal/v1/api.php`

### Server internals

- [Rate limiting](https://github.com/enejkr/certificatedemo/blob/main/server/classes/RateLimiter.php): `server/classes/RateLimiter.php`
- [MySQL database](https://github.com/enejkr/certificatedemo/blob/main/server/classes/Database.php): `server/classes/Database.php`
- [API bootstrap](https://github.com/enejkr/certificatedemo/blob/main/server/bootstrap.php): `server/bootstrap.php`
- [Response helpers](https://github.com/enejkr/certificatedemo/blob/main/server/functions/apiHelper.php): `server/functions/apiHelper.php`
- [API errors](https://github.com/enejkr/certificatedemo/blob/main/server/classes/ApiException.php): `server/classes/ApiException.php`
- [Server logging](https://github.com/enejkr/certificatedemo/blob/main/server/Logger.php): `server/Logger.php`

### Certificate setup

- [Certificate provisioning](https://github.com/enejkr/certificatedemo/tree/main/certs/setup): `certs/setup`
- **HTTPS and mTLS**

### Other components

- **Client user**

## Connections

- Client user → Client workflow: starts login (evidence: `client/index.php`)
- Client workflow → HTTPS client: requests login (evidence: `client/index.php`)
- Client workflow → Token cookies: saves tokens (evidence: `client/index.php`)
- Client workflow → HTTPS client: requests API (evidence: `client/index.php`)
- Client workflow → Token cookies: refreshes tokens (evidence: `client/index.php`)
- Token cookies → HTTPS client: calls refresh (evidence: `client/functions/token_helper.php`)
- HTTPS client → mTLS login: posts certificate
- HTTPS client → Refresh endpoint: sends refresh token
- HTTPS client → Bearer API: sends access token
- mTLS login → API bootstrap: loads bootstrap (evidence: `server/api/mtls/v1/login.php`)
- mTLS login → MySQL database: opens database (evidence: `server/api/mtls/v1/login.php`)
- mTLS login → Certificate check: verifies certificate (evidence: `server/api/mtls/v1/login.php`)
- mTLS login → Rate limiting: checks limit (evidence: `server/api/mtls/v1/login.php`)
- mTLS login → JWT service: creates access token (evidence: `server/api/mtls/v1/login.php`)
- mTLS login → Refresh tokens: creates refresh token (evidence: `server/api/mtls/v1/login.php`)
- mTLS login → Response helpers: returns token response (evidence: `server/api/mtls/v1/login.php`)
- Refresh endpoint → API bootstrap: loads bootstrap (evidence: `server/api/normal/v1/refresh.php`)
- Refresh endpoint → MySQL database: opens database (evidence: `server/api/normal/v1/refresh.php`)
- Refresh endpoint → Refresh tokens: verifies token (evidence: `server/api/normal/v1/refresh.php`)
- Refresh endpoint → Rate limiting: checks limit (evidence: `server/api/normal/v1/refresh.php`)
- Refresh endpoint → JWT service: creates access token (evidence: `server/api/normal/v1/refresh.php`)
- Refresh endpoint → Refresh tokens: rotates token (evidence: `server/api/normal/v1/refresh.php`)
- Refresh endpoint → Response helpers: returns token response (evidence: `server/api/normal/v1/refresh.php`)
- Bearer API → API bootstrap: loads bootstrap (evidence: `server/api/normal/v1/api.php`)
- Bearer API → MySQL database: opens database (evidence: `server/api/normal/v1/api.php`)
- Bearer API → Rate limiting: checks limit (evidence: `server/api/normal/v1/api.php`)
- API bootstrap → Response helpers: uses responses (evidence: `server/bootstrap.php`)
- API bootstrap → Server logging: logs failures (evidence: `server/bootstrap.php`)
- API bootstrap → API errors: handles exceptions (evidence: `server/bootstrap.php`)
- Certificate provisioning → MySQL database: registers fingerprint (evidence: `README.md`)
- HTTPS and mTLS → mTLS login: requires mTLS (evidence: `README.md`)
- HTTPS and mTLS → Bearer API: serves HTTPS (evidence: `README.md`)
