114 lines
3.6 KiB
JavaScript
114 lines
3.6 KiB
JavaScript
const path = require('path');
|
|
const dotenv = require('dotenv');
|
|
|
|
dotenv.config({ path: path.resolve(process.cwd(), '.env') });
|
|
|
|
const requireEnv = (name) => {
|
|
const value = process.env[name];
|
|
if (!value) {
|
|
throw new Error(`Missing required environment variable: ${name}`);
|
|
}
|
|
return value;
|
|
};
|
|
|
|
const parseDurationMs = (value, fallbackMs) => {
|
|
if (!value) return fallbackMs;
|
|
const match = String(value).trim().match(/^(\d+)(ms|s|m|h|d)?$/i);
|
|
if (!match) return fallbackMs;
|
|
|
|
const amount = Number(match[1]);
|
|
const unit = (match[2] || 'ms').toLowerCase();
|
|
const multipliers = {
|
|
ms: 1,
|
|
s: 1000,
|
|
m: 60 * 1000,
|
|
h: 60 * 60 * 1000,
|
|
d: 24 * 60 * 60 * 1000,
|
|
};
|
|
|
|
return amount * multipliers[unit];
|
|
};
|
|
|
|
if (process.env.NODE_ENV === 'production') {
|
|
[
|
|
'JWT_SECRET',
|
|
'CORS_ORIGIN',
|
|
'FRONTEND_URL',
|
|
'DB_HOST',
|
|
'DB_NAME',
|
|
'DB_USER',
|
|
'DB_PASSWORD',
|
|
'STORAGE_PATH',
|
|
'MAIL_HOST',
|
|
'MAIL_PORT',
|
|
'MAIL_USER',
|
|
'MAIL_PASS',
|
|
'MAIL_FROM',
|
|
].forEach(requireEnv);
|
|
|
|
if (process.env.JWT_SECRET === 'change_me') {
|
|
throw new Error('JWT_SECRET cannot use the default insecure value in production.');
|
|
}
|
|
|
|
if ((process.env.FRONTEND_URL || '').includes('localhost')) {
|
|
throw new Error('FRONTEND_URL must not point to localhost in production.');
|
|
}
|
|
}
|
|
|
|
const env = {
|
|
port: Number(process.env.PORT) || 4000,
|
|
nodeEnv: process.env.NODE_ENV || 'development',
|
|
corsOrigin: process.env.CORS_ORIGIN || 'http://localhost:5173',
|
|
|
|
db: {
|
|
host: process.env.DB_HOST || '127.0.0.1',
|
|
port: Number(process.env.DB_PORT) || 3306,
|
|
name: process.env.DB_NAME || 'signdb',
|
|
user: process.env.DB_USER || 'SignLinked',
|
|
password: process.env.DB_PASSWORD || '',
|
|
},
|
|
|
|
jwt: {
|
|
secret: process.env.JWT_SECRET || 'change_me',
|
|
accessExpires: process.env.JWT_ACCESS_EXPIRES || '15m',
|
|
refreshExpires: process.env.JWT_REFRESH_EXPIRES || '15m',
|
|
refreshExpiresMs: parseDurationMs(process.env.JWT_REFRESH_EXPIRES || '15m', 15 * 60 * 1000),
|
|
biometricExpires: process.env.JWT_BIOMETRIC_EXPIRES || '180d',
|
|
biometricExpiresMs: parseDurationMs(process.env.JWT_BIOMETRIC_EXPIRES || '180d', 180 * 24 * 60 * 60 * 1000),
|
|
},
|
|
|
|
storagePath: process.env.STORAGE_PATH || '/tmp/linkedsign_storage',
|
|
|
|
p12: {
|
|
defaultPath: process.env.P12_DEFAULT_PATH || null,
|
|
defaultPassword: process.env.P12_DEFAULT_PASSWORD || '',
|
|
},
|
|
|
|
mail: {
|
|
host: process.env.MAIL_HOST || 'smtp.gmail.com',
|
|
port: Number(process.env.MAIL_PORT) || 587,
|
|
secure: process.env.MAIL_SECURE === 'true',
|
|
rejectUnauthorized: process.env.MAIL_TLS_REJECT_UNAUTHORIZED !== 'false',
|
|
user: process.env.MAIL_USER || '',
|
|
pass: process.env.MAIL_PASS || '',
|
|
from: process.env.MAIL_FROM || 'noreply@linkedsign.local',
|
|
},
|
|
|
|
legal: {
|
|
controllerName: process.env.LEGAL_CONTROLLER_NAME || 'LinkedCorp',
|
|
platformName: process.env.LEGAL_PLATFORM_NAME || 'LinkedSign',
|
|
contactEmail: process.env.LEGAL_CONTACT_EMAIL || process.env.MAIL_FROM || 'sign@linkedcorp.net',
|
|
contactPhone: process.env.LEGAL_CONTACT_PHONE || 'No informado en este entorno',
|
|
contactAddress: process.env.LEGAL_CONTACT_ADDRESS || 'No informado en este entorno',
|
|
website: process.env.LEGAL_WEBSITE || process.env.FRONTEND_URL || 'http://localhost:5173',
|
|
rightsEmail: process.env.LEGAL_RIGHTS_EMAIL || process.env.MAIL_FROM || 'sign@linkedcorp.net',
|
|
},
|
|
|
|
frontendUrl: process.env.FRONTEND_URL || 'http://localhost:5173',
|
|
refreshCookieName: process.env.REFRESH_COOKIE_NAME || 'linkedsign_refresh',
|
|
androidApkPath:
|
|
process.env.ANDROID_APK_PATH || path.resolve(process.cwd(), '..', 'android', 'apk', 'LinkedSign-debug.apk'),
|
|
};
|
|
|
|
module.exports = env;
|