feat(train): the Jellyfin token in Train's own store, sealed by the Keystore (ADR 0030, D52)
The token moves from flutter_secure_storage into JellyfinTokens.kt: a file per person in the no-backup folder, sealed with AES-GCM under a key of Android's Keystore, the person's ID as associated data, so that the music job to come can read it as the app does. A token the keyring held is moved over as it is first read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
64366d5420
commit
6bde74f0ba
1 changed files with 342 additions and 18 deletions
|
|
@ -1310,6 +1310,44 @@ Strava. What was found, 27 Oct:
|
|||
ride starts with), and GPS's speed is ignored while the wheel sent within 5 s; a
|
||||
ride without a circumference (no speed sensor) pauses by GPS as before. Not tried
|
||||
with a real sensor or Health Connect.
|
||||
- **D52 Music kept in the background, and smaller copies** (recommended, the
|
||||
developer's; 29 Oct; step 14, what D47's 10b left open):
|
||||
- **Downloads by a WorkManager job of Train's, in Kotlin, on the app's list** (14b;
|
||||
over the job also reading the marked playlists, which writes part of the Jellyfin
|
||||
client a second time; over the workmanager plugin running today's Dart in a
|
||||
background engine, a new plugin and a whole engine for each run; over Android's
|
||||
DownloadManager, which keeps the token in the system's download database): the
|
||||
app, as it opens and resumes, reads the playlists as before, deletes what they no
|
||||
longer hold and writes which tracks are missing; the job downloads those and works
|
||||
out their tempo, a line each in the person's music folder, which the app takes in
|
||||
as it opens and, while open, as each line comes. A playlist changed on the server
|
||||
while the app is closed is noticed as it opens. The job does every download, the
|
||||
open app's too, so that one code path runs and two never fetch the same track.
|
||||
- **The token in one store of Train's, in Kotlin** (14a; over a second copy beside
|
||||
flutter_secure_storage's, two to keep in step, and over the job reading that
|
||||
plugin's own files, whose format has changed between versions): a file per person
|
||||
in the no-backup folder, sealed with AES-GCM under a key in Android's Keystore
|
||||
that can't be exported; the app reads it over the music channel; a token kept
|
||||
before is moved over once and deleted from the keyring.
|
||||
- **When**: every 6 hours and once whenever the list changes, on an unmetered network,
|
||||
with the battery and the storage not low (over daily while charging, which leaves
|
||||
a new playlist waiting overnight, and over every 12 hours).
|
||||
- **Smaller copies** (14c): the music screen chooses *As they are* or *Smaller*, the
|
||||
default *Smaller*: files above 256 kbps (FLAC and other lossless) are transcoded by
|
||||
Jellyfin to Opus at 128 kbps in WebM, which Android's extractor and decoder read
|
||||
on every version Train runs on; MP3s and AACs come as they are (over *As they are*
|
||||
by default, and over always transcoding, which loses an MP3's quality twice and
|
||||
has the server's processor do every track). Switching downloads the tracks again;
|
||||
a file is kept until its new copy is whole, its tempo kept.
|
||||
- Built: 14a. `JellyfinTokens.kt` keeps each person's token in the no-backup
|
||||
folder's `jellyfin/`, a file named by their ID: a version byte, the IV the
|
||||
Keystore makes and the token sealed with AES-GCM under `train_jellyfin`, a
|
||||
256-bit key of Android's Keystore made once, the person's ID its associated data;
|
||||
a file that doesn't open is deleted and counts as none, so the person signs in
|
||||
again. Tested on the JVM with a software key. `AndroidJellyfinTokenStore` asks it
|
||||
over the music channel and moves a token the keyring holds under
|
||||
`train_jellyfin:` over as it is first read; keeping one, and forgetting others',
|
||||
clears the keyring's too.
|
||||
|
||||
## Consequences
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue