Initial commit
This commit is contained in:
244
cpone-dashboard/README.md
Normal file
244
cpone-dashboard/README.md
Normal file
@@ -0,0 +1,244 @@
|
||||
# CPONE Dashboard
|
||||
|
||||
Web dashboard berbasis Go untuk monitoring CPONE.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Go 1.22+
|
||||
- Akses SSH ke `devcpone.aplikasi.web.id` (untuk koneksi ke database)
|
||||
|
||||
## Cara Menjalankan
|
||||
|
||||
### 1. Setup `.env`
|
||||
|
||||
Salin `.env.example` menjadi `.env`:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Isi `.env` dengan credential yang sesuai:
|
||||
|
||||
```
|
||||
APP_PORT=8080
|
||||
DB_DSN=user:password@tcp(127.0.0.1:3307)/cpone_dashboard?parseTime=true&loc=Local
|
||||
```
|
||||
|
||||
> Port `3307` digunakan karena database diakses melalui SSH tunnel (bukan langsung port 3306).
|
||||
|
||||
### 2. Buka SSH Tunnel ke Database
|
||||
|
||||
Jalankan perintah ini di terminal **terpisah** (atau di background):
|
||||
|
||||
```bash
|
||||
ssh -f -N -L 3307:127.0.0.1:3306 one@devcpone.aplikasi.web.id
|
||||
```
|
||||
|
||||
Kalau muncul error `Address already in use`, berarti tunnel sudah aktif — lanjut ke langkah berikutnya.
|
||||
|
||||
### 3. Jalankan App
|
||||
|
||||
```bash
|
||||
go run .
|
||||
```
|
||||
|
||||
App berjalan di: [http://localhost:8080/dashboard](http://localhost:8080/dashboard)
|
||||
|
||||
---
|
||||
|
||||
## Cara Menghentikan
|
||||
|
||||
Hentikan tunnel dan app sekaligus:
|
||||
|
||||
```bash
|
||||
make stop
|
||||
```
|
||||
|
||||
Atau manual — cari dan kill prosesnya:
|
||||
|
||||
```bash
|
||||
# Hentikan app (port 8080)
|
||||
lsof -ti:8080 | xargs kill
|
||||
|
||||
# Hentikan SSH tunnel (port 3307)
|
||||
lsof -ti:3307 | xargs kill
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Kustomisasi Tampilan
|
||||
|
||||
### Ganti Logo
|
||||
|
||||
Timpa file berikut dengan logo baru (format PNG, background transparan atau putih):
|
||||
|
||||
```
|
||||
static/img/logo.png
|
||||
```
|
||||
|
||||
Tidak perlu ubah kode — logo langsung berubah di seluruh halaman.
|
||||
|
||||
### Ganti Warna Utama
|
||||
|
||||
Semua warna primary dikendalikan dari satu tempat di `templates/layout/base.html`:
|
||||
|
||||
```js
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
brand: {
|
||||
50: '#eef0fb',
|
||||
100: '#dde2f7',
|
||||
...
|
||||
500: '#3b50a0', // <-- warna utama (header, badge, dll)
|
||||
...
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Ubah nilai hex di blok `brand`, semua elemen yang pakai `brand-*` ikut berubah.
|
||||
|
||||
---
|
||||
|
||||
## Autentikasi & Manajemen User
|
||||
|
||||
### Alur Login
|
||||
|
||||
```
|
||||
Browser Go (auth middleware) DB (dashboard_user)
|
||||
│ │ │
|
||||
│ GET /dashboard │ │
|
||||
│ ────────────────────────► │ cek cookie session │
|
||||
│ │ (tidak ada / invalid) │
|
||||
│ redirect /login ◄────── │ │
|
||||
│ │ │
|
||||
│ POST /login │ │
|
||||
│ username=budi ───► │ SELECT User_Password, │
|
||||
│ password=xxx │ User_Salt ──► │
|
||||
│ │ ◄──────── │ hash + salt
|
||||
│ │ SHA2(salt:password, 256) │
|
||||
│ │ cocokkan dengan hash │
|
||||
│ │ │
|
||||
│ set cookie + redirect ◄─ │ ✓ cocok → set session cookie│
|
||||
│ ke /dashboard │ │
|
||||
```
|
||||
|
||||
### Alur Password Hashing
|
||||
|
||||
Password tidak pernah disimpan dalam bentuk plain text. Setiap user punya **salt unik** yang di-generate otomatis saat insert/update.
|
||||
|
||||
```
|
||||
sp_upsert_dashboard_user('budi', 'password123', 'Budi Santoso')
|
||||
│
|
||||
├─ v_salt = UUID() → contoh: "a91f-yyyy-..."
|
||||
├─ v_hash = SHA2("a91f-yyyy-...:password123", 256)
|
||||
│
|
||||
└─ simpan ke DB:
|
||||
User_Password = "f3c2..." ← hash
|
||||
User_Salt = "a91f-..." ← salt
|
||||
```
|
||||
|
||||
Efeknya: dua user dengan password yang sama tetap menghasilkan hash yang berbeda di DB, karena salt-nya berbeda.
|
||||
|
||||
### Menambah User Baru
|
||||
|
||||
```sql
|
||||
-- Error jika username sudah terdaftar
|
||||
CALL sp_insert_dashboard_user('budi', 'password123', 'Budi Santoso');
|
||||
```
|
||||
|
||||
### Reset Password
|
||||
|
||||
```sql
|
||||
-- Error jika username tidak ditemukan
|
||||
CALL sp_reset_dashboard_user_password('budi', 'passwordbaru');
|
||||
```
|
||||
|
||||
### Nonaktifkan User
|
||||
|
||||
```sql
|
||||
UPDATE dashboard_user SET User_IsActive = 'N' WHERE User_Username = 'budi';
|
||||
```
|
||||
|
||||
### Struktur Tabel `dashboard_user`
|
||||
|
||||
| Kolom | Tipe | Keterangan |
|
||||
|---|---|---|
|
||||
| `User_ID` | INT | Primary key, auto increment |
|
||||
| `User_Username` | VARCHAR(50) | Login username, unique |
|
||||
| `User_Password` | VARCHAR(64) | SHA2-256 hash |
|
||||
| `User_Salt` | VARCHAR(36) | UUID salt, unik per user/reset |
|
||||
| `User_DisplayName` | VARCHAR(100) | Nama yang ditampilkan di header |
|
||||
| `User_IsActive` | CHAR(1) | `Y` = aktif, `N` = nonaktif |
|
||||
|
||||
---
|
||||
|
||||
## Mapping User ke MCU Project
|
||||
|
||||
Satu user bisa diassign ke lebih dari satu `mcu_project`. Relasi disimpan di tabel `dashboard_user_project`.
|
||||
|
||||
### Relasi
|
||||
|
||||
```
|
||||
dashboard_user dashboard_user_project mcu_project
|
||||
────────────── ────────────────────── ───────────
|
||||
User_ID ◄──── UserProj_UserID Mcu_ProjectMcuID
|
||||
UserProj_McuID ────►
|
||||
UserProj_IsActive
|
||||
```
|
||||
|
||||
### Assign / Cabut Akses Project
|
||||
|
||||
```sql
|
||||
-- Assign user ke satu project
|
||||
CALL sp_assign_user_project('budi', 101);
|
||||
|
||||
-- Assign ke project lain (bisa lebih dari satu)
|
||||
CALL sp_assign_user_project('budi', 205);
|
||||
|
||||
-- Cabut akses dari satu project (soft delete, data tetap ada)
|
||||
CALL sp_remove_user_project('budi', 101);
|
||||
```
|
||||
|
||||
### Lihat Project yang Bisa Diakses User
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
u.User_Username,
|
||||
u.User_DisplayName,
|
||||
p.Mcu_ProjectMcuID,
|
||||
p.Mcu_ProjectLabel,
|
||||
p.Mcu_ProjectCorporateName,
|
||||
up.UserProj_IsActive
|
||||
FROM dashboard_user_project up
|
||||
JOIN dashboard_user u ON u.User_ID = up.UserProj_UserID
|
||||
JOIN mcu_project p ON p.Mcu_ProjectMcuID = up.UserProj_McuID
|
||||
WHERE u.User_Username = 'budi'
|
||||
AND up.UserProj_IsActive = 'Y';
|
||||
```
|
||||
|
||||
### Struktur Tabel `dashboard_user_project`
|
||||
|
||||
| Kolom | Tipe | Keterangan |
|
||||
|---|---|---|
|
||||
| `UserProj_ID` | INT | Primary key, auto increment |
|
||||
| `UserProj_UserID` | INT | Referensi ke `dashboard_user.User_ID` |
|
||||
| `UserProj_McuID` | INT | Referensi ke `mcu_project.Mcu_ProjectMcuID` |
|
||||
| `UserProj_IsActive` | CHAR(1) | `Y` = aktif, `N` = dicabut |
|
||||
|
||||
---
|
||||
|
||||
## Shortcut via Makefile
|
||||
|
||||
| Perintah | Keterangan |
|
||||
|---|---|
|
||||
| `make start` | Buka SSH tunnel + jalankan app |
|
||||
| `make stop` | Hentikan app dan SSH tunnel |
|
||||
| `make restart` | Stop lalu start ulang |
|
||||
| `make run` | Jalankan app saja (tanpa buka tunnel) |
|
||||
| `make build` | Build binary untuk Linux |
|
||||
| `make deploy` | Build + deploy ke server |
|
||||
Reference in New Issue
Block a user