summaryrefslogtreecommitdiff
path: root/components/drm/drmUtils.ts
blob: 4ba63090c5bc69376409040d5465632f40fbf59c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/**
 * drmUtils.ts
 * 1. 복호화 엔드포인트 (/api/drm/decrypt)를 사용하는 함수
 * 2. 복호화 서버액션을 제공한다.
 * 
 * decryptWithServerAction(file): 서버액션을 사용하여 복호화한 파일을 응답하는 함수
 * 
 */

'use server';

// 서버 액션을 사용하여 복호화하는 함수
export async function decryptWithServerAction(file: File): Promise<ArrayBuffer> {
  try {
    const formData = new FormData();
    formData.append('file', file);

    // 로컬 6543 포트에 drm-proxy 서버가 실행되고 있어야 함
    const backendUrl = "http://localhost:6543/api/drm-proxy/decrypt";
    
    // 로깅은 스프링 자체적으로도 진행하지만(log 파일), 필요시 db 액션을 호출해 eVCP 데이터베이스에 저장
    console.log(`[DRM] 파일 복호화 시도: ${file.name} (크기: ${file.size} bytes, 타입: ${file.type})`);
    
    // POST 요청으로 파일을 file 이라는 키로 Body에 담아 전송하면, 복호화된 파일을 응답받음
    // 응답 헤더에 원본 파일명이 있음. (현재는 미사용)
    const response = await fetch(backendUrl, {
      method: "POST",
      body: formData,
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => '응답 텍스트를 가져올 수 없음');
      throw new Error(`DRM 서버 응답 오류 [${response.status}]: ${errorText}`);
    }

    // 응답을 ArrayBuffer로 받아서 리턴함
    const data = await response.arrayBuffer();
    console.log(`[DRM] 파일 복호화 성공: ${file.name} (결과 크기: ${data.byteLength} bytes)`);
    
    return data;
  } catch (error) {
    
    // 오류 발생시 로깅하며, 폴백으로 복호화되지 않은 파일을 리턴
    const errorMessage = error instanceof Error 
      ? `${error.name}: ${error.message}` 
      : String(error);
    
    console.error(`[DRM] 복호화 오류: ${errorMessage}`, {
      fileName: file.name,
      fileSize: file.size,
      fileType: file.type,
      remark: `
        [정상 동작 안내]
        DTS 개발 서버나 로컬 환경에서는 에러가 발생하는 것이 정상적인 동작입니다.
        이 경우 원본 파일의 arrayBuffer가 그대로 반환됩니다.

        [발생 가능한 에러 케이스]
        1. DRM 백엔드 서버가 없는 경우 - CONNECTION_REJECTED 발생
        2. DRM 중앙 서버와 통신 불가한 경우 - PARENT CERT 속성 추가 불가로 인한 백엔드측 500 에러
      `,
      error
    });
    
    return await file.arrayBuffer();
  }
}

/**
 * Buffer를 사용하여 복호화하는 함수 (서버 측 파일 처리용)
 * @param fileBuffer - 복호화할 파일의 Buffer
 * @param fileName - 원본 파일명
 * @returns 복호화된 Buffer
 */
export async function decryptBufferWithServerAction(
  fileBuffer: Buffer, 
  fileName: string
): Promise<Buffer> {
  try {
    // Buffer를 Blob으로 변환하여 FormData에 추가
    const blob = new Blob([fileBuffer]);
    const formData = new FormData();
    formData.append('file', blob, fileName);

    // 로컬 6543 포트에 drm-proxy 서버가 실행되고 있어야 함
    const backendUrl = "http://localhost:6543/api/drm-proxy/decrypt";
    
    console.log(`[DRM] 파일 복호화 시도: ${fileName} (크기: ${fileBuffer.length} bytes)`);
    
    // POST 요청으로 파일을 file 이라는 키로 Body에 담아 전송하면, 복호화된 파일을 응답받음
    const response = await fetch(backendUrl, {
      method: "POST",
      body: formData,
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => '응답 텍스트를 가져올 수 없음');
      throw new Error(`DRM 서버 응답 오류 [${response.status}]: ${errorText}`);
    }

    // 응답을 ArrayBuffer로 받아서 Buffer로 변환
    const arrayBuffer = await response.arrayBuffer();
    const decryptedBuffer = Buffer.from(arrayBuffer);
    console.log(`[DRM] 파일 복호화 성공: ${fileName} (결과 크기: ${decryptedBuffer.length} bytes)`);
    
    return decryptedBuffer;
  } catch (error) {
    // 오류 발생시 로깅하며, 폴백으로 복호화되지 않은 Buffer를 리턴
    const errorMessage = error instanceof Error 
      ? `${error.name}: ${error.message}` 
      : String(error);
    
    console.error(`[DRM] 복호화 오류: ${errorMessage}`, {
      fileName: fileName,
      fileSize: fileBuffer.length,
      remark: `
        [정상 동작 안내]
        DTS 개발 서버나 로컬 환경에서는 에러가 발생하는 것이 정상적인 동작입니다.
        이 경우 원본 Buffer가 그대로 반환됩니다.

        [발생 가능한 에러 케이스]
        1. DRM 백엔드 서버가 없는 경우 - CONNECTION_REJECTED 발생
        2. DRM 중앙 서버와 통신 불가한 경우 - PARENT CERT 속성 추가 불가로 인한 백엔드측 500 에러
      `,
      error
    });
    
    return fileBuffer;
  }
}