Fix repeated gateway pairing loop

This commit is contained in:
Haitao Pan 2026-04-04 15:35:57 +08:00
parent 8a6366687c
commit 6889ba91b2
2 changed files with 64 additions and 14 deletions

View File

@ -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;

View File

@ -126,6 +126,50 @@ void main() {
},
);
test(
'GatewayRuntime prefers a stored operator device token over a stored shared token on reconnect',
() async {
SharedPreferences.setMockInitialValues(<String, Object>{});
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 <String>[
'device:store',
]);
},
);
test(
'GatewayRuntime persists returned device token and applies go-core session notifications',
() async {