v1.12.31 불필요 파일 정리 및 업로드·배포 안정성 보강
This commit is contained in:
@@ -464,6 +464,30 @@ test('긴 접속 시간은 실시간에 표시하고 평균 체류 집계 상한
|
||||
}
|
||||
})
|
||||
|
||||
test('공개 업로드는 내부 가져오기 파일의 정규화된 우회 경로도 차단한다', async ({ request: anonymousApi }) => {
|
||||
const uploadRoot = process.env.SORI_TEST_UPLOAD_ROOT
|
||||
const privateDirectory = join(uploadRoot, '_import-jobs', 'path-access-test')
|
||||
const publicFile = join(uploadRoot, 'path-access-public.txt')
|
||||
await mkdir(privateDirectory, { recursive: true })
|
||||
await writeFile(join(privateDirectory, 'private.txt'), 'private-test-content')
|
||||
await writeFile(publicFile, 'public-test-content')
|
||||
try {
|
||||
const publicResponse = await anonymousApi.get('/uploads/path-access-public.txt')
|
||||
expect(publicResponse.status()).toBe(200)
|
||||
expect(await publicResponse.text()).toBe('public-test-content')
|
||||
for (const path of [
|
||||
'/uploads/_import-jobs/path-access-test/private.txt',
|
||||
'/uploads/folder%2F..%2F_import-jobs/path-access-test/private.txt',
|
||||
'/uploads/%2F_import-jobs/path-access-test/private.txt'
|
||||
]) {
|
||||
expect((await anonymousApi.get(path)).status(), path).toBe(404)
|
||||
}
|
||||
} finally {
|
||||
await rm(privateDirectory, { recursive: true, force: true })
|
||||
await rm(publicFile, { force: true })
|
||||
}
|
||||
})
|
||||
|
||||
test('미디어 카탈로그 reconcile과 DB 목록 계약 및 fallback을 유지한다', async () => {
|
||||
const uploadRoot = process.env.SORI_TEST_UPLOAD_ROOT
|
||||
const mediaDirectory = join(uploadRoot, 'posts', 'catalog-api-test')
|
||||
@@ -556,9 +580,11 @@ test('미디어 카탈로그 reconcile과 DB 목록 계약 및 fallback을 유
|
||||
const avatarResult = await avatarResponse.json()
|
||||
expect(avatarResult.items[0].avatarOwner.id).toBe(adminUser.userId)
|
||||
expect(avatarResult.items[0].avatarOwner.username).toBeTruthy()
|
||||
const userUsage = avatarResult.items[0].usage.find((usage) => usage.type === 'user')
|
||||
expect(userUsage.typeLabel).toBe('회원')
|
||||
expect(userUsage.adminUrl).toBe(`/admin/members/${adminUser.userId}`)
|
||||
expect(avatarResult.items[0].usage.some((usage) => usage.type === 'user')).toBe(false)
|
||||
const unusedAvatars = await adminApi.get('/admin/api/media?paged=1&tab=all&unused=1&search=catalog-owner')
|
||||
expect((await unusedAvatars.json()).pagination.total).toBe(0)
|
||||
const deleteAvatarResponse = await adminApi.delete('/admin/api/media', { data: { url: avatarUrl } })
|
||||
expect(deleteAvatarResponse.status()).toBe(409)
|
||||
|
||||
const navigationResponse = await adminApi.get('/admin/api/media?paged=1&search=catalog-02&pageSize=50')
|
||||
const navigationResult = await navigationResponse.json()
|
||||
|
||||
Reference in New Issue
Block a user