WeightTracker/data-api.js

138 lines
4.5 KiB
JavaScript

/**
* Simple data API for Weight Tracker
* This script handles data storage operations when deployed in Docker
* Includes authentication for password protection
*/
const fs = require('fs');
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const { initAuth, generateHash } = require('./auth-middleware');
// Create Express app
const app = express();
const port = process.env.PORT || 3000;
// Data file path in the Docker volume
const DATA_DIR = process.env.DATA_DIR || '/data';
const DATA_FILE = path.join(DATA_DIR, 'weight-tracker-data.json');
// Middleware
app.use(cors());
app.use(bodyParser.json({ limit: '5mb' }));
app.use(bodyParser.urlencoded({ extended: true })); // For parsing form data
app.use(express.static('public')); // Serve static files
// Copy login.html to the correct location for serving
const loginHtmlPath = path.join(__dirname, 'login.html');
if (fs.existsSync(loginHtmlPath)) {
// Ensure public directory exists
const publicDir = path.join(__dirname, 'public');
if (!fs.existsSync(publicDir)) {
fs.mkdirSync(publicDir, { recursive: true });
}
// Copy login.html to public directory
fs.copyFileSync(loginHtmlPath, path.join(publicDir, 'login.html'));
console.log('Login page copied to public directory');
}
// Initialize authentication middleware
initAuth(app);
// Ensure data directory exists
if (!fs.existsSync(DATA_DIR)) {
fs.mkdirSync(DATA_DIR, { recursive: true });
console.log(`Created data directory: ${DATA_DIR}`);
}
// Initialize data file if it doesn't exist
if (!fs.existsSync(DATA_FILE)) {
const defaultData = {
weights: [],
meals: [],
version: '1.0.0'
};
fs.writeFileSync(DATA_FILE, JSON.stringify(defaultData, null, 2));
console.log(`Created initial data file: ${DATA_FILE}`);
}
// GET endpoint to retrieve data
app.get('/data/weight-tracker-data.json', (req, res) => {
try {
console.log(`[DEBUG] GET request received for ${DATA_FILE}`);
console.log(`[DEBUG] File exists: ${fs.existsSync(DATA_FILE)}`);
if (fs.existsSync(DATA_FILE)) {
const data = fs.readFileSync(DATA_FILE, 'utf8');
console.log(`[DEBUG] Data read from file: ${data.substring(0, 100)}...`);
res.setHeader('Content-Type', 'application/json');
res.send(data);
console.log(`[DEBUG] Data sent to client`);
} else {
console.log(`[DEBUG] Data file not found at ${DATA_FILE}`);
res.status(404).send({ error: 'Data file not found' });
}
} catch (error) {
console.error('[DEBUG] Error reading data file:', error);
res.status(500).send({ error: 'Failed to read data file' });
}
});
// PUT endpoint to update data
app.put('/data/weight-tracker-data.json', (req, res) => {
try {
console.log(`[DEBUG] PUT request received for ${DATA_FILE}`);
const data = req.body;
// Log request body summary
console.log(`[DEBUG] Request body received:`, {
hasData: !!data,
hasWeights: data && !!data.weights,
weightCount: data && data.weights ? data.weights.length : 0,
hasMeals: data && !!data.meals,
mealCount: data && data.meals ? data.meals.length : 0
});
// Validate data structure
if (!data || !data.weights || !data.meals) {
console.log(`[DEBUG] Invalid data structure received`);
return res.status(400).send({ error: 'Invalid data structure' });
}
// Ensure data directory exists
if (!fs.existsSync(DATA_DIR)) {
console.log(`[DEBUG] Creating data directory: ${DATA_DIR}`);
fs.mkdirSync(DATA_DIR, { recursive: true });
}
// Write to file
console.log(`[DEBUG] Writing data to file: ${DATA_FILE}`);
fs.writeFileSync(DATA_FILE, JSON.stringify(data, null, 2));
// Verify file was written
const fileExists = fs.existsSync(DATA_FILE);
console.log(`[DEBUG] File exists after write: ${fileExists}`);
if (fileExists) {
const stats = fs.statSync(DATA_FILE);
console.log(`[DEBUG] File size after write: ${stats.size} bytes`);
}
res.send({ success: true, message: 'Data saved successfully' });
console.log(`[DEBUG] Data updated: ${new Date().toISOString()}`);
} catch (error) {
console.error('[DEBUG] Error writing data file:', error);
res.status(500).send({ error: 'Failed to write data file' });
}
});
// Start server
app.listen(port, () => {
console.log(`Data API server running on port ${port}`);
console.log(`Data directory: ${DATA_DIR}`);
console.log(`Data file: ${DATA_FILE}`);
});