날씨 랑 todo/긴급위젯이랑 정비일정 위젯 합치기 완료
This commit is contained in:
@@ -441,7 +441,7 @@ export class DashboardController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 쿼리 실행
|
||||
* 쿼리 실행 (SELECT만)
|
||||
* POST /api/dashboards/execute-query
|
||||
*/
|
||||
async executeQuery(req: AuthenticatedRequest, res: Response): Promise<void> {
|
||||
@@ -506,6 +506,79 @@ export class DashboardController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DML 쿼리 실행 (INSERT, UPDATE, DELETE)
|
||||
* POST /api/dashboards/execute-dml
|
||||
*/
|
||||
async executeDML(req: AuthenticatedRequest, res: Response): Promise<void> {
|
||||
try {
|
||||
const { query } = req.body;
|
||||
|
||||
// 유효성 검증
|
||||
if (!query || typeof query !== "string" || query.trim().length === 0) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
message: "쿼리가 필요합니다.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// SQL 인젝션 방지를 위한 기본적인 검증
|
||||
const trimmedQuery = query.trim().toLowerCase();
|
||||
const allowedCommands = ["insert", "update", "delete"];
|
||||
const isAllowed = allowedCommands.some((cmd) =>
|
||||
trimmedQuery.startsWith(cmd)
|
||||
);
|
||||
|
||||
if (!isAllowed) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
message: "INSERT, UPDATE, DELETE 쿼리만 허용됩니다.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 위험한 명령어 차단
|
||||
const dangerousPatterns = [
|
||||
/drop\s+table/i,
|
||||
/drop\s+database/i,
|
||||
/truncate/i,
|
||||
/alter\s+table/i,
|
||||
/create\s+table/i,
|
||||
];
|
||||
|
||||
if (dangerousPatterns.some((pattern) => pattern.test(query))) {
|
||||
res.status(403).json({
|
||||
success: false,
|
||||
message: "허용되지 않는 쿼리입니다.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 쿼리 실행
|
||||
const result = await PostgreSQLService.query(query.trim());
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: {
|
||||
rowCount: result.rowCount || 0,
|
||||
command: result.command,
|
||||
},
|
||||
message: "쿼리가 성공적으로 실행되었습니다.",
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("DML execution error:", error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: "쿼리 실행 중 오류가 발생했습니다.",
|
||||
error:
|
||||
process.env.NODE_ENV === "development"
|
||||
? (error as Error).message
|
||||
: "쿼리 실행 오류",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 외부 API 프록시 (CORS 우회용)
|
||||
* POST /api/dashboards/fetch-external-api
|
||||
|
||||
Reference in New Issue
Block a user