Nodeflux Central
Otentikasi

API Reference — Otentikasi

Endpoint login JWT, refresh, logout, verifikasi kredensial, status integration lock, dan manajemen API key (x-api-key) tingkat pengguna.

Endpoint Login, Refresh, Logout, dan Status tidak memerlukan header Authorization — refresh dan logout mengotentikasi diri lewat refresh_token pada body. Endpoint Ping dan seluruh manajemen API key memerlukan Authorization: Bearer <token> atau X-Api-Key: <key>. Basis URL mengikuti variabel lingkungan VITE_API_URL yang dikonfigurasi pada instalasi Lenz.

Request Authorization: Bearer dari luar dashboard Lenz tunduk pada integration lock (403 integration_lock) — untuk integrasi, kirim X-Api-Key di setiap request tanpa header Authorization. Penjelasan lengkap ada di panduan Otentikasi.


Login & Token

Endpoint untuk memperoleh pasangan token (access_token 30 menit + refresh_token sekali pakai), merotasinya, dan mengakhiri sesi. Login mendukung dua metode: username/password via JSON body (tunduk pada kebijakan satu sesi aktif — 409 active-session-exists), atau API key via header X-Api-Key — keduanya mengarah ke endpoint yang sama dan mengembalikan format respons yang identik.

Login — Dapatkan Token Akses

POST
/api/auth/token

Header Parameters

X-Api-Key?string

API key yang valid (untuk metode login via API key — abaikan jika menggunakan username/password)

Request Body

application/json

Kredensial login (wajib untuk metode username/password; abaikan untuk metode API key)

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

