Switch login to password-only and split pack zip paths

- Login form/route accepts password only; matched account row provides session userId
- PackDefinition: replace packPath with mapPath (.mc_custom/saves) and serverPath (server install dir); editor exposes two .zip fields
- Installer resolves relative platform/map/server URLs against manifest origin under /file/{platforms,maps,servers}/<name>; downloads and extracts the zips

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-10 20:06:32 +09:00
parent 7a963d0409
commit 9c4f0e8dbc
7 changed files with 82 additions and 41 deletions

View File

@@ -38,10 +38,21 @@ export function defaultPackDefinition(name: string): PackDefinition {
serverMaxRam: 4096,
clientMinRam: 2048,
clientRecommendedRam: 4096,
packPath: ''
mapPath: '',
serverPath: ''
}
}
function sanitizeZipFileName(input: unknown): string {
if (typeof input !== 'string') return ''
const trimmed = input.trim().replace(/^\/+/, '')
if (trimmed.length === 0) return ''
// 빈 값 허용, .zip 으로 끝나야 함, 경로 탈출 방지
if (trimmed.includes('..') || trimmed.includes('\\')) return ''
if (!/\.zip$/i.test(trimmed)) return ''
return trimmed
}
const ALLOWED_LOADERS: LoaderType[] = ['vanilla', 'forge', 'fabric', 'neoforge']
export function normalizePackDefinition(input: Partial<PackDefinition> & Record<string, unknown>): PackDefinition {
@@ -90,7 +101,8 @@ export function normalizePackDefinition(input: Partial<PackDefinition> & Record<
serverMaxRam: clampNumber(input.serverMaxRam, fallback.serverMaxRam),
clientMinRam: clampNumber(input.clientMinRam, fallback.clientMinRam),
clientRecommendedRam: clampNumber(input.clientRecommendedRam, fallback.clientRecommendedRam),
packPath: typeof input.packPath === 'string' ? input.packPath.trim() : ''
mapPath: sanitizeZipFileName(input.mapPath),
serverPath: sanitizeZipFileName(input.serverPath)
}
}

View File

@@ -20,7 +20,10 @@ export interface PackDefinition {
serverMaxRam: number
clientMinRam: number
clientRecommendedRam: number
packPath: string
/** /file/maps/<mapPath> 에서 받아 .mc_custom/saves 로 풀 zip 파일 이름. */
mapPath: string
/** /file/servers/<serverPath> 에서 받아 서버 설치 경로로 풀 zip 파일 이름. */
serverPath: string
}
export interface ManifestEntry {