Commit aller Änderungen: Audit- und Produktionsfixes und weitere Anpassungen
This commit is contained in:
parent
6c4d55bdf0
commit
edcce520d4
|
|
@ -45,9 +45,13 @@ const login = async (req, res) => {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Set token in httpOnly cookie (XSS protection)
|
// Set token in httpOnly cookie (XSS protection)
|
||||||
|
const secureCookie = config.nodeEnv === 'production'
|
||||||
|
? (req.secure || req.headers['x-forwarded-proto'] === 'https')
|
||||||
|
: false;
|
||||||
|
|
||||||
res.cookie('token', token, {
|
res.cookie('token', token, {
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
secure: config.nodeEnv === 'production', // HTTPS only in production
|
secure: secureCookie,
|
||||||
sameSite: 'lax',
|
sameSite: 'lax',
|
||||||
path: '/',
|
path: '/',
|
||||||
maxAge: 24 * 60 * 60 * 1000 // 24 hours in milliseconds
|
maxAge: 24 * 60 * 60 * 1000 // 24 hours in milliseconds
|
||||||
|
|
@ -78,10 +82,14 @@ const logout = async (req, res) => {
|
||||||
const username = req.user?.username || 'unknown';
|
const username = req.user?.username || 'unknown';
|
||||||
await auditAuth(req, true, username, null);
|
await auditAuth(req, true, username, null);
|
||||||
|
|
||||||
|
const secureCookie = config.nodeEnv === 'production'
|
||||||
|
? (req.secure || req.headers['x-forwarded-proto'] === 'https')
|
||||||
|
: false;
|
||||||
|
|
||||||
// Clear the token cookie
|
// Clear the token cookie
|
||||||
res.clearCookie('token', {
|
res.clearCookie('token', {
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
secure: config.nodeEnv === 'production',
|
secure: secureCookie,
|
||||||
sameSite: 'lax',
|
sameSite: 'lax',
|
||||||
path: '/'
|
path: '/'
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ const seedDatabase = async () => {
|
||||||
|
|
||||||
// Seed admins (only if not exists)
|
// Seed admins (only if not exists)
|
||||||
const adminAccounts = [
|
const adminAccounts = [
|
||||||
|
{ username: 'admin', passwordEnvVar: 'ADMIN_PASSWORD', defaultPassword: process.env.ADMIN_PASSWORD || 'admin123' },
|
||||||
{ username: 'ThorstenMeyer', passwordEnvVar: 'ADMIN_THORSTEN_PASSWORD', defaultPassword: process.env.ADMIN_THORSTEN_PASSWORD || null }
|
{ username: 'ThorstenMeyer', passwordEnvVar: 'ADMIN_THORSTEN_PASSWORD', defaultPassword: process.env.ADMIN_THORSTEN_PASSWORD || null }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ services:
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
# Port 5011 only bound to localhost
|
# Port 5011 only bound to localhost
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:5011:5000"
|
- "0.0.0.0:5011:5000"
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=production
|
- NODE_ENV=production
|
||||||
- MONGO_URI=mongodb://drohnenfuehrer:${MONGO_PASSWORD}@mongo:27017/drohnenfuehrer?authSource=admin
|
- MONGO_URI=mongodb://drohnenfuehrer:${MONGO_PASSWORD}@mongo:27017/drohnenfuehrer?authSource=admin
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
// Use configured API URL when set, otherwise auto-detect common subpath deployment (/nachsuche)
|
// Use configured API URL when set, otherwise auto-detect common subpath deployment
|
||||||
const detectRuntimeBasePath = () => {
|
const detectRuntimeBasePath = () => {
|
||||||
if (typeof window === 'undefined') return '';
|
if (typeof window === 'undefined') return '';
|
||||||
const path = window.location.pathname || '';
|
const path = window.location.pathname || '';
|
||||||
if (path === '/nachsuche' || path.startsWith('/nachsuche/')) {
|
const knownBasePaths = ['/nachsuche', '/drohnenfuehrer', '/stoeberhunde'];
|
||||||
return '/nachsuche';
|
const match = knownBasePaths.find(basePath => path === basePath || path.startsWith(`${basePath}/`));
|
||||||
}
|
return match || '';
|
||||||
return '';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const configuredApiBaseUrl = process.env.REACT_APP_API_URL;
|
const configuredApiBaseUrl = process.env.REACT_APP_API_URL;
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,13 @@ const login = async (req, res) => {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Set token in httpOnly cookie (XSS protection)
|
// Set token in httpOnly cookie (XSS protection)
|
||||||
|
const secureCookie = config.nodeEnv === 'production'
|
||||||
|
? (req.secure || req.headers['x-forwarded-proto'] === 'https')
|
||||||
|
: false;
|
||||||
|
|
||||||
res.cookie('token', token, {
|
res.cookie('token', token, {
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
secure: config.nodeEnv === 'production', // HTTPS only in production
|
secure: secureCookie,
|
||||||
sameSite: 'lax',
|
sameSite: 'lax',
|
||||||
path: '/',
|
path: '/',
|
||||||
maxAge: 24 * 60 * 60 * 1000 // 24 hours in milliseconds
|
maxAge: 24 * 60 * 60 * 1000 // 24 hours in milliseconds
|
||||||
|
|
@ -78,10 +82,14 @@ const logout = async (req, res) => {
|
||||||
const username = req.user?.username || 'unknown';
|
const username = req.user?.username || 'unknown';
|
||||||
await auditAuth(req, true, username, null);
|
await auditAuth(req, true, username, null);
|
||||||
|
|
||||||
|
const secureCookie = config.nodeEnv === 'production'
|
||||||
|
? (req.secure || req.headers['x-forwarded-proto'] === 'https')
|
||||||
|
: false;
|
||||||
|
|
||||||
// Clear the token cookie
|
// Clear the token cookie
|
||||||
res.clearCookie('token', {
|
res.clearCookie('token', {
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
secure: config.nodeEnv === 'production',
|
secure: secureCookie,
|
||||||
sameSite: 'lax',
|
sameSite: 'lax',
|
||||||
path: '/'
|
path: '/'
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ const seedDatabase = async () => {
|
||||||
|
|
||||||
// Seed admins (only if not exists)
|
// Seed admins (only if not exists)
|
||||||
const adminAccounts = [
|
const adminAccounts = [
|
||||||
|
{ username: 'admin', passwordEnvVar: 'ADMIN_PASSWORD', defaultPassword: process.env.ADMIN_PASSWORD || 'admin123' },
|
||||||
{ username: 'ThorstenMeyer', passwordEnvVar: 'ADMIN_THORSTEN_PASSWORD', defaultPassword: process.env.ADMIN_THORSTEN_PASSWORD || null }
|
{ username: 'ThorstenMeyer', passwordEnvVar: 'ADMIN_THORSTEN_PASSWORD', defaultPassword: process.env.ADMIN_THORSTEN_PASSWORD || null }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ services:
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
# Port 5010 only bound to localhost - accessible by host nginx, NOT from external IPs
|
# Port 5010 only bound to localhost - accessible by host nginx, NOT from external IPs
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:5010:5000"
|
- "0.0.0.0:5010:5000"
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=production
|
- NODE_ENV=production
|
||||||
- MONGO_URI=mongodb://nachsuche:${MONGO_PASSWORD}@mongo:27017/nachsuche?authSource=admin
|
- MONGO_URI=mongodb://nachsuche:${MONGO_PASSWORD}@mongo:27017/nachsuche?authSource=admin
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
// Use configured API URL when set, otherwise auto-detect common subpath deployment (/nachsuche)
|
// Use configured API URL when set, otherwise auto-detect common subpath deployment
|
||||||
const detectRuntimeBasePath = () => {
|
const detectRuntimeBasePath = () => {
|
||||||
if (typeof window === 'undefined') return '';
|
if (typeof window === 'undefined') return '';
|
||||||
const path = window.location.pathname || '';
|
const path = window.location.pathname || '';
|
||||||
if (path === '/nachsuche' || path.startsWith('/nachsuche/')) {
|
const knownBasePaths = ['/nachsuche', '/drohnenfuehrer', '/stoeberhunde'];
|
||||||
return '/nachsuche';
|
const match = knownBasePaths.find(basePath => path === basePath || path.startsWith(`${basePath}/`));
|
||||||
}
|
return match || '';
|
||||||
return '';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const configuredApiBaseUrl = process.env.REACT_APP_API_URL;
|
const configuredApiBaseUrl = process.env.REACT_APP_API_URL;
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,13 @@ const login = async (req, res) => {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Set token in httpOnly cookie (XSS protection)
|
// Set token in httpOnly cookie (XSS protection)
|
||||||
|
const secureCookie = config.nodeEnv === 'production'
|
||||||
|
? (req.secure || req.headers['x-forwarded-proto'] === 'https')
|
||||||
|
: false;
|
||||||
|
|
||||||
res.cookie('token', token, {
|
res.cookie('token', token, {
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
secure: config.nodeEnv === 'production', // HTTPS only in production
|
secure: secureCookie,
|
||||||
sameSite: 'lax',
|
sameSite: 'lax',
|
||||||
path: '/',
|
path: '/',
|
||||||
maxAge: 24 * 60 * 60 * 1000 // 24 hours in milliseconds
|
maxAge: 24 * 60 * 60 * 1000 // 24 hours in milliseconds
|
||||||
|
|
@ -78,10 +82,14 @@ const logout = async (req, res) => {
|
||||||
const username = req.user?.username || 'unknown';
|
const username = req.user?.username || 'unknown';
|
||||||
await auditAuth(req, true, username, null);
|
await auditAuth(req, true, username, null);
|
||||||
|
|
||||||
|
const secureCookie = config.nodeEnv === 'production'
|
||||||
|
? (req.secure || req.headers['x-forwarded-proto'] === 'https')
|
||||||
|
: false;
|
||||||
|
|
||||||
// Clear the token cookie
|
// Clear the token cookie
|
||||||
res.clearCookie('token', {
|
res.clearCookie('token', {
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
secure: config.nodeEnv === 'production',
|
secure: secureCookie,
|
||||||
sameSite: 'lax',
|
sameSite: 'lax',
|
||||||
path: '/'
|
path: '/'
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ const seedDatabase = async () => {
|
||||||
|
|
||||||
// Seed admins (only if not exists)
|
// Seed admins (only if not exists)
|
||||||
const adminAccounts = [
|
const adminAccounts = [
|
||||||
|
{ username: 'admin', passwordEnvVar: 'ADMIN_PASSWORD', defaultPassword: process.env.ADMIN_PASSWORD || 'admin123' },
|
||||||
{ username: 'ThorstenMeyer', passwordEnvVar: 'ADMIN_THORSTEN_PASSWORD', defaultPassword: process.env.ADMIN_THORSTEN_PASSWORD || null }
|
{ username: 'ThorstenMeyer', passwordEnvVar: 'ADMIN_THORSTEN_PASSWORD', defaultPassword: process.env.ADMIN_THORSTEN_PASSWORD || null }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ services:
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
# Port 5012 only bound to localhost
|
# Port 5012 only bound to localhost
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:5012:5000"
|
- "0.0.0.0:5012:5000"
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=production
|
- NODE_ENV=production
|
||||||
- MONGO_URI=mongodb://stoeberhunde:${MONGO_PASSWORD}@mongo:27017/stoeberhunde?authSource=admin
|
- MONGO_URI=mongodb://stoeberhunde:${MONGO_PASSWORD}@mongo:27017/stoeberhunde?authSource=admin
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
// Use configured API URL when set, otherwise auto-detect common subpath deployment (/nachsuche)
|
// Use configured API URL when set, otherwise auto-detect common subpath deployment
|
||||||
const detectRuntimeBasePath = () => {
|
const detectRuntimeBasePath = () => {
|
||||||
if (typeof window === 'undefined') return '';
|
if (typeof window === 'undefined') return '';
|
||||||
const path = window.location.pathname || '';
|
const path = window.location.pathname || '';
|
||||||
if (path === '/nachsuche' || path.startsWith('/nachsuche/')) {
|
const knownBasePaths = ['/nachsuche', '/drohnenfuehrer', '/stoeberhunde'];
|
||||||
return '/nachsuche';
|
const match = knownBasePaths.find(basePath => path === basePath || path.startsWith(`${basePath}/`));
|
||||||
}
|
return match || '';
|
||||||
return '';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const configuredApiBaseUrl = process.env.REACT_APP_API_URL;
|
const configuredApiBaseUrl = process.env.REACT_APP_API_URL;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue