{"version":3,"sources":["../src/server/handlers/validate-avatar.ts"],"names":["HTTPException"],"mappings":";;;;;AAEA,IAAM,mBAAmB,GAAA,GAAM,IAAA;AAOxB,SAAS,0BAA0B,QAAA,EAAqD;AAC7F,EAAA,IAAI,CAAC,YAAY,EAAE,WAAA,IAAe,aAAa,QAAA,CAAS,SAAA,KAAc,IAAA,IAAQ,QAAA,CAAS,SAAA,KAAc,MAAA;AACnG,IAAA;AACF,EAAA,IAAI,OAAO,QAAA,CAAS,SAAA,KAAc,QAAA,EAAU;AAC1C,IAAA,MAAM,IAAIA,+BAAA,CAAc,GAAA,EAAK,EAAE,OAAA,EAAS,uCAAuC,CAAA;AAAA,EACjF;AAEA,EAAA,MAAM,UAAU,QAAA,CAAS,SAAA;AACzB,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,4BAA4B,CAAA;AACxD,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,MAAM,IAAIA,gCAAc,GAAA,EAAK;AAAA,MAC3B,OAAA,EAAS;AAAA,KACV,CAAA;AAAA,EACH;AAKA,EAAA,MAAM,aAAA,GAAgB,MAAM,CAAC,CAAA;AAC7B,EAAA,MAAM,cAAA,GACJ,aAAA,CAAc,MAAA,GAAS,CAAA,IACvB,aAAA,CAAc,SAAS,CAAA,KAAM,CAAA,IAC7B,kEAAA,CAAmE,IAAA,CAAK,aAAa,CAAA;AACvF,EAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,IAAA,MAAM,IAAIA,+BAAA,CAAc,GAAA,EAAK,EAAE,OAAA,EAAS,8CAA8C,CAAA;AAAA,EACxF;AACA,EAAA,MAAM,UAAA,GAAa,MAAA,CAAO,IAAA,CAAK,aAAA,EAAe,QAAQ,CAAA,CAAE,UAAA;AAExD,EAAA,IAAI,eAAe,CAAA,EAAG;AACpB,IAAA,MAAM,IAAIA,+BAAA,CAAc,GAAA,EAAK,EAAE,OAAA,EAAS,+BAA+B,CAAA;AAAA,EACzE;AAEA,EAAA,IAAI,aAAa,gBAAA,EAAkB;AACjC,IAAA,MAAM,IAAIA,gCAAc,GAAA,EAAK;AAAA,MAC3B,OAAA,EAAS,CAAA,2BAAA,EAA8B,gBAAgB,CAAA,iBAAA,EAAoB,UAAU,CAAA,CAAA;AAAA,KACtF,CAAA;AAAA,EACH;AACF","file":"chunk-ZCX2J552.cjs","sourcesContent":["import { HTTPException } from '../http-exception';\n\nconst AVATAR_MAX_BYTES = 512 * 1024; // 512 KB\n\n/**\n * Validates `metadata.avatarUrl` if present.\n * Ensures it's a well-formed data URL and the decoded payload is ≤ 512 KB.\n * No-ops when metadata is absent or doesn't contain avatarUrl.\n */\nexport function validateMetadataAvatarUrl(metadata: Record | undefined): void {\n if (!metadata || !('avatarUrl' in metadata) || metadata.avatarUrl === null || metadata.avatarUrl === undefined)\n return;\n if (typeof metadata.avatarUrl !== 'string') {\n throw new HTTPException(400, { message: 'metadata.avatarUrl must be a string' });\n }\n\n const dataUrl = metadata.avatarUrl;\n const match = dataUrl.match(/^data:([^;]+);base64,(.+)$/);\n if (!match) {\n throw new HTTPException(400, {\n message: 'metadata.avatarUrl must be a valid data URL (data:;base64,)',\n });\n }\n\n // `Buffer.from(..., 'base64')` decodes leniently — it silently ignores\n // invalid characters and never throws. Validate the payload format strictly\n // before measuring its byte length so malformed input is rejected.\n const base64Payload = match[2]!;\n const isStrictBase64 =\n base64Payload.length > 0 &&\n base64Payload.length % 4 === 0 &&\n /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(base64Payload);\n if (!isStrictBase64) {\n throw new HTTPException(400, { message: 'metadata.avatarUrl contains invalid base64' });\n }\n const byteLength = Buffer.from(base64Payload, 'base64').byteLength;\n\n if (byteLength === 0) {\n throw new HTTPException(400, { message: 'metadata.avatarUrl is empty' });\n }\n\n if (byteLength > AVATAR_MAX_BYTES) {\n throw new HTTPException(413, {\n message: `metadata.avatarUrl exceeds ${AVATAR_MAX_BYTES}-byte limit (got ${byteLength})`,\n });\n }\n}\n"]}