bpb-website/server.js
chris 07b83c7ae8 Feature: Create Admin UI with Node.js Backend
This commit introduces a web-based admin UI to manage the store's status, backed by a simple Node.js/Express server for file writing.

Key features:
- **Admin UI (, ):** A form to update the scrolling message and closed status. It provides a user-friendly experience with loading states, in-page feedback, and change detection.
- **Node.js Backend ():** A simple Express server that serves the static site and provides a  endpoint. This endpoint receives data from the admin UI, authenticates it, and writes it to .
- **Enhanced Security:** The password is no longer hardcoded in the client-side JavaScript. Authentication is handled server-side, and the password is read from a  file for local development or an environment variable in production.
- **Project Setup (, ):** The project is now a formal Node.js project with dependencies (, , ) and a  file to exclude .
2025-11-12 14:19:34 -05:00

58 lines
2.0 KiB
JavaScript

require('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser');
const fs = require('fs');
const path = require('path');
const app = express();
const port = 3050;
// IMPORTANT: In a production environment, set the ADMIN_PASSWORD as an environment variable.
// For example: export ADMIN_PASSWORD="your_super_secret_password"
const ADMIN_PASSWORD = process.env.ADMIN_PASSWORD || "balloons";
if (ADMIN_PASSWORD === "balloons") {
console.warn(`
****************************************************************
** WARNING: Using default, insecure password. **
** Please set a secure ADMIN_PASSWORD environment variable **
** in your production environment. **
****************************************************************
`);
}
// Use body-parser middleware to parse JSON bodies
app.use(bodyParser.json());
// Serve static files from the root directory
app.use(express.static(path.join(__dirname)));
// API endpoint to update the JSON file
app.post('/api/update-status', (req, res) => {
const { password, data } = req.body;
if (password !== ADMIN_PASSWORD) {
return res.status(401).json({ success: false, message: 'Unauthorized: Incorrect password.' });
}
if (!data) {
return res.status(400).json({ success: false, message: 'Bad Request: No data provided.' });
}
const jsonString = JSON.stringify(data, null, 4);
const filePath = path.join(__dirname, 'update.json');
fs.writeFile(filePath, jsonString, (err) => {
if (err) {
console.error('Error writing to update.json:', err);
return res.status(500).json({ success: false, message: 'Internal Server Error: Could not write to file.' });
}
res.json({ success: true, message: 'Status updated successfully.' });
});
});
app.listen(port, () => {
console.log(`Server listening at http://localhost:${port}`);
console.log(`Admin panel available at http://localhost:${port}/admin.html`);
});