diff options
| author | Adam Soltys <[email protected]> | 2026-09-04 19:04:41 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-09-04 20:12:58 -0700 |
| commit | e63f86a603ebae0e7c66f94bfdea69905f36f80c (patch) | |
| tree | fa0d940c8aa615119bf60eed85d827ba1c0b9266 /src/routes/(app)/pos/+page.server.ts | |
| parent | a9ae409528219d56a9fbab5dca8a1ad3af68a106 (diff) | |
| download | coinos-ui-e63f86a603ebae0e7c66f94bfdea69905f36f80c.tar.gz coinos-ui-e63f86a603ebae0e7c66f94bfdea69905f36f80c.zip | |
pos: refuse to flash anything that is not a valid LittleFS image
The flasher hex-encoded whatever the /flash endpoint returned, so a
server error body was written to devices as the config partition.
Check the response status, require a 128KB image with the LittleFS
magic, and surface the error above the form instead.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_014gVYGi29FjTeLdNTiutkZx
Diffstat (limited to 'src/routes/(app)/pos/+page.server.ts')
| -rw-r--r-- | src/routes/(app)/pos/+page.server.ts | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/src/routes/(app)/pos/+page.server.ts b/src/routes/(app)/pos/+page.server.ts index 1df1bb33..1e3e1e99 100644 --- a/src/routes/(app)/pos/+page.server.ts +++ b/src/routes/(app)/pos/+page.server.ts @@ -1,6 +1,18 @@ import { PUBLIC_COINOS_URL } from "$env/static/public"; import { auth, fd, get } from "$lib/utils"; import { hex } from "@scure/base"; +import { fail } from "@sveltejs/kit"; + +const LITTLEFS_SIZE = 0x20000; +const LITTLEFS_MAGIC = "littlefs"; + +// A valid image is exactly one partition long and carries the LittleFS +// superblock magic at byte 8. Anything else (e.g. a JSON error body from +// the server) must never reach the flasher. +const isLittleFS = (buf: Uint8Array) => + buf.length === LITTLEFS_SIZE && + new TextDecoder().decode(buf.subarray(8, 8 + LITTLEFS_MAGIC.length)) === + LITTLEFS_MAGIC; export async function load({ cookies }) { let token; @@ -25,6 +37,22 @@ export const actions = { }); const buf = new Uint8Array(await res.arrayBuffer()); + + if (!res.ok) { + let message = `Config server returned ${res.status}`; + try { + message = JSON.parse(new TextDecoder().decode(buf)).message || message; + } catch (e) {} + return fail(res.status >= 400 && res.status < 600 ? res.status : 500, { + error: message, + }); + } + + if (!isLittleFS(buf)) + return fail(500, { + error: `Config server returned an invalid image (${buf.length} bytes)`, + }); + return { bytes: hex.encode(buf) }; }, }; |
