kintex/mobile/lib/screenCapture.ts

45 lines
1.6 KiB
TypeScript

/*
* 화면캡처/녹화 차단 래퍼 (B4 · checklist DP-4 / MASVS-PLATFORM-3).
* 근거: docs/security/mobile-security-audit.md 백로그 B4.
*
* expo-screen-capture:
* · Android: FLAG_SECURE 적용 → 스크린샷·화면녹화·최근앱 스냅샷 차단
* · iOS: 캡처 자체 차단은 불가(OS 제약) → 캡처 "감지"만 지원(별도), 여기서는 Android FLAG_SECURE 목적
* 방어적 동적 require: 미설치/Expo Go/웹에서 graceful no-op(회귀 방지).
* key 인자로 화면별 스택 관리 → 여러 민감화면 동시/중첩 진입 시 안전 해제.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let ScreenCapture: any = null;
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
ScreenCapture = require('expo-screen-capture');
} catch {
ScreenCapture = null;
}
/** 이 기기/빌드에서 캡처 차단 기능을 쓸 수 있는지. */
export function isScreenCaptureGuardAvailable(): boolean {
return typeof ScreenCapture?.preventScreenCaptureAsync === 'function';
}
/** 캡처/녹화 차단 활성(진입 시). key로 화면 스택 구분. */
export async function preventCapture(key: string): Promise<void> {
if (!isScreenCaptureGuardAvailable()) return;
try {
await ScreenCapture.preventScreenCaptureAsync(key);
} catch {
/* graceful */
}
}
/** 캡처/녹화 차단 해제(이탈 시). 진입 시와 동일 key 필요. */
export async function allowCapture(key: string): Promise<void> {
if (typeof ScreenCapture?.allowScreenCaptureAsync !== 'function') return;
try {
await ScreenCapture.allowScreenCaptureAsync(key);
} catch {
/* graceful */
}
}