Initial commit: enterprise digital platform with portal SSO, DigiServer, IT Assets, NetworkView, Server Monitor
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
# Enterprise Digital Platform
|
||||
|
||||
Unified umbrella project that brings together three independent services behind a single portal with SSO.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Browser
|
||||
└── nginx (ports 80 / 443) ← umbrella reverse proxy
|
||||
├── / ← Portal dashboard (Flask, new service)
|
||||
├── /digiserver/ ← DigiServer v2 (Flask)
|
||||
├── /itassets/ ← IT Asset Management (Flask)
|
||||
├── /networkview/ ← NetworkView frontend (React/Vite SPA)
|
||||
└── /networkview/api/ ← NetworkView backend (Node/Express)
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# 1. Copy and fill in secrets
|
||||
cp .env.example .env
|
||||
# Edit .env — at minimum change PORTAL_JWT_SECRET and all *_SECRET_KEY values.
|
||||
|
||||
# 2. Create data directories for DigiServer (it expects them as bind mounts)
|
||||
mkdir -p ../digiserver-v2/data/instance ../digiserver-v2/data/uploads
|
||||
|
||||
# 3. Build and start everything
|
||||
docker compose up --build -d
|
||||
|
||||
# 4. Open http://localhost — default credentials: admin / admin123
|
||||
```
|
||||
|
||||
## Services
|
||||
|
||||
| Container | Internal port | External URL |
|
||||
|-------------------------|---------------|--------------------------|
|
||||
| `edp-portal` | 5001 | `http://host/` |
|
||||
| `edp-digiserver` | 5000 | `http://host/digiserver/`|
|
||||
| `edp-itassets` | 5000 | `http://host/itassets/` |
|
||||
| `edp-networkview-backend`| 3001 | `http://host/networkview/api/` |
|
||||
| `edp-networkview-frontend`| 80 | `http://host/networkview/`|
|
||||
| `edp-nginx` | 80 / 443 | Public entry point |
|
||||
|
||||
## Authentication & SSO
|
||||
|
||||
1. Users log in **once** at the portal (`/login`).
|
||||
2. The portal signs a **JWT cookie** (`edp_portal_token`) that contains the username, role, and list of permitted apps.
|
||||
3. Every request to a sub-app path goes through nginx `auth_request` → the portal's `/api/verify-token` endpoint.
|
||||
4. If the token is valid **and** the user has access to that app, nginx forwards the `X-Auth-Username` / `X-Auth-Role` headers to the sub-app.
|
||||
5. Each Flask sub-app auto-creates a local session for that user (creating the account on first access if needed).
|
||||
|
||||
## Access Management
|
||||
|
||||
Visit `http://host/settings` (admin only) to:
|
||||
- **Create portal users** and assign them access to one or more apps.
|
||||
- **Toggle app access** per user with a single checkbox.
|
||||
- **Generate / revoke API keys** for programmatic access.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
Enterprise_digital-platform/
|
||||
├── docker-compose.yml ← Orchestrates all 5 services
|
||||
├── .env.example ← Copy to .env and fill in secrets
|
||||
├── nginx/
|
||||
│ └── nginx.conf ← Umbrella reverse proxy config
|
||||
└── portal/ ← New portal dashboard service
|
||||
├── Dockerfile
|
||||
├── requirements.txt
|
||||
├── run.py
|
||||
├── config.py
|
||||
└── app/
|
||||
├── models/ ← PortalUser, AppAccess, ApiKey
|
||||
├── routes/ ← auth, dashboard, settings, api (verify-token)
|
||||
├── templates/
|
||||
└── static/css/
|
||||
|
||||
# Existing projects (referenced by docker-compose relative paths)
|
||||
../digiserver-v2/ ← app/utils/portal_sso.py + script_name_fix.py added
|
||||
../IT_asset_management/ ← app/utils/portal_sso.py + script_name_fix.py added
|
||||
../NetworkView/
|
||||
backend/Dockerfile ← added
|
||||
frontend/
|
||||
Dockerfile ← added (multi-stage Vite build + nginx)
|
||||
nginx.conf ← added
|
||||
src/App.tsx ← BrowserRouter basename set from BASE_URL
|
||||
src/api.ts ← API base set from VITE_API_BASE env var
|
||||
vite.config.ts ← base path driven by VITE_BASE_PATH env var
|
||||
```
|
||||
|
||||
## Development (without Docker)
|
||||
|
||||
Each project still works standalone:
|
||||
|
||||
```bash
|
||||
# Portal
|
||||
cd Enterprise_digital-platform/portal
|
||||
pip install -r requirements.txt
|
||||
FLASK_ENV=development python run.py
|
||||
|
||||
# DigiServer v2
|
||||
cd digiserver-v2
|
||||
# ... existing setup unchanged
|
||||
|
||||
# IT Asset Management
|
||||
cd IT_asset_management
|
||||
# ... existing setup unchanged
|
||||
|
||||
# NetworkView
|
||||
cd NetworkView/backend && npm start
|
||||
cd NetworkView/frontend && npm run dev
|
||||
```
|
||||
|
||||
## HTTPS
|
||||
|
||||
Place your certificate and key in `nginx/ssl/cert.pem` and `nginx/ssl/key.pem`, then add an HTTPS server block to `nginx/nginx.conf`.
|
||||
|
||||
---
|
||||
|
||||
## Deployment: Client URL Configuration
|
||||
|
||||
nginx routes traffic **purely by URL path prefix** on port 80. The port number alone carries no routing information — every client device must include the correct module prefix in its server URL.
|
||||
|
||||
### URL pattern
|
||||
|
||||
```
|
||||
http://<your-domain>/<module-prefix>/api/<endpoint>
|
||||
```
|
||||
|
||||
### DigiServer — digital signage players
|
||||
|
||||
Each player stores a "server URL" in its config. Change it to:
|
||||
|
||||
```
|
||||
http://<your-domain>/digiserver
|
||||
```
|
||||
|
||||
The player then calls paths such as:
|
||||
|
||||
| Action | Full URL |
|
||||
|---|---|
|
||||
| Authenticate | `POST http://<your-domain>/digiserver/api/auth/player` |
|
||||
| Fetch playlist | `GET http://<your-domain>/digiserver/api/playlists/<player_id>` |
|
||||
| Send feedback | `POST http://<your-domain>/digiserver/api/player-feedback` |
|
||||
|
||||
### Server Monitor — Raspberry Pi / Linux agents
|
||||
|
||||
Each agent script (or cron job) sends logs to:
|
||||
|
||||
```
|
||||
POST http://<your-domain>/srvmonitor/api/logs/submit
|
||||
```
|
||||
|
||||
Example payload (no auth token needed — this path bypasses portal SSO):
|
||||
|
||||
```json
|
||||
{
|
||||
"hostname": "rpi-kitchen-01",
|
||||
"device_ip": "192.168.1.42",
|
||||
"nume_masa": "Masa-01",
|
||||
"log_message": "Card detected: ABC123",
|
||||
"severity": "info"
|
||||
}
|
||||
```
|
||||
|
||||
Other agent endpoints:
|
||||
|
||||
| Action | Full URL |
|
||||
|---|---|
|
||||
| Submit log (JSON) | `POST http://<your-domain>/srvmonitor/api/logs/submit` |
|
||||
| Upload log file | `POST http://<your-domain>/srvmonitor/api/logs/file` |
|
||||
| Query logs | `GET http://<your-domain>/srvmonitor/api/logs/query` |
|
||||
|
||||
### Why the prefix is required
|
||||
|
||||
Without the prefix, nginx cannot distinguish between modules and the request falls through to the portal (which returns 401/302). There is no routing by port — all traffic enters on port 80 (or 443 for HTTPS).
|
||||
|
||||
```
|
||||
✅ http://yourdomain.com/digiserver/api/auth/player → DigiServer
|
||||
✅ http://yourdomain.com/srvmonitor/api/logs/submit → Server Monitor
|
||||
❌ http://yourdomain.com/api/logs/submit → Portal (wrong!)
|
||||
❌ http://yourdomain.com:5002/api/auth/player → Direct port, bypasses nginx (blocked in prod)
|
||||
```
|
||||
|
||||
### Development vs production URLs
|
||||
|
||||
| Environment | Port | Example base URL |
|
||||
|---|---|---|
|
||||
| Development | 8080 | `http://localhost:8080/srvmonitor` |
|
||||
| Production | 80 | `http://yourdomain.com/srvmonitor` |
|
||||
| Production HTTPS | 443 | `https://yourdomain.com/srvmonitor` |
|
||||
Reference in New Issue
Block a user