• Stefy Lanza (nextime / spora )'s avatar
    township: add a fighter's reference photo from a link (v0.2.47) · 24caf0e8
    Stefy Lanza (nextime / spora ) authored
    Uploading a photo to a fighter was never missing — the Characters page has had a
    file picker and a working /profile/upload-image endpoint all along. It LOOKED
    missing because the page's whole <script> block has been dead since v0.2.41
    (fixed in 11b0f446), so the button did nothing at all. Anyone on 0.2.41-0.2.46
    sees a picker that ignores them.
    
    What was genuinely absent is the other half: pasting a link. That now feeds the
    SAME endpoint, so a fetched picture goes through the same magic-byte check (the
    extension is never trusted), the same ref_NN numbering, and the same
    patch_profile sync to CoderAI. The caller gets one answer covering both sources.
    
    I wrote a second endpoint for this first and deleted it: /profile/upload-image
    already did everything except fetch, and a parallel route would have been a
    second place to keep the validation, the numbering and the sync correct.
    
    The fetch is guarded the same way as the character studio's, for the same reason
    — the request is made by the tool, which can reach coderai on 127.0.0.1 and the
    whole LAN:
    
    - every hop must resolve to a public address, checked by RESOLVING the host
      rather than matching the string;
    - redirects followed by hand, five hops, each re-checked (a public URL that 302s
      to 127.0.0.1 is the usual way past a one-time check);
    - http/https only; 64 MB ceiling enforced while streaming;
    - the content must decode as PNG/JPEG/WebP/GIF by magic bytes.
    
    --allow-private-fetch opts out, for pulling from your own NAS.
    
    Verified against a real profile: an uploaded JPEG became ref_01.jpg, a public
    link became ref_02.png, and a link to 127.0.0.1:8776 was refused with the reason.
    "synced": false is reported honestly when CoderAI is unreachable rather than
    claiming the profile was updated.
    
    131 tests.
    Co-Authored-By: 's avatarClaude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0182DhR1eFNPQyGmDrpHbedY
    24caf0e8
test_township_page_js.py 6.36 KB