summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/file-stroage.ts38
-rw-r--r--lib/shi-api/shi-api-utils.ts68
2 files changed, 64 insertions, 42 deletions
diff --git a/lib/file-stroage.ts b/lib/file-stroage.ts
index c347ffe3..7bc9ef1c 100644
--- a/lib/file-stroage.ts
+++ b/lib/file-stroage.ts
@@ -194,31 +194,31 @@ class FileSecurityValidator {
return { valid: true };
}
- // 파일 내용 기본 검증 (매직 넘버 체크 + XSS 패턴 검사)
+ // 파일 내용 기본 검증 (매직 넘버 체크(비활성화) + XSS 패턴 검사)
static async validateFileContent(buffer: Buffer, fileName: string): Promise<{ valid: boolean; error?: string }> {
try {
const extension = path.extname(fileName).toLowerCase().substring(1);
- // 파일 시그니처 (매직 넘버) 검증
- const fileSignatures: Record<string, Buffer[]> = {
- 'pdf': [Buffer.from([0x25, 0x50, 0x44, 0x46])], // %PDF
- 'jpg': [Buffer.from([0xFF, 0xD8, 0xFF])],
- 'jpeg': [Buffer.from([0xFF, 0xD8, 0xFF])],
- 'png': [Buffer.from([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])],
- 'gif': [Buffer.from([0x47, 0x49, 0x46, 0x38])], // GIF8
- 'zip': [Buffer.from([0x50, 0x4B, 0x03, 0x04]), Buffer.from([0x50, 0x4B, 0x05, 0x06])],
- };
+ // 파일 시그니처 (매직 넘버) 검증 << DRM 파일 처리 불가로 주석 처리
+ // const fileSignatures: Record<string, Buffer[]> = {
+ // 'pdf': [Buffer.from([0x25, 0x50, 0x44, 0x46])], // %PDF
+ // 'jpg': [Buffer.from([0xFF, 0xD8, 0xFF])],
+ // 'jpeg': [Buffer.from([0xFF, 0xD8, 0xFF])],
+ // 'png': [Buffer.from([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])],
+ // 'gif': [Buffer.from([0x47, 0x49, 0x46, 0x38])], // GIF8
+ // 'zip': [Buffer.from([0x50, 0x4B, 0x03, 0x04]), Buffer.from([0x50, 0x4B, 0x05, 0x06])],
+ // };
- const expectedSignatures = fileSignatures[extension];
- if (expectedSignatures) {
- const hasValidSignature = expectedSignatures.some(signature =>
- buffer.subarray(0, signature.length).equals(signature)
- );
+ // const expectedSignatures = fileSignatures[extension];
+ // if (expectedSignatures) {
+ // const hasValidSignature = expectedSignatures.some(signature =>
+ // buffer.subarray(0, signature.length).equals(signature)
+ // );
- if (!hasValidSignature) {
- return { valid: false, error: `파일 내용이 확장자와 일치하지 않습니다: ${extension}` };
- }
- }
+ // if (!hasValidSignature) {
+ // return { valid: false, error: `파일 내용이 확장자와 일치하지 않습니다: ${extension}` };
+ // }
+ // }
// 실행 파일 패턴 검색
const executablePatterns = [
diff --git a/lib/shi-api/shi-api-utils.ts b/lib/shi-api/shi-api-utils.ts
index 280a2fcb..3906883a 100644
--- a/lib/shi-api/shi-api-utils.ts
+++ b/lib/shi-api/shi-api-utils.ts
@@ -65,8 +65,8 @@ export const getAllNonsapUser = async () => {
name: u.USR_NM || undefined,
email: u.EMAIL_ADR || undefined,
epId: u.MYSNG_ID || undefined,
- deptCode: u.CH_DEPTCD || undefined,
- deptName: u.CH_DEPTNM || undefined,
+ deptCode: u.DEPTCD || undefined,
+ deptName: u.DEPTNM || undefined,
phone: u.TELNO || undefined,
isAbsent,
isDeletedOnNonSap: isDeleted,
@@ -80,27 +80,49 @@ export const getAllNonsapUser = async () => {
const mappedUsers = mappedRaw as InsertUser[];
if (mappedUsers.length > 0) {
- await db.insert(users)
- .values(mappedUsers)
- .onConflictDoUpdate({
- target: users.nonsapUserId,
- set: {
- name: users.name,
- employeeNumber: users.employeeNumber,
- knoxId: users.knoxId,
- epId: users.epId,
- deptCode: users.deptCode,
- deptName: users.deptName,
- phone: users.phone,
- nonsapUserId: users.nonsapUserId,
- isAbsent: users.isAbsent,
- isDeletedOnNonSap: users.isDeletedOnNonSap,
- isActive: users.isActive,
- isRegularEmployee: users.isRegularEmployee,
- updatedAt: sql`now()`,
- },
- });
- debugSuccess(`[UPSERT] users upserted=${mappedUsers.length} using key=nonsapUserId`);
+ // 배치 처리: 500개씩 분할하여 처리 (콜스택 크기 문제 대응)
+ const BATCH_SIZE = 500;
+ let totalUpserted = 0;
+
+ for (let i = 0; i < mappedUsers.length; i += BATCH_SIZE) {
+ const batch = mappedUsers.slice(i, i + BATCH_SIZE);
+
+ try {
+ await db.insert(users)
+ .values(batch)
+ .onConflictDoUpdate({
+ target: users.nonsapUserId,
+ set: {
+ name: users.name,
+ employeeNumber: users.employeeNumber,
+ knoxId: users.knoxId,
+ epId: users.epId,
+ deptCode: users.deptCode,
+ deptName: users.deptName,
+ phone: users.phone,
+ nonsapUserId: users.nonsapUserId,
+ isAbsent: users.isAbsent,
+ isDeletedOnNonSap: users.isDeletedOnNonSap,
+ isActive: users.isActive,
+ isRegularEmployee: users.isRegularEmployee,
+ updatedAt: sql`now()`,
+ },
+ });
+
+ totalUpserted += batch.length;
+ debugLog(`[BATCH ${Math.floor(i/BATCH_SIZE) + 1}] Processed ${batch.length} users (${totalUpserted}/${mappedUsers.length})`);
+
+ // 배치 간 잠시 대기하여 시스템 부하 방지
+ if (i + BATCH_SIZE < mappedUsers.length) {
+ await new Promise(resolve => setTimeout(resolve, 100));
+ }
+ } catch (batchError) {
+ debugError(`[BATCH ${Math.floor(i/BATCH_SIZE) + 1}] Failed to process batch ${i}-${i+batch.length}`, batchError);
+ throw batchError;
+ }
+ }
+
+ debugSuccess(`[UPSERT] users upserted=${totalUpserted} using key=nonsapUserId (processed in ${Math.ceil(mappedUsers.length/BATCH_SIZE)} batches)`);
} else {
debugWarn('[UPSERT] No users mapped for upsert (missing name/email or invalid USR_ID)');
}