enable ssl for pg connection
This commit is contained in:
@@ -15,320 +15,310 @@ app.use(express.json({ limit: '10mb' }));
|
||||
|
||||
// PostgreSQL connection pool
|
||||
function handleHeaders(headers) {
|
||||
const alias = (headers['db-alias'] || 'default').toUpperCase().replace(/-/g, '_');
|
||||
|
||||
const alias = (headers['db-alias'] || 'default').toUpperCase().replace(/-/g, '_');
|
||||
let pool = {
|
||||
host: process.env[`DB_${alias}_HOST`],
|
||||
port: process.env[`DB_${alias}_PORT`],
|
||||
database: process.env[`DB_${alias}_DATABASE`],
|
||||
user: process.env[`DB_${alias}_USER`],
|
||||
password: process.env[`DB_${alias}_PASSWORD`],
|
||||
max: 20,
|
||||
idleTimeoutMillis: 30000,
|
||||
connectionTimeoutMillis: 2000,
|
||||
};
|
||||
|
||||
let pool={
|
||||
host: process.env[`DB_${alias}_HOST`],
|
||||
port: process.env[`DB_${alias}_PORT`],
|
||||
database: process.env[`DB_${alias}_DATABASE`],
|
||||
user: process.env[`DB_${alias}_USER`],
|
||||
password: process.env[`DB_${alias}_PASSWORD`],
|
||||
max: 20,
|
||||
idleTimeoutMillis: 30000,
|
||||
connectionTimeoutMillis: 2000,
|
||||
};
|
||||
const allUndefined =
|
||||
pool.host === undefined && pool.port === undefined && pool.database === undefined && pool.user === undefined && pool.password === undefined;
|
||||
const someUndefined = pool.host === '' || pool.port === '' || pool.database === '' || pool.user === '' || pool.password === '';
|
||||
const someDefined = pool.host != undefined || pool.port != undefined || pool.database != undefined || pool.user != undefined || pool.password != undefined;
|
||||
|
||||
const allUndefined = pool.host=== undefined && pool.port=== undefined && pool.database=== undefined && pool.user=== undefined && pool.password=== undefined;
|
||||
const someUndefined = pool.host=== '' || pool.port=== '' || pool.database=== '' || pool.user=== '' || pool.password=== '';
|
||||
const someDefined = pool.host != undefined || pool.port != undefined || pool.database != undefined || pool.user != undefined || pool.password != undefined;
|
||||
|
||||
if (allUndefined) {
|
||||
throw new Error('Invalid db alias');
|
||||
if (allUndefined) {
|
||||
throw new Error('Invalid db alias');
|
||||
} else if (someUndefined && someDefined) {
|
||||
console.log(pool);
|
||||
if (pool.host === '') {
|
||||
throw new Error('Host is not configured for the specified db alias');
|
||||
}
|
||||
else if(someUndefined && someDefined) {
|
||||
console.log(pool);
|
||||
if(pool.host === '') {
|
||||
throw new Error('Host is not configured for the specified db alias');
|
||||
}
|
||||
if(pool.port === '') {
|
||||
throw new Error('Port is not configured for the specified db alias');
|
||||
}
|
||||
if(pool.database === '') {
|
||||
throw new Error('Database is not configured for the specified db alias');
|
||||
}
|
||||
if(pool.user === '') {
|
||||
throw new Error('User is not configured for the specified db alias');
|
||||
}
|
||||
if(pool.password === '') {
|
||||
throw new Error('Password is not configured for the specified db alias');
|
||||
}
|
||||
|
||||
if (pool.port === '') {
|
||||
throw new Error('Port is not configured for the specified db alias');
|
||||
}
|
||||
else{
|
||||
return new Pool({
|
||||
host: process.env[`DB_${alias}_HOST`],
|
||||
port: process.env[`DB_${alias}_PORT`],
|
||||
database: process.env[`DB_${alias}_DATABASE`],
|
||||
user: process.env[`DB_${alias}_USER`],
|
||||
password: process.env[`DB_${alias}_PASSWORD`],
|
||||
max: 20,
|
||||
idleTimeoutMillis: 30000,
|
||||
connectionTimeoutMillis: 2000,
|
||||
});
|
||||
if (pool.database === '') {
|
||||
throw new Error('Database is not configured for the specified db alias');
|
||||
}
|
||||
|
||||
|
||||
if (pool.user === '') {
|
||||
throw new Error('User is not configured for the specified db alias');
|
||||
}
|
||||
if (pool.password === '') {
|
||||
throw new Error('Password is not configured for the specified db alias');
|
||||
}
|
||||
} else {
|
||||
return new Pool({
|
||||
host: process.env[`DB_${alias}_HOST`],
|
||||
port: process.env[`DB_${alias}_PORT`],
|
||||
database: process.env[`DB_${alias}_DATABASE`],
|
||||
user: process.env[`DB_${alias}_USER`],
|
||||
password: process.env[`DB_${alias}_PASSWORD`],
|
||||
max: 20,
|
||||
idleTimeoutMillis: 30000,
|
||||
connectionTimeoutMillis: 2000,
|
||||
ssl: { rejectUnauthorized: false },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Health check endpoint
|
||||
app.get('/api/health', (req, res) => {
|
||||
res.json({
|
||||
status: 'ok',
|
||||
timestamp: new Date().toISOString(),
|
||||
node_version: process.version
|
||||
});
|
||||
res.json({
|
||||
status: 'ok',
|
||||
timestamp: new Date().toISOString(),
|
||||
node_version: process.version,
|
||||
});
|
||||
});
|
||||
|
||||
// SELECT query endpoint
|
||||
app.post('/api/postgres/select', async (req, res) => {
|
||||
const { query, bindings = [] } = req.body;
|
||||
const { query, bindings = [] } = req.body;
|
||||
|
||||
if (!query) {
|
||||
return res.status(422).json({
|
||||
success: false,
|
||||
error: 'Query is required'
|
||||
});
|
||||
}
|
||||
if (!query) {
|
||||
return res.status(422).json({
|
||||
success: false,
|
||||
error: 'Query is required',
|
||||
});
|
||||
}
|
||||
|
||||
let pool;
|
||||
try {
|
||||
pool = handleHeaders(req.headers);
|
||||
const result = await pool.query(query, bindings);
|
||||
let pool;
|
||||
try {
|
||||
pool = handleHeaders(req.headers);
|
||||
const result = await pool.query(query, bindings);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.rows,
|
||||
count: result.rowCount
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('SELECT Error:', error);
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
} finally {
|
||||
if (pool) await pool.end();
|
||||
}
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.rows,
|
||||
count: result.rowCount,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('SELECT Error:', error);
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: error.message,
|
||||
});
|
||||
} finally {
|
||||
if (pool) await pool.end();
|
||||
}
|
||||
});
|
||||
|
||||
// EXECUTE query endpoint (INSERT, UPDATE, DELETE)
|
||||
app.post('/api/postgres/execute', async (req, res) => {
|
||||
const { query, bindings = [] } = req.body;
|
||||
const { query, bindings = [] } = req.body;
|
||||
|
||||
if (!query) {
|
||||
return res.status(422).json({
|
||||
success: false,
|
||||
error: 'Query is required'
|
||||
});
|
||||
}
|
||||
if (!query) {
|
||||
return res.status(422).json({
|
||||
success: false,
|
||||
error: 'Query is required',
|
||||
});
|
||||
}
|
||||
|
||||
let pool;
|
||||
try {
|
||||
pool = handleHeaders(req.headers);
|
||||
const result = await pool.query(query, bindings);
|
||||
let pool;
|
||||
try {
|
||||
pool = handleHeaders(req.headers);
|
||||
const result = await pool.query(query, bindings);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
affected_rows: result.rowCount
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('EXECUTE Error:', error);
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
} finally {
|
||||
if (pool) await pool.end();
|
||||
}
|
||||
res.json({
|
||||
success: true,
|
||||
affected_rows: result.rowCount,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('EXECUTE Error:', error);
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: error.message,
|
||||
});
|
||||
} finally {
|
||||
if (pool) await pool.end();
|
||||
}
|
||||
});
|
||||
|
||||
// TRANSACTION endpoint
|
||||
app.post('/api/postgres/transaction', async (req, res) => {
|
||||
const { queries } = req.body;
|
||||
const { queries } = req.body;
|
||||
|
||||
if (!queries || !Array.isArray(queries)) {
|
||||
return res.status(422).json({
|
||||
success: false,
|
||||
error: 'Queries array is required'
|
||||
});
|
||||
if (!queries || !Array.isArray(queries)) {
|
||||
return res.status(422).json({
|
||||
success: false,
|
||||
error: 'Queries array is required',
|
||||
});
|
||||
}
|
||||
|
||||
let pool;
|
||||
let client;
|
||||
try {
|
||||
pool = handleHeaders(req.headers);
|
||||
client = await pool.connect();
|
||||
|
||||
await client.query('BEGIN');
|
||||
|
||||
const results = [];
|
||||
for (const item of queries) {
|
||||
const result = await client.query(item.query, item.bindings || []);
|
||||
results.push({
|
||||
rowCount: result.rowCount,
|
||||
success: true,
|
||||
});
|
||||
}
|
||||
|
||||
let pool;
|
||||
let client;
|
||||
try {
|
||||
pool = handleHeaders(req.headers);
|
||||
client = await pool.connect();
|
||||
await client.query('COMMIT');
|
||||
|
||||
await client.query('BEGIN');
|
||||
|
||||
const results = [];
|
||||
for (const item of queries) {
|
||||
const result = await client.query(item.query, item.bindings || []);
|
||||
results.push({
|
||||
rowCount: result.rowCount,
|
||||
success: true
|
||||
});
|
||||
}
|
||||
|
||||
await client.query('COMMIT');
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
results: results
|
||||
});
|
||||
} catch (error) {
|
||||
if (client) await client.query('ROLLBACK');
|
||||
console.error('TRANSACTION Error:', error);
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
} finally {
|
||||
if (client) client.release();
|
||||
if (pool) await pool.end();
|
||||
}
|
||||
res.json({
|
||||
success: true,
|
||||
results: results,
|
||||
});
|
||||
} catch (error) {
|
||||
if (client) await client.query('ROLLBACK');
|
||||
console.error('TRANSACTION Error:', error);
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: error.message,
|
||||
});
|
||||
} finally {
|
||||
if (client) client.release();
|
||||
if (pool) await pool.end();
|
||||
}
|
||||
});
|
||||
|
||||
// INSERT simplified endpoint
|
||||
app.post('/api/postgres/insert', async (req, res) => {
|
||||
const { table, data } = req.body;
|
||||
const { table, data } = req.body;
|
||||
|
||||
if (!table || !data) {
|
||||
return res.status(422).json({
|
||||
success: false,
|
||||
error: 'Table and data are required'
|
||||
});
|
||||
}
|
||||
if (!table || !data) {
|
||||
return res.status(422).json({
|
||||
success: false,
|
||||
error: 'Table and data are required',
|
||||
});
|
||||
}
|
||||
|
||||
let pool;
|
||||
try {
|
||||
pool = handleHeaders(req.headers);
|
||||
const columns = Object.keys(data);
|
||||
const values = Object.values(data);
|
||||
const placeholders = values.map((_, i) => `$${i + 1}`).join(', ');
|
||||
let pool;
|
||||
try {
|
||||
pool = handleHeaders(req.headers);
|
||||
const columns = Object.keys(data);
|
||||
const values = Object.values(data);
|
||||
const placeholders = values.map((_, i) => `$${i + 1}`).join(', ');
|
||||
|
||||
const query = `
|
||||
INSERT INTO "${table}" (${columns.map(c => `"${c}"`).join(', ')})
|
||||
const query = `
|
||||
INSERT INTO "${table}" (${columns.map((c) => `"${c}"`).join(', ')})
|
||||
VALUES (${placeholders})
|
||||
RETURNING *
|
||||
`;
|
||||
|
||||
const result = await pool.query(query, values);
|
||||
const result = await pool.query(query, values);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.rows[0]
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('INSERT Error:', error);
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
} finally {
|
||||
if (pool) await pool.end();
|
||||
}
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.rows[0],
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('INSERT Error:', error);
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: error.message,
|
||||
});
|
||||
} finally {
|
||||
if (pool) await pool.end();
|
||||
}
|
||||
});
|
||||
|
||||
// UPDATE simplified endpoint
|
||||
app.post('/api/postgres/update', async (req, res) => {
|
||||
const { table, data, where } = req.body;
|
||||
const { table, data, where } = req.body;
|
||||
|
||||
if (!table || !data || !where) {
|
||||
return res.status(422).json({
|
||||
success: false,
|
||||
error: 'Table, data and where are required'
|
||||
});
|
||||
}
|
||||
if (!table || !data || !where) {
|
||||
return res.status(422).json({
|
||||
success: false,
|
||||
error: 'Table, data and where are required',
|
||||
});
|
||||
}
|
||||
|
||||
let pool;
|
||||
try {
|
||||
pool = handleHeaders(req.headers);
|
||||
const setColumns = Object.keys(data);
|
||||
const setValues = Object.values(data);
|
||||
const whereColumns = Object.keys(where);
|
||||
const whereValues = Object.values(where);
|
||||
let pool;
|
||||
try {
|
||||
pool = handleHeaders(req.headers);
|
||||
const setColumns = Object.keys(data);
|
||||
const setValues = Object.values(data);
|
||||
const whereColumns = Object.keys(where);
|
||||
const whereValues = Object.values(where);
|
||||
|
||||
const setClause = setColumns
|
||||
.map((col, i) => `"${col}" = $${i + 1}`)
|
||||
.join(', ');
|
||||
const setClause = setColumns.map((col, i) => `"${col}" = $${i + 1}`).join(', ');
|
||||
|
||||
const whereClause = whereColumns
|
||||
.map((col, i) => `"${col}" = $${setValues.length + i + 1}`)
|
||||
.join(' AND ');
|
||||
const whereClause = whereColumns.map((col, i) => `"${col}" = $${setValues.length + i + 1}`).join(' AND ');
|
||||
|
||||
const query = `
|
||||
const query = `
|
||||
UPDATE "${table}"
|
||||
SET ${setClause}
|
||||
WHERE ${whereClause}
|
||||
`;
|
||||
|
||||
const result = await pool.query(query, [...setValues, ...whereValues]);
|
||||
const result = await pool.query(query, [...setValues, ...whereValues]);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
affected_rows: result.rowCount
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('UPDATE Error:', error);
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
} finally {
|
||||
if (pool) await pool.end();
|
||||
}
|
||||
res.json({
|
||||
success: true,
|
||||
affected_rows: result.rowCount,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('UPDATE Error:', error);
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: error.message,
|
||||
});
|
||||
} finally {
|
||||
if (pool) await pool.end();
|
||||
}
|
||||
});
|
||||
|
||||
// DELETE simplified endpoint
|
||||
app.post('/api/postgres/delete', async (req, res) => {
|
||||
const { table, where } = req.body;
|
||||
const { table, where } = req.body;
|
||||
|
||||
if (!table || !where) {
|
||||
return res.status(422).json({
|
||||
success: false,
|
||||
error: 'Table and where are required'
|
||||
});
|
||||
}
|
||||
if (!table || !where) {
|
||||
return res.status(422).json({
|
||||
success: false,
|
||||
error: 'Table and where are required',
|
||||
});
|
||||
}
|
||||
|
||||
let pool;
|
||||
try {
|
||||
pool = handleHeaders(req.headers);
|
||||
const whereColumns = Object.keys(where);
|
||||
const whereValues = Object.values(where);
|
||||
let pool;
|
||||
try {
|
||||
pool = handleHeaders(req.headers);
|
||||
const whereColumns = Object.keys(where);
|
||||
const whereValues = Object.values(where);
|
||||
|
||||
const whereClause = whereColumns
|
||||
.map((col, i) => `"${col}" = $${i + 1}`)
|
||||
.join(' AND ');
|
||||
const whereClause = whereColumns.map((col, i) => `"${col}" = $${i + 1}`).join(' AND ');
|
||||
|
||||
const query = `DELETE FROM "${table}" WHERE ${whereClause}`;
|
||||
const query = `DELETE FROM "${table}" WHERE ${whereClause}`;
|
||||
|
||||
const result = await pool.query(query, whereValues);
|
||||
const result = await pool.query(query, whereValues);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
affected_rows: result.rowCount
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('DELETE Error:', error);
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
} finally {
|
||||
if (pool) await pool.end();
|
||||
}
|
||||
res.json({
|
||||
success: true,
|
||||
affected_rows: result.rowCount,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('DELETE Error:', error);
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: error.message,
|
||||
});
|
||||
} finally {
|
||||
if (pool) await pool.end();
|
||||
}
|
||||
});
|
||||
|
||||
// Start server
|
||||
app.listen(PORT, () => {
|
||||
console.log(`✓ Postgres API running on http://localhost:${PORT}`);
|
||||
console.log(`✓ Health check: http://localhost:${PORT}/api/health`);
|
||||
console.log(`✓ Postgres API running on http://localhost:${PORT}`);
|
||||
console.log(`✓ Health check: http://localhost:${PORT}/api/health`);
|
||||
});
|
||||
|
||||
// Handle shutdown gracefully
|
||||
process.on('SIGINT', async () => {
|
||||
console.log('\nShutting down gracefully...');
|
||||
process.exit(0);
|
||||
});
|
||||
console.log('\nShutting down gracefully...');
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user