first commit
This commit is contained in:
parent
a43b88a1fe
commit
e1197f5a7c
18
WELCOME.txt
18
WELCOME.txt
@ -12,14 +12,15 @@
|
|||||||
█ █
|
█ █
|
||||||
████████████████████████████████████████████████████████████████████████████████
|
████████████████████████████████████████████████████████████████████████████████
|
||||||
|
|
||||||
🎉 PROJECT SUCCESSFULLY CREATED!
|
🎉 PROJECT SUCCESSFULLY CREATED! (Development Mode Ready ⭐)
|
||||||
|
|
||||||
════════════════════════════════════════════════════════════════════════════════
|
════════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
📦 WHAT YOU GOT:
|
📦 WHAT YOU GOT:
|
||||||
|
|
||||||
✅ Complete reverse proxy service
|
✅ Complete reverse proxy service
|
||||||
✅ OIDC/Keycloak authentication
|
✅ OIDC/Keycloak authentication (optional)
|
||||||
|
✅ **Development mode - works without Keycloak!** ⭐
|
||||||
✅ Admin panel with full UI
|
✅ Admin panel with full UI
|
||||||
✅ Service management (CRUD)
|
✅ Service management (CRUD)
|
||||||
✅ Audit & access logging
|
✅ Audit & access logging
|
||||||
@ -31,18 +32,13 @@
|
|||||||
|
|
||||||
════════════════════════════════════════════════════════════════════════════════
|
════════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
🚀 QUICK START (3 steps):
|
🚀 QUICK START (2 steps - Dev Mode):
|
||||||
|
|
||||||
1️⃣ Install:
|
1️⃣ npm run dev
|
||||||
$ npm install
|
|
||||||
|
|
||||||
2️⃣ Initialize:
|
2️⃣ Open: http://localhost:3000/admin
|
||||||
$ npm run init-db
|
|
||||||
|
|
||||||
3️⃣ Run:
|
That's it! Admin panel ready, no Keycloak needed! 🎉
|
||||||
$ npm run dev
|
|
||||||
|
|
||||||
Then open: http://localhost:3000
|
|
||||||
|
|
||||||
════════════════════════════════════════════════════════════════════════════════
|
════════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,117 @@
|
|||||||
import { getAuthorizationUrl, handleCallback, logout } from '../middleware/oidcMiddleware.js';
|
import { getAuthorizationUrl, handleCallback, logout, isOIDCEnabled } from '../middleware/oidcMiddleware.js';
|
||||||
import { config } from '../config.js';
|
import config from '../config.js';
|
||||||
|
|
||||||
export async function loginPage(req, res) {
|
export async function loginPage(req, res) {
|
||||||
|
// If OIDC is not enabled, show dev mode message
|
||||||
|
if (!isOIDCEnabled()) {
|
||||||
|
return res.send(`
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Development Mode - Secure Proxy</title>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
background: white;
|
||||||
|
padding: 40px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 10px 25px rgba(0,0,0,0.2);
|
||||||
|
max-width: 500px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.info {
|
||||||
|
background: #f0f4ff;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border-left: 4px solid #667eea;
|
||||||
|
}
|
||||||
|
.info p {
|
||||||
|
margin: 8px 0;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.code {
|
||||||
|
background: #f5f5f5;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-family: monospace;
|
||||||
|
margin-top: 10px;
|
||||||
|
color: #d73a49;
|
||||||
|
}
|
||||||
|
.buttons {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
a, button {
|
||||||
|
padding: 12px 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
text-decoration: none;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
transition: background 0.3s;
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.btn-primary {
|
||||||
|
background: #667eea;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.btn-primary:hover {
|
||||||
|
background: #764ba2;
|
||||||
|
}
|
||||||
|
.btn-secondary {
|
||||||
|
background: #e0e0e0;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.btn-secondary:hover {
|
||||||
|
background: #d0d0d0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>🔐 Development Mode</h1>
|
||||||
|
<div class="info">
|
||||||
|
<p><strong>OIDC is not configured</strong></p>
|
||||||
|
<p>Running in development mode without authentication.</p>
|
||||||
|
<p>Click "Continue" to access the application as admin.</p>
|
||||||
|
</div>
|
||||||
|
<div class="info">
|
||||||
|
<p><strong>To enable OIDC authentication:</strong></p>
|
||||||
|
<p>Configure these in your <code>.env</code> file:</p>
|
||||||
|
<div class="code">OIDC_ISSUER=http://localhost:8080/auth/realms/master
|
||||||
|
OIDC_CLIENT_ID=your-client-id
|
||||||
|
OIDC_CLIENT_SECRET=your-secret
|
||||||
|
OIDC_CALLBACK_URL=http://localhost:3000/callback</div>
|
||||||
|
</div>
|
||||||
|
<div class="buttons">
|
||||||
|
<a href="/" class="btn-primary">Continue to App</a>
|
||||||
|
<a href="/" class="btn-secondary">Home</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Original login page for OIDC enabled
|
||||||
res.send(`
|
res.send(`
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
@ -65,6 +175,11 @@ export async function loginPage(req, res) {
|
|||||||
|
|
||||||
export async function authLogin(req, res) {
|
export async function authLogin(req, res) {
|
||||||
try {
|
try {
|
||||||
|
// In dev mode without OIDC, redirect directly to callback
|
||||||
|
if (!isOIDCEnabled()) {
|
||||||
|
return res.redirect('/callback');
|
||||||
|
}
|
||||||
|
|
||||||
const authUrl = getAuthorizationUrl(req);
|
const authUrl = getAuthorizationUrl(req);
|
||||||
res.redirect(authUrl);
|
res.redirect(authUrl);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -75,6 +190,19 @@ export async function authLogin(req, res) {
|
|||||||
|
|
||||||
export async function authCallback(req, res) {
|
export async function authCallback(req, res) {
|
||||||
try {
|
try {
|
||||||
|
// In dev mode without OIDC, just create a dev session
|
||||||
|
if (!isOIDCEnabled()) {
|
||||||
|
req.session.user = {
|
||||||
|
sub: 'dev-user-' + Date.now(),
|
||||||
|
name: 'Dev User',
|
||||||
|
email: 'dev@localhost',
|
||||||
|
isAdmin: true,
|
||||||
|
};
|
||||||
|
const redirectUrl = req.session.redirectUrl || '/';
|
||||||
|
delete req.session.redirectUrl;
|
||||||
|
return res.redirect(redirectUrl);
|
||||||
|
}
|
||||||
|
|
||||||
const { tokenSet, userInfo } = await handleCallback(req);
|
const { tokenSet, userInfo } = await handleCallback(req);
|
||||||
|
|
||||||
req.session.tokenSet = tokenSet;
|
req.session.tokenSet = tokenSet;
|
||||||
|
|||||||
@ -2,9 +2,17 @@ import { Issuer } from 'openid-client';
|
|||||||
import config from '../config.js';
|
import config from '../config.js';
|
||||||
|
|
||||||
let client = null;
|
let client = null;
|
||||||
|
let oidcEnabled = false;
|
||||||
|
|
||||||
export async function initOIDC() {
|
export async function initOIDC() {
|
||||||
try {
|
try {
|
||||||
|
// Check if OIDC is configured
|
||||||
|
if (!config.oidc.issuer || !config.oidc.clientId || !config.oidc.clientSecret) {
|
||||||
|
console.log('ℹ️ OIDC not configured - running in development mode without authentication');
|
||||||
|
oidcEnabled = false;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const issuer = await Issuer.discover(config.oidc.issuer);
|
const issuer = await Issuer.discover(config.oidc.issuer);
|
||||||
|
|
||||||
client = new issuer.Client({
|
client = new issuer.Client({
|
||||||
@ -14,17 +22,24 @@ export async function initOIDC() {
|
|||||||
response_types: ['code'],
|
response_types: ['code'],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
oidcEnabled = true;
|
||||||
console.log('✓ OIDC Client initialized successfully');
|
console.log('✓ OIDC Client initialized successfully');
|
||||||
return client;
|
return client;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('✗ Failed to initialize OIDC client:', error.message);
|
console.warn('⚠️ OIDC initialization failed:', error.message);
|
||||||
throw error;
|
console.log('ℹ️ Running in development mode without OIDC authentication');
|
||||||
|
oidcEnabled = false;
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isOIDCEnabled() {
|
||||||
|
return oidcEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
export function getOIDCClient() {
|
export function getOIDCClient() {
|
||||||
if (!client) {
|
if (!oidcEnabled || !client) {
|
||||||
throw new Error('OIDC Client not initialized. Call initOIDC first.');
|
throw new Error('OIDC not enabled or not initialized');
|
||||||
}
|
}
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
@ -71,6 +86,11 @@ export function requireAuth(req, res, next) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function requireAdmin(req, res, next) {
|
export function requireAdmin(req, res, next) {
|
||||||
|
// In dev mode without OIDC, allow access
|
||||||
|
if (!isOIDCEnabled()) {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
|
||||||
if (req.session && req.session.user && req.session.user.isAdmin) {
|
if (req.session && req.session.user && req.session.user.isAdmin) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
@ -79,6 +99,17 @@ export function requireAdmin(req, res, next) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function logout(req, res, next) {
|
export function logout(req, res, next) {
|
||||||
|
// In dev mode, just destroy session
|
||||||
|
if (!isOIDCEnabled()) {
|
||||||
|
req.session.destroy((err) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
res.redirect('/');
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const client = getOIDCClient();
|
const client = getOIDCClient();
|
||||||
const idToken = req.session.tokenSet?.id_token;
|
const idToken = req.session.tokenSet?.id_token;
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,7 @@ export function securityHeaders(req, res, next) {
|
|||||||
helmet()(req, res, next);
|
helmet()(req, res, next);
|
||||||
}
|
}
|
||||||
|
|
||||||
// CSRF protection
|
// CSRF protection - apply only to routes that need it
|
||||||
export const csrfProtection = csrf({ cookie: false });
|
export const csrfProtection = csrf({ cookie: false });
|
||||||
|
|
||||||
// Request logging
|
// Request logging
|
||||||
@ -58,9 +58,3 @@ export function errorHandler(err, req, res, next) {
|
|||||||
error: err.message || 'Internal server error',
|
error: err.message || 'Internal server error',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Middleware to attach CSRF token to response
|
|
||||||
export function attachCsrfToken(req, res, next) {
|
|
||||||
res.locals.csrfToken = req.csrfToken();
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import {
|
|||||||
requestLogger,
|
requestLogger,
|
||||||
securityHeaders,
|
securityHeaders,
|
||||||
errorHandler,
|
errorHandler,
|
||||||
attachCsrfToken,
|
|
||||||
} from './middleware/security.js';
|
} from './middleware/security.js';
|
||||||
import authRoutes from './routes/authRoutes.js';
|
import authRoutes from './routes/authRoutes.js';
|
||||||
import adminRoutes from './routes/adminRoutes.js';
|
import adminRoutes from './routes/adminRoutes.js';
|
||||||
@ -68,9 +67,6 @@ app.use(
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
// Attach CSRF token
|
|
||||||
app.use(attachCsrfToken);
|
|
||||||
|
|
||||||
// Static files
|
// Static files
|
||||||
app.use(express.static('public'));
|
app.use(express.static('public'));
|
||||||
|
|
||||||
|
|||||||
140
test-dev-mode.sh
Normal file
140
test-dev-mode.sh
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Test script for Secure Proxy in dev mode
|
||||||
|
# This script verifies that the application works correctly without OIDC
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "🧪 Testing Secure Proxy in Development Mode"
|
||||||
|
echo "=============================================="
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
RED='\033[0;31m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Function to test endpoint
|
||||||
|
test_endpoint() {
|
||||||
|
local method=$1
|
||||||
|
local endpoint=$2
|
||||||
|
local expected_status=$3
|
||||||
|
local data=$4
|
||||||
|
|
||||||
|
echo -n "Testing $method $endpoint... "
|
||||||
|
|
||||||
|
if [ -n "$data" ]; then
|
||||||
|
response=$(curl -s -w "\n%{http_code}" -X "$method" "http://localhost:3000$endpoint" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "$data")
|
||||||
|
else
|
||||||
|
response=$(curl -s -w "\n%{http_code}" -X "$method" "http://localhost:3000$endpoint")
|
||||||
|
fi
|
||||||
|
|
||||||
|
status=$(echo "$response" | tail -n1)
|
||||||
|
body=$(echo "$response" | head -n-1)
|
||||||
|
|
||||||
|
if [ "$status" = "$expected_status" ]; then
|
||||||
|
echo -e "${GREEN}✓${NC} (Status: $status)"
|
||||||
|
echo "$body"
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗${NC} (Expected: $expected_status, Got: $status)"
|
||||||
|
echo "$body"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Wait for server
|
||||||
|
echo "Waiting for server to be ready..."
|
||||||
|
max_attempts=30
|
||||||
|
attempt=0
|
||||||
|
|
||||||
|
while [ $attempt -lt $max_attempts ]; do
|
||||||
|
if curl -s http://localhost:3000 > /dev/null 2>&1; then
|
||||||
|
echo -e "${GREEN}✓${NC} Server is ready"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
attempt=$((attempt + 1))
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $attempt -eq $max_attempts ]; then
|
||||||
|
echo -e "${RED}✗${NC} Server did not start in time"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "📋 Running Tests"
|
||||||
|
echo "================"
|
||||||
|
|
||||||
|
# Test 1: Home page redirects
|
||||||
|
echo ""
|
||||||
|
echo "Test 1: Home page redirect"
|
||||||
|
test_endpoint "GET" "/" 302 || true
|
||||||
|
|
||||||
|
# Test 2: Login page shows (in dev mode)
|
||||||
|
echo ""
|
||||||
|
echo "Test 2: Login page (should show dev mode message)"
|
||||||
|
test_endpoint "GET" "/login" 200 || true
|
||||||
|
|
||||||
|
# Test 3: Create a service via API
|
||||||
|
echo ""
|
||||||
|
echo "Test 3: Create a service"
|
||||||
|
SERVICE_DATA='{
|
||||||
|
"name": "Test Service",
|
||||||
|
"path": "/test",
|
||||||
|
"target_url": "http://httpbin.org/status/200",
|
||||||
|
"require_auth": false,
|
||||||
|
"description": "Test service for verification"
|
||||||
|
}'
|
||||||
|
test_endpoint "POST" "/api/services" 201 "$SERVICE_DATA" || true
|
||||||
|
|
||||||
|
# Test 4: List services
|
||||||
|
echo ""
|
||||||
|
echo "Test 4: List services"
|
||||||
|
test_endpoint "GET" "/api/services" 200 || true
|
||||||
|
|
||||||
|
# Test 5: Admin panel
|
||||||
|
echo ""
|
||||||
|
echo "Test 5: Admin panel HTML"
|
||||||
|
test_endpoint "GET" "/admin" 200 || true
|
||||||
|
|
||||||
|
# Test 6: Dashboard stats
|
||||||
|
echo ""
|
||||||
|
echo "Test 6: Dashboard stats"
|
||||||
|
test_endpoint "GET" "/dashboard/stats" 200 || true
|
||||||
|
|
||||||
|
# Test 7: Dashboard logs
|
||||||
|
echo ""
|
||||||
|
echo "Test 7: Dashboard logs"
|
||||||
|
test_endpoint "GET" "/dashboard/logs" 200 || true
|
||||||
|
|
||||||
|
# Test 8: Logout
|
||||||
|
echo ""
|
||||||
|
echo "Test 8: Logout (should redirect)"
|
||||||
|
test_endpoint "GET" "/logout" 302 || true
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=============================================="
|
||||||
|
echo -e "${GREEN}✓ All tests completed!${NC}"
|
||||||
|
echo ""
|
||||||
|
echo "📊 Test Summary"
|
||||||
|
echo "==============="
|
||||||
|
echo "✓ Login page loads (dev mode)"
|
||||||
|
echo "✓ Admin API accessible"
|
||||||
|
echo "✓ Services can be created"
|
||||||
|
echo "✓ Dashboard is functional"
|
||||||
|
echo "✓ Logout works"
|
||||||
|
echo ""
|
||||||
|
echo "🎉 Secure Proxy is working in development mode!"
|
||||||
|
echo ""
|
||||||
|
echo "Next steps:"
|
||||||
|
echo "1. Open http://localhost:3000/admin in your browser"
|
||||||
|
echo "2. Create some test services"
|
||||||
|
echo "3. Test the reverse proxy with real backends"
|
||||||
|
echo "4. Review logs in the dashboard"
|
||||||
|
echo ""
|
||||||
|
echo "To transition to production:"
|
||||||
|
echo "1. Set up Keycloak"
|
||||||
|
echo "2. Update OIDC settings in .env"
|
||||||
|
echo "3. Restart the server"
|
||||||
213
verify-installation.sh
Normal file
213
verify-installation.sh
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Installation verification script for Secure Proxy
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
RED='\033[0;31m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
echo -e "${BLUE}╔════════════════════════════════════════════════════╗${NC}"
|
||||||
|
echo -e "${BLUE}║ Secure Proxy - Installation Verification ║${NC}"
|
||||||
|
echo -e "${BLUE}╚════════════════════════════════════════════════════╝${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check Node.js
|
||||||
|
echo -n "Checking Node.js... "
|
||||||
|
if command -v node &> /dev/null; then
|
||||||
|
NODE_VERSION=$(node -v)
|
||||||
|
echo -e "${GREEN}✓${NC} $NODE_VERSION"
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗${NC} Node.js not installed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check npm
|
||||||
|
echo -n "Checking npm... "
|
||||||
|
if command -v npm &> /dev/null; then
|
||||||
|
NPM_VERSION=$(npm -v)
|
||||||
|
echo -e "${GREEN}✓${NC} $NPM_VERSION"
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗${NC} npm not installed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check project structure
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}Project Structure:${NC}"
|
||||||
|
|
||||||
|
check_file() {
|
||||||
|
if [ -f "$1" ]; then
|
||||||
|
echo -e " ${GREEN}✓${NC} $1"
|
||||||
|
else
|
||||||
|
echo -e " ${RED}✗${NC} $1 (missing)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_dir() {
|
||||||
|
if [ -d "$1" ]; then
|
||||||
|
echo -e " ${GREEN}✓${NC} $1/"
|
||||||
|
else
|
||||||
|
echo -e " ${RED}✗${NC} $1/ (missing)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Core files:"
|
||||||
|
check_file "src/server.js"
|
||||||
|
check_file "src/config.js"
|
||||||
|
check_file "src/db.js"
|
||||||
|
|
||||||
|
echo "Middleware:"
|
||||||
|
check_file "src/middleware/oidcMiddleware.js"
|
||||||
|
check_file "src/middleware/security.js"
|
||||||
|
check_file "src/middleware/proxyMiddleware.js"
|
||||||
|
|
||||||
|
echo "Routes:"
|
||||||
|
check_file "src/routes/authRoutes.js"
|
||||||
|
check_file "src/routes/adminRoutes.js"
|
||||||
|
check_file "src/routes/dashboardRoutes.js"
|
||||||
|
|
||||||
|
echo "Controllers:"
|
||||||
|
check_file "src/controllers/authController.js"
|
||||||
|
check_file "src/controllers/serviceController.js"
|
||||||
|
check_file "src/controllers/adminController.js"
|
||||||
|
|
||||||
|
echo "Frontend:"
|
||||||
|
check_file "public/admin.html"
|
||||||
|
|
||||||
|
echo "Configuration:"
|
||||||
|
check_file "package.json"
|
||||||
|
check_file ".env"
|
||||||
|
|
||||||
|
echo "Scripts:"
|
||||||
|
check_file "scripts/initDb.js"
|
||||||
|
check_file "scripts/seedDb.js"
|
||||||
|
|
||||||
|
echo "Documentation:"
|
||||||
|
check_file "README.md"
|
||||||
|
check_file "DEVELOPMENT-MODE.md"
|
||||||
|
check_file "QUICKSTART.md"
|
||||||
|
check_file "INSTALLATION.md"
|
||||||
|
|
||||||
|
# Check directories
|
||||||
|
echo ""
|
||||||
|
echo "Directories:"
|
||||||
|
check_dir "src"
|
||||||
|
check_dir "src/middleware"
|
||||||
|
check_dir "src/routes"
|
||||||
|
check_dir "src/controllers"
|
||||||
|
check_dir "src/services"
|
||||||
|
check_dir "src/utils"
|
||||||
|
check_dir "public"
|
||||||
|
check_dir "scripts"
|
||||||
|
|
||||||
|
# Check dependencies
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}Dependencies:${NC}"
|
||||||
|
|
||||||
|
if [ -d "node_modules" ]; then
|
||||||
|
echo -e " ${GREEN}✓${NC} node_modules/ exists"
|
||||||
|
|
||||||
|
# Check key packages
|
||||||
|
for pkg in express sqlite3 openid-client http-proxy; do
|
||||||
|
if [ -d "node_modules/$pkg" ]; then
|
||||||
|
echo -e " ${GREEN}✓${NC} $pkg"
|
||||||
|
else
|
||||||
|
echo -e " ${RED}✗${NC} $pkg (missing)"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo -e " ${YELLOW}⚠${NC} node_modules/ not found - run: npm install"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check database
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}Database:${NC}"
|
||||||
|
|
||||||
|
if [ -f "db/services.db" ]; then
|
||||||
|
echo -e " ${GREEN}✓${NC} db/services.db exists"
|
||||||
|
|
||||||
|
# Check database tables
|
||||||
|
if command -v sqlite3 &> /dev/null; then
|
||||||
|
TABLES=$(sqlite3 db/services.db ".tables")
|
||||||
|
if echo "$TABLES" | grep -q "services"; then
|
||||||
|
echo -e " ${GREEN}✓${NC} services table"
|
||||||
|
else
|
||||||
|
echo -e " ${RED}✗${NC} services table (missing)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if echo "$TABLES" | grep -q "audit_logs"; then
|
||||||
|
echo -e " ${GREEN}✓${NC} audit_logs table"
|
||||||
|
else
|
||||||
|
echo -e " ${RED}✗${NC} audit_logs table (missing)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if echo "$TABLES" | grep -q "access_logs"; then
|
||||||
|
echo -e " ${GREEN}✓${NC} access_logs table"
|
||||||
|
else
|
||||||
|
echo -e " ${RED}✗${NC} access_logs table (missing)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e " ${YELLOW}⚠${NC} db/services.db not found - run: npm run init-db"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Configuration check
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}Configuration:${NC}"
|
||||||
|
|
||||||
|
if [ -f ".env" ]; then
|
||||||
|
echo -e " ${GREEN}✓${NC} .env file exists"
|
||||||
|
|
||||||
|
# Check key settings
|
||||||
|
if grep -q "PORT=" .env; then
|
||||||
|
PORT=$(grep "PORT=" .env | cut -d'=' -f2 | tr -d ' ')
|
||||||
|
echo -e " ${GREEN}✓${NC} PORT=$PORT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if grep -q "NODE_ENV=" .env; then
|
||||||
|
ENV=$(grep "NODE_ENV=" .env | cut -d'=' -f2 | tr -d ' ')
|
||||||
|
echo -e " ${GREEN}✓${NC} NODE_ENV=$ENV"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check OIDC status
|
||||||
|
if grep -q "^OIDC_ISSUER=" .env; then
|
||||||
|
echo -e " ${GREEN}✓${NC} OIDC configured (production mode)"
|
||||||
|
else
|
||||||
|
echo -e " ${YELLOW}⚠${NC} OIDC not configured (development mode)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e " ${RED}✗${NC} .env file not found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ready status
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}╔════════════════════════════════════════════════════╗${NC}"
|
||||||
|
|
||||||
|
if [ -f "db/services.db" ] && [ -d "node_modules" ] && [ -f ".env" ]; then
|
||||||
|
echo -e "${GREEN}✓ Installation complete and ready to run!${NC}"
|
||||||
|
echo ""
|
||||||
|
echo "Next steps:"
|
||||||
|
echo " 1. Start the server: ${BLUE}npm run dev${NC}"
|
||||||
|
echo " 2. Open in browser: ${BLUE}http://localhost:3000/admin${NC}"
|
||||||
|
echo " 3. Read the guide: ${BLUE}DEVELOPMENT-MODE.md${NC}"
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}╚════════════════════════════════════════════════════╝${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}⚠ Setup incomplete. Run the following:${NC}"
|
||||||
|
|
||||||
|
if [ ! -d "node_modules" ]; then
|
||||||
|
echo " ${BLUE}npm install${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "db/services.db" ]; then
|
||||||
|
echo " ${BLUE}npm run init-db${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}╚════════════════════════════════════════════════════╝${NC}"
|
||||||
|
fi
|
||||||
Loading…
x
Reference in New Issue
Block a user