Replace Go mock server with Node.js implementation for better reliability

This commit is contained in:
Andreas Düren 2025-03-20 13:45:58 +01:00
parent f32919d436
commit e69166fc91

374
start.sh
View File

@ -264,125 +264,241 @@ if [ -f "${MUSEUM_DIR}/museum" ] && [ -x "${MUSEUM_DIR}/museum" ]; then
done done
else else
echo "==> ERROR: Museum server not found at ${MUSEUM_DIR}/museum" echo "==> ERROR: Museum server not found at ${MUSEUM_DIR}/museum"
echo "==> Starting a mock server for demonstration purposes" echo "==> Starting a mock server with Node.js for demonstration purposes"
# Create a temporary directory for a simple Go server # Create a temporary directory for a simple Node.js server
mkdir -p /tmp/mock-server mkdir -p /tmp/mock-server
cd /tmp/mock-server cd /tmp/mock-server
# Create a minimal Go server file that just logs requests and returns mock responses # Create a minimal Node.js server file
cat > server.go << 'ENDOFCODE' cat > server.js << 'ENDOFCODE'
package main const http = require('http');
const fs = require('fs');
const path = require('path');
import ( // Ensure log directory exists
"encoding/json" const logDir = '/app/data/logs';
"fmt" fs.mkdirSync(logDir, { recursive: true });
"log" const logFile = path.join(logDir, 'api_requests.log');
"math/rand"
"net/http"
"os"
"time"
)
func main() { // Open log file
// Create log file fs.writeFileSync(logFile, `API Server started at ${new Date().toISOString()}\n`, { flag: 'a' });
os.MkdirAll("/app/data/logs", 0755)
logFile, err := os.OpenFile("/app/data/logs/api_requests.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) // Log function
if err != nil { function log(message) {
fmt.Printf("Error creating log file: %v\n", err) const timestamp = new Date().toISOString();
} else { const logMessage = `${timestamp} - ${message}\n`;
defer logFile.Close() console.log(message);
log.SetOutput(logFile) fs.writeFileSync(logFile, logMessage, { flag: 'a' });
} }
// Log startup // Generate random 6-digit code
fmt.Println("Starting mock Ente API server on port 8080") function generateCode() {
log.Println("Starting mock Ente API server on port 8080") return Math.floor(100000 + Math.random() * 900000).toString();
}
// Initialize random // Create HTTP server
rand.Seed(time.Now().UnixNano()) const server = http.createServer((req, res) => {
const url = req.url;
const method = req.method;
log(`Received ${method} request for ${url}`);
// Set CORS headers
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
// Handle preflight requests
if (method === 'OPTIONS') {
res.statusCode = 200;
res.end();
return;
}
// Handle requests based on URL path
if (url === '/health') {
// Health check endpoint // Health check endpoint
http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) { res.setHeader('Content-Type', 'application/json');
w.Header().Set("Content-Type", "application/json") res.end(JSON.stringify({
fmt.Fprintf(w, `{"status":"ok","time":"%s"}`, time.Now().Format(time.RFC3339)) status: "ok",
}) time: new Date().toISOString()
}));
}
else if (url === '/users/ott') {
// OTT verification code endpoint
let body = '';
// Login/token endpoints req.on('data', chunk => {
http.HandleFunc("/users/ott", func(w http.ResponseWriter, r *http.Request) { body += chunk.toString();
log.Printf("OTT Request received: %s %s", r.Method, r.URL.Path) });
req.on('end', () => {
let email = 'user@example.com';
// Try to parse email from request if possible
try {
const data = JSON.parse(body);
if (data.email) {
email = data.email;
}
} catch (e) {
try {
// Try to parse as URL-encoded form data
const params = new URLSearchParams(body);
if (params.has('email')) {
email = params.get('email');
}
} catch (e2) {
// Ignore parsing errors
}
}
// Generate verification code // Generate verification code
code := fmt.Sprintf("%06d", 100000+rand.Intn(900000)) const code = generateCode();
// Log the verification code prominently // Log the code prominently
message := fmt.Sprintf("⚠️ VERIFICATION CODE: %s", code) const codeMessage = `⚠️ VERIFICATION CODE FOR ${email}: ${code}`;
fmt.Println(message) log(codeMessage);
log.Println(message) console.log('\n' + codeMessage + '\n');
w.Header().Set("Content-Type", "application/json") // Send response
response := map[string]interface{}{ res.setHeader('Content-Type', 'application/json');
"status": "ok", res.end(JSON.stringify({
"id": 12345, status: "ok",
"token": "mock-token-12345", id: 12345,
"ott": code, token: "mock-token-12345",
"exp": time.Now().Add(time.Hour).Unix(), ott: code,
"email": "user@example.com", exp: Math.floor(Date.now()/1000) + 3600,
"createdAt": time.Now().Format(time.RFC3339), email: email,
"updatedAt": time.Now().Format(time.RFC3339), createdAt: new Date().toISOString(),
"key": map[string]interface{}{ updatedAt: new Date().toISOString(),
"pubKey": "mockPubKey123456", key: {
"encPubKey": "mockEncPubKey123456", pubKey: "mockPubKey123456",
"kty": "mockKty", encPubKey: "mockEncPubKey123456",
"kid": "mockKid", kty: "mockKty",
"alg": "mockAlg", kid: "mockKid",
"verifyKey": "mockVerifyKey123456", alg: "mockAlg",
}, verifyKey: "mockVerifyKey123456"
} }
json.NewEncoder(w).Encode(response) }));
}) });
// User verification endpoint
http.HandleFunc("/users/verification", func(w http.ResponseWriter, r *http.Request) {
log.Printf("Verification request received: %s %s", r.Method, r.URL.Path)
// Accept any 6-digit code
fmt.Println("⚠️ VERIFICATION SUCCESSFUL - accepting any code in mock server")
log.Println("⚠️ VERIFICATION SUCCESSFUL - accepting any code in mock server")
w.Header().Set("Content-Type", "application/json")
response := map[string]interface{}{
"status": "ok",
"id": 12345,
"token": "mock-token-12345",
"email": "user@example.com",
"key": map[string]interface{}{
"pubKey": "mockPubKey123456",
"encPubKey": "mockEncPubKey123456",
"kty": "mockKty",
"kid": "mockKid",
"alg": "mockAlg",
"verifyKey": "mockVerifyKey123456",
},
"isEmailVerified": true,
} }
json.NewEncoder(w).Encode(response) else if (url === '/users/verification') {
}) // Verification endpoint
let body = '';
// Default handler req.on('data', chunk => {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { body += chunk.toString();
log.Printf("Request: %s %s", r.Method, r.URL.Path) });
w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, `{"status":"ok","path":"%s"}`, r.URL.Path) req.on('end', () => {
}) log("Verification request received with body: " + body);
log("⚠️ VERIFICATION SUCCESSFUL - accepting any code in mock server");
// Send success response
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({
status: "ok",
id: 12345,
token: "mock-token-12345",
email: "user@example.com",
key: {
pubKey: "mockPubKey123456",
encPubKey: "mockEncPubKey123456",
kty: "mockKty",
kid: "mockKid",
alg: "mockAlg",
verifyKey: "mockVerifyKey123456"
},
isEmailVerified: true
}));
});
}
else {
// Default handler for other paths
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({
status: "ok",
path: url
}));
}
});
// Start server // Start server
fmt.Println("Server listening on 0.0.0.0:8080") const PORT = 8080;
if err := http.ListenAndServe("0.0.0.0:8080", nil); err != nil { server.listen(PORT, '0.0.0.0', () => {
fmt.Printf("Server error: %v\n", err) log(`Mock API server running at http://0.0.0.0:${PORT}/`);
log.Fatalf("Server error: %v", err) });
ENDOFCODE
# Create a similar server for public albums
mkdir -p /tmp/mock-public-server
cd /tmp/mock-public-server
cat > server.js << 'ENDOFCODE'
const http = require('http');
const fs = require('fs');
const path = require('path');
// Ensure log directory exists
const logDir = '/app/data/logs';
fs.mkdirSync(logDir, { recursive: true });
const logFile = path.join(logDir, 'public_api_requests.log');
// Open log file
fs.writeFileSync(logFile, `Public Albums API Server started at ${new Date().toISOString()}\n`, { flag: 'a' });
// Log function
function log(message) {
const timestamp = new Date().toISOString();
const logMessage = `${timestamp} - ${message}\n`;
console.log(message);
fs.writeFileSync(logFile, logMessage, { flag: 'a' });
} }
// Create HTTP server
const server = http.createServer((req, res) => {
const url = req.url;
const method = req.method;
log(`Received ${method} request for ${url}`);
// Set CORS headers
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
// Handle preflight requests
if (method === 'OPTIONS') {
res.statusCode = 200;
res.end();
return;
} }
// Health check endpoint
if (url === '/health') {
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({
status: "ok",
time: new Date().toISOString()
}));
}
else {
// Default handler for other paths
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({
status: "ok",
path: url
}));
}
});
// Start server
const PORT = 8081;
server.listen(PORT, '0.0.0.0', () => {
log(`Mock Public Albums API server running at http://0.0.0.0:${PORT}/`);
});
ENDOFCODE ENDOFCODE
# Set SERVER_PID to 0 for safety # Set SERVER_PID to 0 for safety
@ -394,8 +510,9 @@ ENDOFCODE
chmod 666 "${LOGS_DIR}/api_requests.log" chmod 666 "${LOGS_DIR}/api_requests.log"
# Run the mock server # Run the mock server
echo "==> Running mock API server" echo "==> Running mock API server with Node.js"
go run server.go > "${LOGS_DIR}/mock_server.log" 2>&1 & cd /tmp/mock-server
node server.js > "${LOGS_DIR}/mock_server.log" 2>&1 &
SERVER_PID=$! SERVER_PID=$!
echo "==> Mock API server started with PID $SERVER_PID" echo "==> Mock API server started with PID $SERVER_PID"
@ -404,65 +521,12 @@ ENDOFCODE
echo "==> Testing mock API connectivity" echo "==> Testing mock API connectivity"
curl -s --max-time 2 --fail http://0.0.0.0:${API_PORT}/health || echo "==> Warning: Mock API server not responding!" curl -s --max-time 2 --fail http://0.0.0.0:${API_PORT}/health || echo "==> Warning: Mock API server not responding!"
# Create a similar mock server for public albums
mkdir -p /tmp/mock-public-server
cd /tmp/mock-public-server
cat > server.go << 'ENDOFCODE'
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"time"
)
func main() {
port := "8081"
// Create log directory and file
os.MkdirAll("/app/data/logs", 0755)
logFile, err := os.OpenFile("/app/data/logs/public_api_requests.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
fmt.Printf("Error creating log file: %v\n", err)
} else {
defer logFile.Close()
log.SetOutput(logFile)
}
// Log startup
fmt.Println("Starting mock Public Albums server on port", port)
log.Println("Starting mock Public Albums server on port", port)
// Health check endpoint
http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, `{"status":"ok","time":"%s"}`, time.Now().Format(time.RFC3339))
})
// Default handler
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
log.Printf("Public Albums Request: %s %s", r.Method, r.URL.Path)
w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, `{"status":"ok","path":"%s"}`, r.URL.Path)
})
// Start server
fmt.Println("Public Albums server listening on 0.0.0.0:" + port)
if err := http.ListenAndServe("0.0.0.0:"+port, nil); err != nil {
fmt.Printf("Public Albums server error: %v\n", err)
log.Fatalf("Public Albums server error: %v", err)
}
}
ENDOFCODE
# Run the public albums mock server # Run the public albums mock server
go run server.go > "${LOGS_DIR}/public_mock_server.log" 2>&1 & echo "==> Running Public Albums mock server with Node.js"
cd /tmp/mock-public-server
node server.js > "${LOGS_DIR}/public_mock_server.log" 2>&1 &
PUBLIC_SERVER_PID=$! PUBLIC_SERVER_PID=$!
echo "==> Started Public Albums mock server with PID $PUBLIC_SERVER_PID" echo "==> Public Albums mock server started with PID $PUBLIC_SERVER_PID"
# Wait for it to start # Wait for it to start
sleep 3 sleep 3