amber-backend/pb_hooks/update.pb.js

60 lines
2.3 KiB
JavaScript
Raw Normal View History

/// <reference path="../pb_data/types.d.ts" />
// Auto-update manifest (epic #6, issue #16).
//
// GET /api/update/manifest?platform=windows|linux|android (auth: users)
//
Stop choosing an update variant, and drop the 18+ controls Amber ships one build. The manifest hook returned `adult` or `clean` according to the account's nsfwEnabled flag; it now returns `clean` to everyone. The `variant` field itself stays in the response, and that is the important part: every Amber already installed compares it against its own and refuses a mismatch SILENTLY - no error, no prompt, the update simply never appears. Removing the field, or sending anything else, would strand every one of those installs with nothing to see. whoami stops returning nsfwEnabled. It was there in case some future amber-api surface wanted to scope results by it; none was built, and an account flag nobody reads is what a token-introspection endpoint should not be handing out. amber-api's copy goes with it - it was parsed into the user object and never once branched on. The dashboard loses the 18+ account tile, the variant column, the per-flavour error table, the 18+ pill, the per-user enable/disable button and the new-account checkbox. A control that sets a flag nothing reads is worse than no control. Releases are now read as newest-per-platform filtered to variant='clean', rather than newest-per-platform-and-variant. Leftover 18+ rows are still in the collection and would otherwise have been reported as what the family is being served. Those rows and the collection rule that hides them are deliberately left alone: the rule is what keeps them unreachable, and deleting published artifacts is not something to do as a side effect of a cleanup. check-flavor.py is gone. It proved which of two builds an artifact was, by a marker compiled into the Dart snapshot, because a clean-named Windows installer once carried the 18+ payload. With one build there is nothing to tell apart.
2026-08-30 02:09:10 +00:00
// 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.
//
Drop the 18+ account flag, its rule clause and the web page's 18+ field Nothing read `users.nsfwEnabled` any more. `/api/amber/whoami` stopped returning it, `GET /api/update/manifest` always answers `clean`, and the `releases` read rule stopped mentioning it in migration 1793000000, when the nine 18+ rows (437 MB) were deleted. What was left was a per-account flag nobody writes and nobody reads, sitting on the family's accounts and showing up in every schema dump and access-rule review as if it still gated something. A flag that looks like a protection but protects nothing costs the next reader the work of proving it dead. One live reader did remain: pb_public/index.html showed a "Zdroj 18+" source field and wrote `adultAddonUrl` into the encrypted addon config for a flagged account, and picked a different child-profile label for one. Both are gone, so the page offers the same three sources to everyone. Migration 1797000000 drops the field, rewrites users.updateRule to `id = @request.auth.id` (the clause it loses guarded a field that no longer exists), and removes `adult` from releases.variant's allowed values. Checked before writing it: 15 release rows, every one `clean`; three accounts carried the flag (the owner's, one family member's, the retired test account); the separate 18+ app has no accounts and no PocketBase, so nothing outside Amber reads it. `variant` itself stays and stays required: every installed Amber compares it against its own build and refuses a mismatch SILENTLY, so dropping the field would strand those installs with no error to see. publish-release.sh now accepts only `clean`. The status dashboard stops listing `adult-stremio-addon` and `stripchat-proxy`. Both still run on the VPS; they are the owner's, not Amber's, and Amber never reached them. scripts/verify.py asserts the flag stays gone (field absent, no rule mentions it, updateRule own-record-only). Run against a local PocketBase built from origin/main it failed on exactly those three checks; with this migration applied, ALL CHECKS PASSED. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 18:32:02 +00:00
// `variant` used to be chosen here from an account flag, picking an 18+ build
// over the clean one. Amber has no 18+ build any more and the flag is gone
// (migration 1797000000), so it is a constant.
Stop choosing an update variant, and drop the 18+ controls Amber ships one build. The manifest hook returned `adult` or `clean` according to the account's nsfwEnabled flag; it now returns `clean` to everyone. The `variant` field itself stays in the response, and that is the important part: every Amber already installed compares it against its own and refuses a mismatch SILENTLY - no error, no prompt, the update simply never appears. Removing the field, or sending anything else, would strand every one of those installs with nothing to see. whoami stops returning nsfwEnabled. It was there in case some future amber-api surface wanted to scope results by it; none was built, and an account flag nobody reads is what a token-introspection endpoint should not be handing out. amber-api's copy goes with it - it was parsed into the user object and never once branched on. The dashboard loses the 18+ account tile, the variant column, the per-flavour error table, the 18+ pill, the per-user enable/disable button and the new-account checkbox. A control that sets a flag nothing reads is worse than no control. Releases are now read as newest-per-platform filtered to variant='clean', rather than newest-per-platform-and-variant. Leftover 18+ rows are still in the collection and would otherwise have been reported as what the family is being served. Those rows and the collection rule that hides them are deliberately left alone: the rule is what keeps them unreachable, and deleting published artifacts is not something to do as a side effect of a cleanup. check-flavor.py is gone. It proved which of two builds an artifact was, by a marker compiled into the Dart snapshot, because a clean-named Windows installer once carried the 18+ payload. With one build there is nothing to tell apart.
2026-08-30 02:09:10 +00:00
//
// 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")
Stop choosing an update variant, and drop the 18+ controls Amber ships one build. The manifest hook returned `adult` or `clean` according to the account's nsfwEnabled flag; it now returns `clean` to everyone. The `variant` field itself stays in the response, and that is the important part: every Amber already installed compares it against its own and refuses a mismatch SILENTLY - no error, no prompt, the update simply never appears. Removing the field, or sending anything else, would strand every one of those installs with nothing to see. whoami stops returning nsfwEnabled. It was there in case some future amber-api surface wanted to scope results by it; none was built, and an account flag nobody reads is what a token-introspection endpoint should not be handing out. amber-api's copy goes with it - it was parsed into the user object and never once branched on. The dashboard loses the 18+ account tile, the variant column, the per-flavour error table, the 18+ pill, the per-user enable/disable button and the new-account checkbox. A control that sets a flag nothing reads is worse than no control. Releases are now read as newest-per-platform filtered to variant='clean', rather than newest-per-platform-and-variant. Leftover 18+ rows are still in the collection and would otherwise have been reported as what the family is being served. Those rows and the collection rule that hides them are deliberately left alone: the rule is what keeps them unreachable, and deleting published artifacts is not something to do as a side effect of a cleanup. check-flavor.py is gone. It proved which of two builds an artifact was, by a marker compiled into the Dart snapshot, because a clean-named Windows installer once carried the 18+ payload. With one build there is nothing to tell apart.
2026-08-30 02:09:10 +00:00
// 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=<file token>`.
downloadPath: "/api/files/releases/" + rec.id + "/" + filename,
})
}, $apis.requireAuth("users"))