diff --git a/lib/runtime/gateway_runtime_core.dart b/lib/runtime/gateway_runtime_core.dart index c03410db..78e1ce3e 100644 --- a/lib/runtime/gateway_runtime_core.dart +++ b/lib/runtime/gateway_runtime_core.dart @@ -145,18 +145,6 @@ class GatewayRuntime extends ChangeNotifier with GatewayRuntimeHelpersInternal { ''); final explicitToken = authTokenOverride.trim(); final explicitPassword = authPasswordOverride.trim(); - final sharedTokenSource = explicitToken.isNotEmpty - ? 'shared:form' - : storedToken.isNotEmpty - ? 'shared:store' - : (setupPayload?.token.trim().isNotEmpty ?? false) - ? 'shared:setup-code' - : null; - final sharedToken = explicitToken.isNotEmpty - ? explicitToken - : storedToken.isNotEmpty - ? storedToken - : (setupPayload?.token.trim() ?? ''); final passwordSource = explicitPassword.isNotEmpty ? 'password:form' : storedPassword.isNotEmpty @@ -177,14 +165,32 @@ class GatewayRuntime extends ChangeNotifier with GatewayRuntimeHelpersInternal { ))?.trim() ?? ''; final explicitDeviceToken = ''; + final canUseStoredDeviceToken = + explicitToken.isEmpty && storedDeviceToken.isNotEmpty; + final sharedTokenSource = explicitToken.isNotEmpty + ? 'shared:form' + : canUseStoredDeviceToken + ? null + : storedToken.isNotEmpty + ? 'shared:store' + : (setupPayload?.token.trim().isNotEmpty ?? false) + ? 'shared:setup-code' + : null; + final sharedToken = explicitToken.isNotEmpty + ? explicitToken + : canUseStoredDeviceToken + ? '' + : storedToken.isNotEmpty + ? storedToken + : (setupPayload?.token.trim() ?? ''); final deviceTokenSource = explicitDeviceToken.isNotEmpty ? 'device:form' - : sharedToken.isEmpty && storedDeviceToken.isNotEmpty + : canUseStoredDeviceToken ? 'device:store' : null; final deviceToken = explicitDeviceToken.isNotEmpty ? explicitDeviceToken - : sharedToken.isEmpty + : canUseStoredDeviceToken ? storedDeviceToken : ''; final authToken = sharedToken.isNotEmpty ? sharedToken : deviceToken; diff --git a/test/runtime/gateway_runtime_suite.dart b/test/runtime/gateway_runtime_suite.dart index 14c5746f..bb0ec716 100644 --- a/test/runtime/gateway_runtime_suite.dart +++ b/test/runtime/gateway_runtime_suite.dart @@ -126,6 +126,50 @@ void main() { }, ); + test( + 'GatewayRuntime prefers a stored operator device token over a stored shared token on reconnect', + () async { + SharedPreferences.setMockInitialValues({}); + final store = createIsolatedTestStore(); + final identityStore = DeviceIdentityStore(store); + final identity = await identityStore.loadOrCreate(); + await store.saveGatewayToken( + 'stored-shared-token', + profileIndex: kGatewayRemoteProfileIndex, + ); + await store.saveDeviceToken( + deviceId: identity.deviceId, + role: 'operator', + token: 'stored-device-token', + ); + final runtime = GatewayRuntime( + store: store, + identityStore: identityStore, + ); + final server = await FakeGatewayRuntimeServerInternal.start(); + addTearDown(runtime.dispose); + addTearDown(server.close); + + await runtime.connectProfile( + GatewayConnectionProfile.defaults().copyWith( + mode: RuntimeConnectionMode.remote, + host: '127.0.0.1', + port: server.port, + tls: false, + useSetupCode: false, + ), + profileIndex: kGatewayRemoteProfileIndex, + ); + + expect(server.connectAuth?['token'], 'stored-device-token'); + expect(server.connectAuth?['deviceToken'], 'stored-device-token'); + expect(runtime.snapshot.connectAuthMode, 'device-token'); + expect(runtime.snapshot.connectAuthSources, const [ + 'device:store', + ]); + }, + ); + test( 'GatewayRuntime persists returned device token and applies go-core session notifications', () async {