🏗️ Build and Test JellyTau / Run Tests (push) Successful in 29m23s
🏗️ Build and Test JellyTau / Supply Chain (push) Successful in 44s
📱 Test APK / Build test APK (push) Successful in 43m47s
Publish Documentation / Build & publish docs to gitea-pages (push) Successful in 6m33s
Traceability Validation / Check Requirement Traces (push) Successful in 14s
🏗️ Build and Test JellyTau / Android Compile Check (push) Successful in 5m21s
Two frontend halves of the version-compatibility work.
The login flow now renders ServerCompatibility. A server below the floor blocks
with a message naming the minimum; a server newer than this build gets a
non-blocking note and proceeds; an unreadable version says nothing at all,
because refusing — or even warning — on a version string we could not parse would
punish the user for a limitation of ours.
The frontend never receives a version number to reason about, only the opaque
verdict, for the same reason it never receives an item-type list. Rust decides
whether the server is usable; the frontend decides only how that reads.
Separately, imageCache.getCachedImageUrl is deleted. It built
${serverUrl}/Items/${itemId}/Images/${imageType} in Svelte — a Jellyfin route in
the presentation layer, which is domain logic by this project's own litmus test
(would it change if Jellyfin changed its API?). check:boundary does not catch it:
the tripwire flags item-type array literals, not route strings.
It was also entirely unused. Nothing outside its own file and test ever called
it; the live path is CachedImage.svelte -> commands.imageGetUrl -> Rust, which
was already correct. So the leak was in dead code and the fix is a deletion
rather than a migration.
One consequence left deliberately unacted: that function was the last
convertFileSrc caller, so the asset-protocol grant narrowed to
$APPDATA/thumbnails/** under DR-198 now has no caller at all. Dropping a
capability grant is a security change that deserves its own commit and its own
testing on Android, not a side effect of deleting dead code. Noted in the file.
TRACES: UR-012, UR-085 | DR-285, DR-286
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
// Presentation of the backend's server-compatibility verdict.
|
|
//
|
|
// The decision is Rust's — see `ServerCompatibility` in `auth/mod.rs`. This file
|
|
// decides only how it *reads*, which is presentation and changes only if the UI
|
|
// is redesigned. Nothing here compares a version number, and nothing here may
|
|
// start to: the backend sends an opaque state precisely so the frontend cannot.
|
|
//
|
|
// TRACES: UR-085 | DR-286
|
|
|
|
import type { ServerCompatibility } from "$lib/api/bindings";
|
|
|
|
export interface CompatibilityNotice {
|
|
/** Blocks going on to the login step. Only a server below the floor does. */
|
|
blocking: boolean;
|
|
tone: "error" | "warning";
|
|
message: string;
|
|
}
|
|
|
|
/**
|
|
* What to show the user about a server's version, or `null` when there is
|
|
* nothing worth saying — which is the common case.
|
|
*/
|
|
export function compatibilityNotice(
|
|
compatibility: ServerCompatibility,
|
|
serverVersion: string,
|
|
): CompatibilityNotice | null {
|
|
switch (compatibility.type) {
|
|
case "supported":
|
|
return null;
|
|
|
|
case "unknownVersion":
|
|
// Not worth interrupting anyone over: the server almost certainly works,
|
|
// and we simply could not read what it called itself.
|
|
return null;
|
|
|
|
case "newerThanKnown":
|
|
return {
|
|
blocking: false,
|
|
tone: "warning",
|
|
message:
|
|
`This server (${serverVersion}) is newer than this version of JellyTau. ` +
|
|
`It should work normally — update the app if anything looks wrong.`,
|
|
};
|
|
|
|
case "tooOld":
|
|
return {
|
|
blocking: true,
|
|
tone: "error",
|
|
message:
|
|
`This server runs Jellyfin ${serverVersion}. JellyTau needs ` +
|
|
`${compatibility.minimum} or newer.`,
|
|
};
|
|
}
|
|
}
|