@osiris-ai/postgres-sdk
Version:
Osiris Postgres SDK
119 lines (116 loc) • 3.15 kB
JavaScript
import { z } from 'zod';
import { SecretSharingAuthenticator } from '@osiris-ai/sdk';
import { Client } from 'pg';
// @osiris-ai/postgres-sdk - PostgreSQL SDK for Authentication and API Clients
var PostgresSecretSchema = z.object({
db_url: z.string().url({ message: "Invalid database URL format" })
});
var PostgresSecretSharingAuthenticator = class extends SecretSharingAuthenticator {
secrets = null;
constructor() {
super("postgres", PostgresSecretSchema);
}
set(secrets) {
const result = PostgresSecretSchema.safeParse(secrets);
if (!result.success) {
return false;
}
this.secrets = result.data;
return true;
}
getDbUrl() {
return this.secrets?.db_url ?? null;
}
/**
* Execute SQL queries against the PostgreSQL database
* @param params Action parameters containing SQL query
* @param secrets Database connection secrets
* @returns Query results or error response
*/
async action(params, secrets) {
if (!params.data) {
return {
status: 400,
statusText: "No data provided",
data: null
};
}
const sql = params.data.sql;
const queryParams = params.data.params;
if (!sql || !queryParams) {
return {
status: 400,
statusText: "No SQL query provided",
data: null
};
}
const validation = this.validateSql(sql);
if (!validation.isValid) {
return {
status: 400,
statusText: validation.error || "Invalid SQL query",
data: null
};
}
if (!this.secrets?.db_url) {
return {
status: 400,
statusText: "No database connection configured",
data: null
};
}
const client = new Client({ connectionString: this.secrets.db_url });
try {
await client.connect();
const result = await client.query(sql, queryParams);
await client.end();
return {
status: 200,
statusText: "OK",
data: {
rows: result.rows,
rowCount: result.rowCount,
command: result.command
},
headers: {}
};
} catch (error) {
await client.end().catch(() => {
});
return {
status: 500,
statusText: error.message || "Database query failed",
data: null
};
}
}
/**
* Validate SQL query for safety (basic checks)
* @param sql SQL query to validate
* @returns true if query appears safe
*/
validateSql(sql) {
const trimmedSql = sql.trim().toLowerCase();
const dangerousPatterns = [
/^\s*drop\s+/,
/^\s*delete\s+.*\s+where\s+1\s*=\s*1/,
/^\s*truncate\s+/,
/^\s*alter\s+/,
/;\s*drop\s+/,
/;\s*delete\s+/,
/;\s*truncate\s+/
];
for (const pattern of dangerousPatterns) {
if (pattern.test(trimmedSql)) {
return {
isValid: false,
error: "SQL query contains potentially dangerous operations"
};
}
}
return { isValid: true };
}
};
export { PostgresSecretSharingAuthenticator };
//# sourceMappingURL=authenticator.js.map
//# sourceMappingURL=authenticator.js.map