This commit is contained in:
parent
c4ce80c5c2
commit
d6e9b1f489
@ -115,7 +115,7 @@ steps:
|
||||
gcloud secrets versions access latest --secret=WRAPPED_DEK_dev --project=$PROJECT > /tmp/dev_dek.enc; \
|
||||
if [ -s /tmp/dev_dek.enc ]; then \
|
||||
docker volume ls -q | grep -qx aptiva_dek_staging || docker volume create aptiva_dek_staging >/dev/null; \
|
||||
sudo docker run --rm -v aptiva_dek_staging:/v -v /tmp:/host busybox sh -c 'set -e; mkdir -p /v/staging; cp -f /host/dev_dek.enc /v/staging/dek.enc; chown 1000:1000 /v/staging/dek.enc; chmod 400 /v/staging/dek.enc; rm -f /v/staging/dek.fpr; echo -n "staging dek.enc bytes: "; wc -c </v/staging/dek.enc; ls -l /v/staging'
|
||||
sudo docker run --rm -v aptiva_dek_staging:/v -v /tmp:/host busybox sh -c 'set -e; mkdir -p /v/staging; cp -f /host/dev_dek.enc /v/staging/dek.enc; chown 1000:1000 /v/staging/dek.enc; chmod 400 /v/staging/dek.enc; rm -f /v/staging/dek.fpr; echo -n \"staging dek.enc bytes: \"; wc -c </v/staging/dek.enc; ls -l /v/staging'
|
||||
else \
|
||||
echo \"⚠️ WRAPPED_DEK_dev returned empty; skipping copy\"; \
|
||||
fi; \
|
||||
|
@ -4,15 +4,11 @@ import helmet from 'helmet';
|
||||
import dotenv from 'dotenv';
|
||||
import { fileURLToPath } from 'url';
|
||||
import path from 'path';
|
||||
import bodyParser from 'body-parser';
|
||||
import bcrypt from 'bcrypt';
|
||||
import jwt from 'jsonwebtoken'; // For token-based authentication
|
||||
import jwt from 'jsonwebtoken';
|
||||
import { initEncryption, encrypt, decrypt, verifyCanary, SENTINEL } from './shared/crypto/encryption.js';
|
||||
|
||||
import pool from './config/mysqlPool.js'; // adjust path if needed
|
||||
|
||||
import sqlite3 from 'sqlite3';
|
||||
|
||||
import pool from './config/mysqlPool.js';
|
||||
// import sqlite3 from 'sqlite3'; // (unused here – safe to remove)
|
||||
|
||||
const CANARY_SQL = `
|
||||
CREATE TABLE IF NOT EXISTS encryption_canary (
|
||||
@ -22,13 +18,11 @@ const CANARY_SQL = `
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
const rootPath = path.resolve(__dirname, '..'); // Up one level
|
||||
const rootPath = path.resolve(__dirname, '..');
|
||||
const env = process.env.NODE_ENV?.trim() || 'development';
|
||||
const envPath = path.resolve(rootPath, `.env.${env}`);
|
||||
dotenv.config({ path: envPath }); // Load .env file
|
||||
dotenv.config({ path: envPath, override: false });
|
||||
|
||||
// Grab secrets and config from ENV
|
||||
const {
|
||||
JWT_SECRET,
|
||||
CORS_ALLOWED_ORIGINS,
|
||||
@ -37,46 +31,48 @@ const {
|
||||
|
||||
if (!JWT_SECRET) {
|
||||
console.error('FATAL: JWT_SECRET missing – aborting startup');
|
||||
process.exit(1); // container exits, Docker marks it unhealthy
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (!CORS_ALLOWED_ORIGINS) {
|
||||
console.error('FATAL: CORS_ALLOWED_ORIGINS missing – aborting startup');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
/* ─── unwrap / verify DEK before we serve requests ────────────── */
|
||||
await initEncryption();
|
||||
|
||||
// Unwrap / verify DEK and seed canary before serving traffic
|
||||
try {
|
||||
/* quick connectivity smoke‑test (optional) */
|
||||
await pool.query('SELECT 1');
|
||||
await initEncryption(); // <-- wrap in try/catch
|
||||
|
||||
/* ① ensure table exists */
|
||||
await pool.query(CANARY_SQL);
|
||||
const db = pool.raw || pool; // <-- bypass DAO wrapper for canary ops
|
||||
|
||||
/* ② insert sentinel on first run */
|
||||
await pool.query(
|
||||
// quick connectivity check
|
||||
await db.query('SELECT 1');
|
||||
|
||||
// ① ensure table
|
||||
await db.query(CANARY_SQL);
|
||||
|
||||
// ② insert sentinel on first run (ignore if exists)
|
||||
await db.query(
|
||||
'INSERT IGNORE INTO encryption_canary (id, value) VALUES (1, ?)',
|
||||
[encrypt(SENTINEL)]
|
||||
);
|
||||
|
||||
/* ③ read back & verify */
|
||||
const [rows] = await pool.query(
|
||||
// ③ read back & verify
|
||||
const [rows] = await db.query(
|
||||
'SELECT value FROM encryption_canary WHERE id = 1 LIMIT 1'
|
||||
);
|
||||
|
||||
const plaintext = decrypt(rows[0]?.value || '');
|
||||
if (plaintext !== SENTINEL) {
|
||||
throw new Error('DEK mismatch with database sentinel');
|
||||
}
|
||||
|
||||
console.log('[ENCRYPT] DEK verified against canary – proceeding');
|
||||
console.log('[ENCRYPT] DEK verified against canary – proceeding');
|
||||
} catch (err) {
|
||||
console.error('FATAL:', err.message || err);
|
||||
process.exit(1); // container restarts → alert
|
||||
console.error('FATAL:', err?.message || err);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// …the rest of your server: app = express(), middlewares, routes, app.listen()
|
||||
|
||||
/* ────────────────────────────────────────────────────────────────
|
||||
Express app & middleware
|
||||
---------------------------------------------------------------- */
|
||||
|
Loading…
Reference in New Issue
Block a user