Base URL: {{baseUrl}} (otomatis mengikuti domain server) ยท Auth: Authorization: Bearer <access_token> untuk mobile, token admin global untuk panel.
Backend Laravel 10 (PHP 8.3) โ DB SQLite default, bisa switch MySQL via .env. Login mobile selalu lewat backend ini ke server auth myauth.kuroichi.my.id/docs.
Akun uji: dummy001 โฆ dummy100 โ password password.
โฆ/test/* menulis/menghapus data dan hanya aktif saat APP_ENV != production. Jangan expose token admin ke publik.| Variable | Contoh | Keterangan |
|---|---|---|
baseUrl | location.origin + '/api' | Otomatis sesuai domain server |
api_token | notif-secret-key-2026 | Token admin global (.env API_TOKEN) |
employee_token | โ | Legacy token pegawai (opsional; access token lebih diutamakan) |
nup | 199001010000000001 | NUP pegawai (demo) |
access_token | โ | Dari POST /auth/login. Berlaku sampai logout; satu akun boleh punya banyak token. |
Login tidak diproses di HP. Semua kredensial lewat backend agar bebas CORS dan server auth tidak pernah diekspos ke client.
POST /api/auth/login berisi username + password.POST http://myauth.kuroichi.my.id/apisisdm/api/apps/sign sebagai multipart id + paswd.status = "success" dan ada bearer.access_token dari server auth (bukan login_result.code).data_pegawai_sisdm (fallback login_result) dan mengambil absensi dari absensi_sikap; hanya employees yang di-upsert.auth_sessions (hash token) dan mengembalikan Bearer token dari objek bearer.localStorage dan mengirim Authorization: Bearer <access_token> untuk semua request berikutnya.Multi-login: login kedua dari perangkat lain membuat baris/token baru. Logout hanya mencabut token yang dipakai, token perangkat lain tetap aktif.
Cek status: saat app dibuka, mobile memanggil /auth/userinfo; backend memvalidasi Bearer token ke GET /apisisdm/api/apps/me (sekaligus memperpanjang masa aktif 30 hari). Profil dan absensi ikut segar. Bila server auth tak terjangkau, sesi lokal dipertahankan; bila token ditolak (401), sesi dicabut dan app logout.
Konfigurasi URL login: backend memakai APP_LOGIN_URL di framework/.env (otomatis di-inject ke preview /mobile). Build APK memakai VITE_LOGIN_URL di MOBILE/.env; jika kosong, dipakai VITE_API_URL + /auth/login.
| Kode | Arti | Bentuk body |
|---|---|---|
200 | OK (GET / update) | {"success":true, ...} atau data |
201 | Created (POST) | {"success":true,"notification_id":1} |
400 | Bad Request (field kurang) | {"error":"title and body required"} |
401 | Unauthorized / login gagal | {"error":"Unauthorized"} |
404 | Not Found (id/route salah) | {"error":"Not found"} |
422 | User ID / password kosong | {"error":"User ID dan password wajib diisi"} |
429 | Terlalu banyak percobaan login | {"error":"Terlalu banyak percobaan login, coba lagi nanti"} |
502 | Server auth bermasalah / tidak terjangkau | {"error":"Server auth bermasalah: ..."} |
Semua respons sukses mengandung success:true (kecuali /health). Error selalu {"error":"<pesan>"} + HTTP code sesuai tabel.
| Aksi | Admin token | Access token (mobile) |
|---|---|---|
Kirim notifikasi (POST /notifications, /notifications/broadcast) | โ boleh | โ 401 |
Hapus / pulihkan notifikasi (DELETE, /restore) | โ boleh | โ 401 |
| CRUD pegawai, admin log | โ boleh | โ 401 |
GET /employees (data diri) | โ boleh | โ boleh (self) |
Tarik notifikasi (GET /notifications, detail) | โ boleh | โ boleh (self) |
Tandai dibaca (POST /{id}/acknowledge) | โ boleh | โ boleh (self) |
| Absensi hari ini | โ boleh | โ boleh (self) |
| Lihat / cabut sesi login | โ boleh | โ 401 |
/auth/userinfo, /auth/refresh, /auth/logout | โ | โ boleh |
Admin token = token server (.env API_TOKEN) untuk Admin Panel & kirim. Access token = token dari POST /auth/login, disimpan di tabel auth_sessions (SHA-256). Satu akun boleh login di banyak perangkat; logout hanya mematikan token yang dipakai.
Alur: MOBILE โ POST {{baseUrl}}/auth/login โ backend โ POST http://myauth.kuroichi.my.id/apisisdm/api/apps/sign. Mobile tidak pernah memanggil server auth langsung (CORS + kredensial aman).
{
"username": "dummy001",
"password": "password"
}
โ 200 Berhasil:
{
"success": true,
"access_token": "1509133|C8PytmNhnGkO79TlsUZh0zl6Ipn7KUdDTRlAY87w",
"token": "1509133|C8PytmNhnGkO79TlsUZh0zl6Ipn7KUdDTRlAY87w",
"tokens": { "access_token": "...", "token_type": "Bearer", "expires_in": null },
"user": {
"nup": "1990012026013357",
"nama": "TAUFAN MAULANA HARIES",
"user_id": "taufan",
"username": "taufan",
"unit_kerja": "SUBBAGIAN SISTEM INFORMASI SUMBER DAYA MANUSIA",
"jabatan": "ANALIS SISTEM INFORMASI",
"status_pegawai": "NON",
"role_id": 10
},
"absensi_sikap": { "jam_masuk": "07:14:01", "jam_keluar": null }
}
Pemetaan field server auth (acuan utama data_pegawai_sisdm):
| Server auth | Disimpan sebagai |
|---|---|
data_pegawai_sisdm.NUP_BP_NOSPACE (fallback user_no) | NUP (employees.nup) |
data_pegawai_sisdm.NAMA (fallback user_name) | Nama lengkap (employees.nama) |
user_id | Username (employees.username) |
data_pegawai_sisdm.UNIT_KERJA_SUB โ UNIT_KERJA (fallback dept_name) | Unit kerja (employees.unit_kerja) |
data_pegawai_sisdm.NAMA_JABATAN (fallback position_name_2) | Jabatan (employees.jabatan) |
data_pegawai_sisdm.STATUS_PEGAWAI (menggantikan level_id/position_name) | Status pegawai (employees.status_pegawai) |
bearer.access_token | Penanda login sukses + token akses mobile (auth_sessions.access_token = SHA-256) |
absensi_sikap.data.jam_masuk / jam_keluar | Absensi hari ini (dibaca langsung, tidak disimpan ke DB) |
Email tidak dipakai dan tidak ada kolomnya di database.
โ 401 Gagal โ code "01" (user/password salah):
{ "error": "User ID atau password salah" }
โ 422 Gagal โ field kosong:
{ "error": "User ID dan password wajib diisi" }
โ 429 Gagal โ terlalu banyak percobaan (code "03"):
{ "error": "Terlalu banyak percobaan login, coba lagi nanti" }
Auth: Bearer {{access_token}}
Dipakai mobile saat halaman beranda (absensi) dibuka untuk mengecek status login: Bearer token divalidasi ke GET /apisisdm/api/apps/me, profil + absensi diperbarui, dan masa aktif token diperpanjang (sliding 30 hari). Tidak dipanggil dari polling notifikasi/background service. Bila server auth tak terjangkau, profil lokal tetap dipakai; token ditolak โ 401 dan sesi lokal dicabut.
โ
200 Berhasil: {"success":true,"user":{...},"absensi_sikap":{"jam_masuk":"08:00","jam_keluar":null}}
Sama dengan /auth/userinfo (validasi ke /me), ditambah tokens berisi Bearer token yang sama.
{ "access_token": "{{access_token}}" }
โ
200: {"success":true,"tokens":{...},"user":{...}} ยท โ 401: {"error":"Sesi berakhir, silakan login ulang"}
Auth: Bearer {{access_token}}
Cabut token yang dipakai saja. Token lain milik akun yang sama tetap aktif (multi-login).
โ
200: {"success":true}
โ 401: {"error":"Token akses tidak valid"}
Setiap login menyimpan satu baris di auth_sessions. Token asli hanya dikirim ke client satu kali; database menyimpan hash-nya.
| Kolom | Isi |
|---|---|
access_token | SHA-256 dari token asli (unik) |
auth_code | 00 = sukses |
auth_payload | Output JSON server auth apa adanya |
auth_hash | SHA-256 dari auth_payload |
nup, username, employee_id | Pemilik sesi |
device_uuid, ip_address, user_agent | Info login/perangkat |
last_used_at, revoked_at | Terakhir dipakai; diisi saat logout |
Contoh: HP A dan HP B login akun yang sama โ dua token berbeda. Logout di HP A hanya mengisi revoked_at token A; HP B tetap bisa memakai token B.
Validasi token: Authorization: Bearer <token> โ hash โ cari baris dengan revoked_at = null. Tidak valid/revoked โ 401, app logout.
Publik, tanpa auth. Dipakai mobile untuk status server aktif/tidak.
โ 200 Berhasil:
{ "status": "ok", "timestamp": "2026-10-05T08:38:44+00:00" }
Publik. Konfigurasi client dari server: interval polling (menit). Mobile menyimpannya di localStorage. Diatur dari Admin Panel โ Konfigurasi โ Polling Notifikasi; fallback APP_POLL_INTERVAL_MINUTES di framework/.env.
{
"status": "ok",
"poll_interval_minutes": 1,
"server_time": "2026-10-26T01:15:00+07:00"
}
Auth: Bearer {{api_token}}
{
"device_id": "test-device-001",
"device_name": "HP Test",
"platform": "android"
}
โ
200 Berhasil: {"success":true}
โ 401 Gagal โ token salah/kosong: {"error":"Unauthorized"}
โ 400 Gagal โ device_id kosong: {"error":"device_id required"}
Publik. Info APK yang tersedia di public/apk/ (nama, ukuran, waktu update).
{ "apk": { "file": "AppNotifikasi-debug.apk", "size_mb": 8.14, "updated_at": "..." } }
Alur sama dengan halaman /admin: Kirim pakai server token (2 mode: Semua Device / NUP Tertentu), Tarik pakai access token (NUP dari sesi).
Auth: Bearer {{api_token}} (server token) ยท setara pilihan "Semua Device" di Admin
{
"title": "Pengumuman",
"body": "Untuk semua device"
}
โ 201 Berhasil:
{
"success": true,
"notification_id": 5,
"devices_targeted": 3
}
Di log Admin: target_summary = "Semua Device", is_broadcast = 1.
โ 400 Gagal โ title/body kosong: {"error":"title and body required"}
โ 401 Gagal โ token bukan access token/admin: {"error":"Unauthorized"}
Auth: Bearer {{api_token}} (server token) ยท setara pilihan "NUP Tertentu" di Admin
Di Admin, NUP diambil dari upload Excel/CSV kolom NUPNIP atau ketik manual (pisah koma/baris). Semua NUP terkirim โ termasuk yang belum terdaftar di Data Pegawai (dikirim langsung berdasarkan NUP).
{
"title": "Khusus",
"body": "Hanya NUP terpilih",
"link": "https://example.com/doc.pdf",
"target_nups": ["199001010000000001"]
}
โ 201 Berhasil:
{
"success": true,
"notification_id": 6,
"devices_targeted": 1
}
Di log Admin: target_summary = "NUP Bulk (1)", target_nups_total = 1.
Catatan: API juga menerima device_ids, unit_kerja, jabatan untuk kebutuhan lanjutan (di luar UI Admin). Endpoint POST /notifications tersedia untuk kirim satu pesan dengan body yang sama (tanpa is_broadcast).
Auth: Bearer {{access_token}} ยท NUP diambil dari token
Hanya broadcast (is_broadcast) atau NUP dikunci untuk user. Device terima target_nups_count (bukan daftar). Retensi 6 bulan.
โ 200 Berhasil:
{
"notifications": [
{
"id": 1,
"title": "Uji Notifikasi Laravel",
"body": "Server Laravel",
"link": "https://example.com/dokumen.pdf",
"is_broadcast": 1,
"acknowledged": 0,
"target_nups_count": 0,
"created_at": "2026-10-05 10:51:27",
"updated_at": "2026-10-05 10:51:27"
}
],
"count": 1
}
โ 400 Gagal โ tanpa device_id/token/nup:
{
"error": "device_id, employee_token or nup required"
}
Detail + target_summary. 404 bila bukan target / lebih tua 6 bulan.
โ
200 Berhasil: {"notification":{...,"target_summary":"Semua Device","acknowledged":1}}
โ 404 Gagal โ bukan target / id tak ada: {"error":"Not found"}
{
"nup": "{{nup}}"
}
โ
200 Berhasil: {"success":true}
โ 401 Gagal โ token bukan pegawai & bukan admin: {"error":"Unauthorized"}
โ 400 Gagal โ device_id kosong: {"error":"device_id required"}
Sembunyi dari device, badge di Admin. Pulihkan via POST {{baseUrl}}/notifications/:id/restore
โ
200 Berhasil: {"success":true} ยท โ 404: {"error":"Not found"}
Log full (tanpa retensi): targets_count, target_summary, daftar NUP max 200 + target_nups_total.
Auth: Bearer {{api_token}}
โ
200: {"settings":{"poll_interval_minutes":1}}
Auth: Bearer {{api_token}}
{ "poll_interval_minutes": 5 }
โ
200: {"success":true,"settings":{"poll_interval_minutes":5}} ยท โ 422: nilai harus 1-1440 menit
Auth: Bearer {{api_token}}
Daftar sesi login per pegawai (max 200): device_uuid, ip_address, user_agent, last_used_at, revoked_at, active. Tanpa nup = semua sesi.
Auth: Bearer {{api_token}}
โ
200: {"success":true} ยท โ 404: {"error":"Not found"}
Auth: Bearer {{api_token}}
{ "nup": "{{nup}}" }
โ
200: {"success":true,"revoked":2} ยท โ 400: {"error":"nup or employee_id required"}
Di Admin Panel: tombol ๐ pada baris pegawai โ modal Sesi Login โ tombol Logout per sesi atau Logout Semua. Token yang dicabut langsung dapat 401 di request berikutnya (mobile auto-logout).
Access token โ hanya data diri sendiri. Admin token โ semua + filter nup/search.
โ
200 Berhasil: {"employees":[{...,"token":"ef105f..."}],"count":1} ยท โ 401: {"error":"Unauthorized"}
{
"nama": "Budi Santoso",
"nup": "12345",
"username": "budi",
"unit_kerja": "IT",
"jabatan": "Staff",
"status_pegawai": "Aktif"
}
โ
201 Berhasil: {"success":true,"id":1,"token":"a1b2c3..."}
โ 400 Gagal โ nama/nup kosong: {"error":"nama and nup required"}
PUT: { "id": 1, "jabatan": "Supervisor" }
DELETE: { "id": 1 }
โ
200 Berhasil: {"success":true} ยท โ 400: {"error":"id required"} ยท โ 404: {"error":"Not found"}
Rotate token tak memutus kiriman (fetch kunci NUP).
โ
200 Berhasil: {"success":true,"token":"token-baru..."} ยท โ 404: {"error":"Not found"}
Absensi hari ini dibaca langsung dari objek absensi_sikap.data di server auth (jam_masuk/jam_keluar) memakai Bearer token yang sama. Tidak ada tabel attendances dan data tidak disimpan di database.
Auth: Bearer {{access_token}} (self)
โ
200: {"attendance":{"jam_masuk":"08:00","jam_keluar":null},"status":"Sudah Masuk","tanggal":"2026-10-25"}
โ 401: Bearer token tidak valid / sudah logout ยท โ 502: server auth tidak terjangkau
{"title":"Uji Coba","body":"Pesan dummy"}
Default 3 tabel (notifications, device_notifications, notification_nups). employees/devices aman โ kecuali kirim {"tables":["all"]} (semua 6 tabel termasuk auth_sessions, semua token hangus, HP wajib login ulang).
{}
# Reset SEMUA tabel (bahaya):
{"tables":["all"]}
1. POST /auth/login {"username":"dummy001","password":"password"}
2. GET /auth/userinfo (Bearer access_token)
3. POST /test/notification {}
4. GET /notifications (Bearer access_token)
5. POST /auth/logout (Bearer access_token)