feat: Implement user ID duplication check in user registration and update processes
- Added functionality to check for existing user IDs during new user registration and updates to prevent overwriting accounts from different companies. - Enhanced error handling to return appropriate messages when a duplicate user ID is detected. - Updated the frontend to include user ID duplication verification, ensuring a smoother user experience during user creation and editing. - These changes aim to improve data integrity and user management across multiple company implementations.
This commit is contained in:
@@ -949,14 +949,25 @@ export async function addTableData(
|
||||
|
||||
const tableManagementService = new TableManagementService();
|
||||
|
||||
// 🆕 멀티테넌시: company_code 자동 추가 (테이블에 company_code 컬럼이 있는 경우)
|
||||
// 🆕 멀티테넌시: company_code 강제 설정 (테이블에 company_code 컬럼이 있는 경우)
|
||||
// 일반 관리자는 자신의 company_code로 강제, 슈퍼관리자(*)는 클라이언트 값 허용(프리뷰용)
|
||||
const companyCode = req.user?.companyCode;
|
||||
if (companyCode && !data.company_code) {
|
||||
// 테이블에 company_code 컬럼이 있는지 확인
|
||||
if (companyCode) {
|
||||
const hasCompanyCodeColumn = await tableManagementService.hasColumn(tableName, "company_code");
|
||||
if (hasCompanyCodeColumn) {
|
||||
data.company_code = companyCode;
|
||||
logger.info(`멀티테넌시: company_code 자동 추가 - ${companyCode}`);
|
||||
if (companyCode === "*") {
|
||||
// 슈퍼관리자: 클라이언트가 보낸 company_code 허용, 없으면 '*'
|
||||
if (!data.company_code) {
|
||||
data.company_code = companyCode;
|
||||
logger.info(`멀티테넌시: company_code 자동 추가 - ${companyCode}`);
|
||||
}
|
||||
} else {
|
||||
// 일반 관리자: 항상 자신의 company_code로 강제 (타 회사 주입 방지)
|
||||
if (data.company_code && data.company_code !== companyCode) {
|
||||
logger.warn(`멀티테넌시: 타 회사 company_code 주입 시도 차단 - 요청값: ${data.company_code}, 강제값: ${companyCode}`);
|
||||
}
|
||||
data.company_code = companyCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1115,6 +1126,37 @@ export async function editTableData(
|
||||
const tableManagementService = new TableManagementService();
|
||||
const companyCode = req.user?.companyCode || "*";
|
||||
|
||||
// 🔒 멀티테넌시 보안: 일반 관리자는 타 회사 데이터 수정 불가 + company_code 변경 차단
|
||||
if (companyCode !== "*") {
|
||||
const hasCompanyCodeColumn = await tableManagementService.hasColumn(tableName, "company_code");
|
||||
if (hasCompanyCodeColumn) {
|
||||
// 1. 원본 데이터의 company_code 확인
|
||||
if (originalData?.id) {
|
||||
try {
|
||||
const existing = await tableManagementService.getTableData(tableName, {
|
||||
page: 1, size: 1,
|
||||
search: { id: String(originalData.id) },
|
||||
});
|
||||
const existingRow = existing.data?.[0];
|
||||
if (existingRow && existingRow.company_code && existingRow.company_code !== companyCode && existingRow.company_code !== "*") {
|
||||
logger.warn(`🔒 타 회사 데이터 수정 차단: ${tableName} id=${originalData.id}, 요청자=${companyCode}, 데이터소속=${existingRow.company_code}`);
|
||||
res.status(403).json({
|
||||
success: false,
|
||||
message: "해당 데이터를 수정할 권한이 없습니다.",
|
||||
error: { code: "FORBIDDEN_COMPANY", details: "cross-company edit blocked" },
|
||||
});
|
||||
return;
|
||||
}
|
||||
} catch { /* skip 검증 실패 시 원래 흐름 진행 */ }
|
||||
}
|
||||
// 2. updatedData에 company_code 변경 시도가 있으면 제거
|
||||
if (updatedData.company_code && updatedData.company_code !== companyCode) {
|
||||
logger.warn(`🔒 company_code 변경 시도 차단: ${tableName}, 요청값=${updatedData.company_code}`);
|
||||
delete updatedData.company_code;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 회사별 NOT NULL 소프트 제약조건 검증 (수정 데이터 대상)
|
||||
const notNullViolations = await tableManagementService.validateNotNullConstraints(
|
||||
tableName,
|
||||
|
||||
Reference in New Issue
Block a user