curl -X POST "https://lenz.example.com/api/auth/token" \  -H "Content-Type: application/json" \  -d '{    "user_access": "admin@example.com",    "password": "rahasia123",    "remember_me": false  }'
{  "ok": true,  "message": "Successfull Login",  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NDIsInNpZCI6ImI3ZjMuLi4iLCJleHAiOjE3NDYwMDE4MDB9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NDIsImp0aSI6ImI3ZjMuLi4iLCJleHAiOjE3NDYwODY0MDB9.abc123def456ghi789",  "name": "Siti Rahayu"}
{  "ok": false,  "errors": [    "invalid email or password"  ],  "message": "Invalid email or password"}
{  "ok": false,  "errors": [    "api key not found"  ],  "message": "Invalid API key"}
{  "ok": false,  "code": "active-session-exists",  "message": "An active session already exists for this account",  "errors": [    "string"  ],  "data": {    "session_count": 1,    "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/126.0",    "ip_address": "10.0.4.21",    "last_used_at": "2026-09-16T08:12:44Z"  }}

Refresh — Perbarui Token

POST
/api/auth/refresh

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

refresh_token*string

refresh_token yang diterima dari login atau refresh sebelumnya

Response Body

application/json

application/json

application/json

curl -X POST "https://lenz.example.com/api/auth/refresh" \  -H "Content-Type: application/json" \  -d '{    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NDIsImp0aSI6ImI3ZjMuLi4iLCJleHAiOjE3NDYwODY0MDB9.abc123def456ghi789"  }'
{  "ok": true,  "message": "Token refreshed",  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NDIsInNpZCI6ImI3ZjMuLi4iLCJleHAiOjE3NDYwMDE4MDB9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NDIsImp0aSI6ImI3ZjMuLi4iLCJleHAiOjE3NDYwODY0MDB9.abc123def456ghi789",  "name": "Siti Rahayu"}
{  "ok": false,  "errors": [    "refresh_token is required"  ],  "message": "refresh_token is required"}
{  "ok": false,  "code": "not-authenticate",  "errors": [    "session revoked"  ],  "message": "Invalid refresh token"}

Logout — Akhiri Sesi

POST
/api/auth/logout

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

refresh_token?string

refresh_token dari sesi yang ingin diakhiri. Jika dikosongkan, server tetap menjawab 200 tanpa merevoke apa pun.

Response Body

application/json

application/json

curl -X POST "https://lenz.example.com/api/auth/logout" \  -H "Content-Type: application/json" \  -d '{    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NDIsImp0aSI6ImI3ZjMuLi4iLCJleHAiOjE3NDYwODY0MDB9.abc123def456ghi789"  }'
{  "ok": true,  "message": "Logged out"}
{  "ok": false,  "code": "fatal-error",  "message": "Failed to logout"}

Statistik & Status

Ping — Verifikasi Kredensial

GET
/api/auth/ping

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Response Body

application/json

application/json

curl -X GET "https://lenz.example.com/api/auth/ping"
{  "ok": true,  "message": "pong"}
{  "ok": false,  "code": "not-authenticate",  "errors": [    "string"  ],  "message": "Failed verify token"}

Status — Cek Sinkronisasi Integration Lock

GET
/api/auth/status

Header Parameters

X-Integration-Signature?string

JWT HS256 yang ditandatangani dengan secret integration lock (opsional)

Response Body

application/json

curl -X GET "https://lenz.example.com/api/auth/status"
{  "ok": true,  "integration": true}

API Keys

Endpoint untuk mengelola API key tingkat pengguna. API key berguna untuk integrasi service-to-service, skrip otomatis, dan CI/CD pipeline. Setelah API key dibuat atau diperbarui, nilai key rahasia hanya dikembalikan satu kali pada respons — simpan segera.

Jangan menyimpan nilai API key di source code atau commit ke repository publik. Gunakan environment variable, secret manager (seperti Vault atau AWS Secrets Manager), atau file .env yang masuk ke dalam .gitignore.

Daftar API Key

GET
/api/api-keys

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Query Parameters

page?integer

Nomor halaman, dimulai dari 1

Default1
limit?integer

Jumlah data per halaman

Default20
search?string

Pencarian berdasarkan nama API key

filter[status]?string

Filter berdasarkan status API key

Value in"active" | "inactive"

Response Body

application/json

curl -X GET "https://lenz.example.com/api/api-keys"
{  "ok": true,  "message": "success",  "results": {    "limit": 20,    "current_page": 1,    "total_data": 2,    "total_page": 1,    "api_keys": [      {        "id": 7,        "user_id": 42,        "name": "Integrasi CCTV Gedung A",        "status": "active",        "last_used_at": "2026-04-28T08:30:00Z",        "expires_at": "2027-04-30T00:00:00Z",        "created_by": 1,        "created_at": "2026-01-15T10:00:00Z",        "updated_at": "2026-04-01T09:00:00Z",        "username": "siti.rahayu",        "email": "siti.rahayu@example.com"      }    ]  }}

Buat API Key Baru

POST
/api/api-keys

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

curl -X POST "https://lenz.example.com/api/api-keys" \  -H "Content-Type: application/json" \  -d '{    "name": "Integrasi CCTV Gedung B",    "expires_at": "2027-12-31T23:59:59Z"  }'
{  "ok": true,  "message": "success",  "api_key": {    "id": 9,    "user_id": 42,    "name": "Integrasi CCTV Gedung B",    "status": "active",    "key": "lenz_ak_4f8e2a1b3d7c9e0f5a2b6d8c1e4f7a3b",    "last_used_at": null,    "expires_at": "2027-12-31T23:59:59Z",    "created_by": 42,    "created_at": "2026-04-30T12:00:00Z",    "updated_at": "2026-04-30T12:00:00Z",    "username": "siti.rahayu",    "email": "siti.rahayu@example.com"  }}

Detail API Key

GET
/api/api-keys/{id}

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

id*integer

ID numerik API key

Response Body

application/json

curl -X GET "https://lenz.example.com/api/api-keys/7"
{  "ok": true,  "message": "string",  "api_key": {    "id": 7,    "user_id": 42,    "name": "Integrasi CCTV Gedung A",    "status": "active",    "last_used_at": "2026-04-28T08:30:00Z",    "expires_at": "2027-04-30T00:00:00Z",    "created_by": 1,    "created_at": "2026-01-15T10:00:00Z",    "updated_at": "2026-04-01T09:00:00Z",    "username": "siti.rahayu",    "email": "siti.rahayu@example.com"  }}

Perbarui API Key

PUT
/api/api-keys/{id}

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

id*integer

ID numerik API key

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

curl -X PUT "https://lenz.example.com/api/api-keys/7" \  -H "Content-Type: application/json" \  -d '{    "name": "Integrasi CCTV Gedung A — Diperbarui",    "expires_at": "2028-01-01T00:00:00Z"  }'
{  "ok": true,  "message": "string",  "api_key": {    "id": 7,    "user_id": 42,    "name": "Integrasi CCTV Gedung A",    "status": "active",    "last_used_at": "2026-04-28T08:30:00Z",    "expires_at": "2027-04-30T00:00:00Z",    "created_by": 1,    "created_at": "2026-01-15T10:00:00Z",    "updated_at": "2026-04-01T09:00:00Z",    "username": "siti.rahayu",    "email": "siti.rahayu@example.com",    "key": "lenz_ak_4f8e2a1b3d7c9e0f5a2b6d8c1e4f7a3b"  }}

Hapus API Key

DELETE
/api/api-keys/{id}

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

id*integer

ID numerik API key

Response Body

application/json

curl -X DELETE "https://lenz.example.com/api/api-keys/7"
{  "ok": true,  "message": "success"}

Federation Headers

Dalam arsitektur multi-instance Lenz, header X-User-Permissions digunakan oleh Federation Module (Core) saat meneruskan request pengguna ke remote instance (backend) — bukan oleh integrator eksternal. Tidak ada endpoint khusus untuk alur ini; mekanisme ini terjadi otomatis di layer middleware backend.

Ketika Federation Module membuat request ke remote instance, dua header berikut selalu disertakan bersama-sama:

HeaderNilaiKeterangan
X-Api-KeyAPI key remote instance yang validMengotentikasi Federation Module ke remote instance
X-User-PermissionsJWT bertanda tangan HMAC-SHA256Membawa identitas dan izin pengguna yang sudah difilter

JWT X-User-Permissions ditandatangani menggunakan API key remote instance sebagai secret, sehingga remote instance dapat memvalidasi keasliannya tanpa perlu lookup ke database lokal. TTL JWT ini adalah 5 menit — Federation Module membuat JWT baru untuk setiap batch request.

On this page