PNG 자료 존재
자료 저장소에는 실제 파일명 image_cat.png가 있습니다.
마지막 업데이트 2026-07-29
이 커밋은 PNG 파일을 시스템에서 없앤 것이 아닙니다. 수업 활동에서 정상 표시를 보장하기 어려운 PNG 참조가 새로 저장되는 길을 목록·편집 화면·API에서 단계적으로 막았습니다.
PNG 업로드 자체를 막은 변경은 아닙니다. 활동과 활동 템플릿에서는 PNG 자료를 선택·저장·일괄 등록할 수 없게 하고, 기존 PNG 참조는 사용자가 교체해야 저장되도록 만든 변경입니다.
활동·활동 템플릿의 PNG 선택 및 저장
PNG 업로드 API, 아바타 자료, 정적 UI 이미지
파일은 PNG였지만 활동에는 확장자 없는 이름만 저장됐고, 수업 화면은 기본적으로 JPG를 찾았습니다.
image_cat.png
image_cat
image_cat.jpg
자료 저장소에는 실제 파일명 image_cat.png가 있습니다.
/api/resources/list가 선택 목록용 이름을 image_cat으로 만듭니다.
일반 자료는 resName, 선택형 이미지는 selectionImages에 저장됩니다.
MeetImage는 확장자가 없으면 .jpg를 붙여 자료를 찾습니다.
실제 PNG와 요청한 JPG 이름이 달라 자료를 표시하지 못할 수 있었습니다.
실패 가능근거 수준: 위 흐름은 커밋과 현재 렌더러 코드에서 확인되는 실패 가능성입니다. 커밋 메시지에는 특정 수업의 장애 사례가 별도로 기록되어 있지 않으므로, “실제 장애가 확정됐다”고 확대 해석하지 않습니다.
목록에서 예방하고, 기존 데이터는 편집 화면에서 알려주며, 마지막에는 서버가 우회를 차단합니다.
선택 가능한 resources에서는 PNG를 빼고, 기존 참조 확인용 pngResources에는 이름을 남깁니다.
활동·템플릿 폼이 현재 step을 검사해 “자료 교체가 필요합니다”와 해당 자료명을 보여줍니다.
activity-form · activity-template-form 사용자가 고칠 위치를 알려주는 UXresName이나 selectionImages에 PNG 참조가 남아 있으면 저장 요청 자체를 보내지 않습니다.
서버가 DynamoDB 자료 목록과 다시 대조하고 HTTP 400 PNG_RESOURCE_NOT_ALLOWED를 반환합니다.
같은 제한이지만 새 활동, 기존 활동, API 사용자는 서로 다른 지점에서 안내받습니다.
자료 선택 목록에 PNG 이름이 나타나지 않습니다. 처음부터 JPG·WEBP·GIF 또는 영상 자료를 선택합니다.
체감: 잘못 고를 기회가 사라짐경고에 표시된 PNG 자료명을 확인하고 다른 이미지 또는 영상으로 교체해야 저장할 수 있습니다.
체감: 문제 자료와 해결 행동을 바로 안내요청 안에 PNG 참조가 하나라도 있으면 DB 쓰기 전에 HTTP 400으로 거절됩니다.
체감: 조용한 데이터 오염 대신 명시적 오류“PNG 전체 금지”가 아니라 “활동에서 PNG 참조 저장 제한”입니다.
| 구분 | 이번 커밋의 처리 | 의미 |
|---|---|---|
| 활동 / 활동 템플릿 | PNG 참조 제한 | 새 선택과 저장, 기존 참조 재저장을 막음 |
resName / selectionImages |
둘 다 검사 | 일반 자료와 “선택 후 넘기기” 이미지를 함께 보호 |
| 단건 생성·수정 / 일괄 생성·수정 | 관련 API 모두 서버 검사 | 화면 밖의 직접 요청도 저장 전에 차단 |
| PNG 업로드 API | 유지 | .png 업로드 허용 코드는 이번 커밋에서 제거하지 않음 |
| 기존 DynamoDB 데이터 | 자동 삭제·변환 없음 | 편집 시 경고 후 사람이 교체 |
| 아바타·정적 UI 이미지 | 이번 제한 범위 밖 | 활동 step 자료 검증과 별개 |
“이번 PNG 판정 대상이 아니다”는 각 형식의 모든 런타임 동작을 이 커밋이 새로 보장한다는 뜻은 아닙니다.
공통 판정 함수 하나를 UI와 서버가 공유하고, 실제 저장 경로마다 서버 가드를 적용했습니다.
4b4abc095ae5f203224466835ddeb84e2e60a351
fix: restrict PNG activity resources
판정 코어 1 · 서버 가드 1 · API 7 · UI 3 · 테스트 1 = 총 13개 파일
파일명 정규화, PNG 목록, step 참조 교집합을 계산합니다.
apps/web/lib/activity-resource-validation.tsDynamoDB의 실제 자료 파일명과 요청 step을 대조합니다.
apps/web/lib/activity-resource-guard.ts목록 응답을 분리하고, 활동·템플릿의 단건 및 일괄 저장 직전에 검증합니다.
apps/web/app/api/resources/list/route.tsapps/web/app/api/activities/route.tsapps/web/app/api/activities/[userId]/[id]/route.tsapps/web/app/api/activities/bulk/route.tsapps/web/app/api/activity-templates/route.tsapps/web/app/api/activity-templates/[id]/route.tsapps/web/app/api/activity-templates/bulk/route.tsPNG 이름 수신, 기존 참조 경고, 제출 차단과 안내 문구를 담당합니다.
apps/web/components/sections/activity-form.tsxapps/web/components/sections/activity-template-form.tsxapps/web/components/ui/step-form.tsx대소문자, 이름 정규화, 두 참조 필드 동시 탐지를 고정합니다.
apps/web/lib/activity-resource-validation.test.ts| 대상 | 단건 생성 | 단건 수정 | 일괄 생성 | 일괄 수정 |
|---|---|---|---|---|
| 활동 | POST /api/activities |
PUT /api/activities/[userId]/[id] |
POST /api/activities/bulk |
PUT /api/activities/bulk |
| 활동 템플릿 | POST /api/activity-templates |
PUT /api/activity-templates/[id] |
POST /api/activity-templates/bulk |
해당 커밋에 별도 일괄 수정 경로 없음 |
UI를 거치지 않은 요청도 같은 오류 코드와 실제 문제 자료명을 받습니다.
클라이언트는 resourceNames를 이용해 무엇을 교체할지 안내할 수 있습니다.
{
"error": "PNG_RESOURCE_NOT_ALLOWED",
"message": "PNG 자료(image_cat)는 수업 화면에서 사용할 수 없습니다. 다른 이미지 또는 영상으로 교체해주세요.",
"resourceNames": ["image_cat"]
}
.png와 .PNG를 같은 PNG로 판정_480p 접미어를 제거해 활동 이름으로 정규화resName과 selectionImages의 PNG 참조를 함께 탐지이 커밋의 핵심은 “파일 형식 금지”보다 “잘못된 활동 참조가 저장되지 않게 하는 다층 방어”입니다.
변경 전에는 PNG가 활동 목록에 들어오고 확장자 없는 이름으로 저장될 수 있었습니다. 변경 후에는 선택 목록에서 예방하고, 기존 참조를 알려주고, 폼과 서버에서 두 번 차단합니다.