feat(prod): production deployment fixes - env loader, mongoose module, CSS static files, security hardening, PDF export, new UI components
This commit is contained in:
1 parent
a403f752f3
commit
46f33eb088
69 files changed
+7367
-744
No files matched your search
@@ -5,7 +5,8 @@
|
||||
|
||||
const mongoose = require('mongoose');
|
||||
const path = require('path');
|
||||
require('dotenv').config({ path: path.join(__dirname, '../../.env.local') });
|
||||
const envFile = process.env.NODE_ENV === 'production' ? '.env.production' : '.env.local';
|
||||
require('dotenv').config({ path: path.join(__dirname, '../../', envFile) });
|
||||
|
||||
const MONGODB_URI = process.env.MONGODB_URI || 'mongodb://127.0.0.1:27017/backone_dpi';
|
||||
|
||||
|
||||
@@ -50,7 +50,24 @@ const storage = multer.diskStorage({
|
||||
cb(null, `profile-${uniqueSuffix}${path.extname(file.originalname)}`);
|
||||
}
|
||||
});
|
||||
const upload = multer({ storage });
|
||||
|
||||
// File filter — only allow image formats for profile picture uploads
|
||||
function imageFileFilter(req, file, cb) {
|
||||
const allowedMimeTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp'];
|
||||
if (allowedMimeTypes.includes(file.mimetype)) {
|
||||
cb(null, true);
|
||||
} else {
|
||||
cb(new Error('Invalid file type. Only JPEG, PNG, and WebP images are allowed.'), false);
|
||||
}
|
||||
}
|
||||
|
||||
const upload = multer({
|
||||
storage,
|
||||
fileFilter: imageFileFilter,
|
||||
limits: {
|
||||
fileSize: 5 * 1024 * 1024, // 5 MB maximum per profile picture
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
JWT_SECRET,
|
||||
|
||||
+17
-6
@@ -1,5 +1,10 @@
|
||||
// backend/server.js
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Polyfill global crypto for Node 18 compatibility (required by mongodb driver)
|
||||
if (typeof globalThis.crypto === 'undefined') {
|
||||
globalThis.crypto = require('crypto');
|
||||
}
|
||||
|
||||
// BackOne Backend API Server
|
||||
//
|
||||
// Tanggung jawab backend ini adalah READ-ONLY dari MongoDB.
|
||||
@@ -15,7 +20,8 @@
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
const path = require('path');
|
||||
require('dotenv').config({ path: path.join(__dirname, '..', '.env.local') });
|
||||
const envFile = process.env.NODE_ENV === 'production' ? '.env.production' : '.env.local';
|
||||
require('dotenv').config({ path: path.join(__dirname, '..', envFile) });
|
||||
|
||||
const express = require('express');
|
||||
const cors = require('cors');
|
||||
@@ -45,7 +51,8 @@ app.use(cors({
|
||||
},
|
||||
credentials: true
|
||||
}));
|
||||
app.use(express.json());
|
||||
app.use(express.json({ limit: '10mb' }));
|
||||
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
|
||||
app.use(cookieParser());
|
||||
|
||||
// ─── Public Routes ────────────────────────────────────────────────────────────
|
||||
@@ -116,8 +123,12 @@ app.get('/api/health', (req, res) => {
|
||||
});
|
||||
|
||||
// ─── Start Server ─────────────────────────────────────────────────────────────
|
||||
app.listen(PORT, () => {
|
||||
console.log(`\n🚀 BackOne API Server berjalan di http://localhost:${PORT}`);
|
||||
console.log(`🔌 API Health : http://localhost:${PORT}/api/health`);
|
||||
console.log(`📡 Mode : READ-ONLY dari MongoDB (data dikirim oleh Proxy Server)\n`);
|
||||
// Bind to 127.0.0.1 in production to prevent direct external access to port 3001.
|
||||
// All external traffic must go through the reverse proxy (Apache/Nginx) at port 80/443.
|
||||
const BIND_HOST = process.env.NODE_ENV === 'production' ? '127.0.0.1' : '0.0.0.0';
|
||||
app.listen(PORT, BIND_HOST, () => {
|
||||
console.log(`\n🚀 BackOne API Server berjalan di http://${BIND_HOST}:${PORT}`);
|
||||
console.log(`🔌 API Health : http://${BIND_HOST}:${PORT}/api/health`);
|
||||
console.log(`📡 Mode : READ-ONLY dari MongoDB (data dikirim oleh Proxy Server)`);
|
||||
console.log(`🔒 Security : Bound to ${BIND_HOST} (internal only in production)\n`);
|
||||
});
|
||||
Reference in new issue
Block a user