Files

192 lines
6.5 KiB
Markdown

# 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` |