fix(profile): avoid PIN prompt on restart

This commit is contained in:
edde746
2026-05-02 01:23:21 +02:00
parent 87aa7d9d81
commit 43242673fb
2 changed files with 11 additions and 24 deletions
+7 -12
View File
@@ -23,8 +23,8 @@ typedef PlexHomePinPrompt = Future<String?> Function(Profile profile, {String? e
typedef ShouldDeferInitialBind = FutureOr<bool> Function(Profile profile);
@visibleForTesting
bool shouldUsePlexHomeTokenCache({required bool preVerified, required bool hasBoundOnce, required bool plexProtected}) {
return preVerified || (!hasBoundOnce && !plexProtected);
bool shouldUsePlexHomeTokenCache({required bool preVerified, required bool hasBoundOnce}) {
return preVerified || !hasBoundOnce;
}
/// Wires the active [Profile] into [MultiServerManager] + [MultiServerProvider].
@@ -285,17 +285,12 @@ class ActiveProfileBinder {
// Fast path: reuse the previously-minted user-token from the
// [ProfileConnection] row for this profile's parent connection.
// Cold-start auto-resume can use cached tokens for unprotected Plex Home
// users only. Protected users must revalidate their PIN unless
// activateProfileWithPin has already minted the token in this same
// activation (pre-verified flag), in which case using the cache once skips
// a redundant second prompt without weakening the security model.
// Cold-start auto-resume can use cached tokens. Once a profile is bound in
// this session, switches bypass the cache so Plex revalidates PINs where
// needed. A just-preverified activation also uses the fresh cache once to
// avoid a redundant second prompt.
final preVerified = consumePlexHomePreVerified(profile.id);
final useCache = shouldUsePlexHomeTokenCache(
preVerified: preVerified,
hasBoundOnce: _hasBoundOnce,
plexProtected: profile.plexProtected,
);
final useCache = shouldUsePlexHomeTokenCache(preVerified: preVerified, hasBoundOnce: _hasBoundOnce);
String? cachedToken;
if (useCache) {
final pc = await profileConnections.get(profile.id, parentId);
+4 -12
View File
@@ -145,24 +145,16 @@ void main() {
});
group('Plex Home token cache policy', () {
test('protected cold start revalidates PIN even when profile selection is not required', () {
expect(shouldUsePlexHomeTokenCache(preVerified: false, hasBoundOnce: false, plexProtected: true), isFalse);
});
test('protected cold start revalidates PIN when profile selection is required', () {
expect(shouldUsePlexHomeTokenCache(preVerified: false, hasBoundOnce: false, plexProtected: true), isFalse);
test('cold start uses cached token instead of forcing PIN revalidation', () {
expect(shouldUsePlexHomeTokenCache(preVerified: false, hasBoundOnce: false), isTrue);
});
test('preverified activation uses cache once regardless of setting', () {
expect(shouldUsePlexHomeTokenCache(preVerified: true, hasBoundOnce: false, plexProtected: true), isTrue);
});
test('unprotected cold start can use cached token', () {
expect(shouldUsePlexHomeTokenCache(preVerified: false, hasBoundOnce: false, plexProtected: false), isTrue);
expect(shouldUsePlexHomeTokenCache(preVerified: true, hasBoundOnce: false), isTrue);
});
test('user-initiated switches bypass cache after first bind', () {
expect(shouldUsePlexHomeTokenCache(preVerified: false, hasBoundOnce: true, plexProtected: false), isFalse);
expect(shouldUsePlexHomeTokenCache(preVerified: false, hasBoundOnce: true), isFalse);
});
test('preverified activation flag is consumed once per profile', () {