/// // Auto-update manifest (epic #6, issue #16). // // GET /api/update/manifest?platform=windows|linux|android (auth: users) // // Returns the latest published build for the caller's platform. The download is // PocketBase's native protected file endpoint: the app mints a short-lived file // token (`POST /api/files/token`) and appends it to `downloadPath`, and the token // grant re-checks the collection rule. // // `variant` used to be chosen here from the account's admin-set `nsfwEnabled`, // picking an 18+ build over the clean one. Amber has no 18+ build any more, so it // is a constant. // // It is NOT removed from the response, and must not be. Every Amber already // installed compares this field against its own and refuses a mismatch SILENTLY // — no error, no prompt, the update simply never appears. Drop it, or send // anything but "clean", and those installs stop updating with nothing to see. // // NOTE: PocketBase runs each routerAdd handler in its own isolated JSVM, so the // small helpers live inside the handler. routerAdd("GET", "/api/update/manifest", (e) => { const ALLOWED = ["windows", "linux", "android"] const platform = (e.request.url.query().get("platform") || "").toLowerCase().trim() if (ALLOWED.indexOf(platform) === -1) throw new BadRequestError("bad or missing platform") // One build ships. See the note above for why this field survives at all. const variant = "clean" let rec = null try { const rows = $app.findRecordsByFilter( "releases", "platform = {:p} && variant = {:v}", "-buildNumber", 1, 0, { p: platform, v: variant } ) if (rows && rows.length) rec = rows[0] } catch (_) { /* no matching release */ } if (!rec) return e.json(200, { available: false }) const filename = rec.getString("file") return e.json(200, { available: true, platform: platform, variant: variant, version: rec.getString("version"), buildNumber: rec.getInt("buildNumber"), notes: rec.getString("notes"), sha256: rec.getString("sha256"), size: rec.getInt("size"), filename: filename, // Native protected-file path; the app appends `?token=`. downloadPath: "/api/files/releases/" + rec.id + "/" + filename, }) }, $apis.requireAuth("users"))