Fix managed bridge token priority
This commit is contained in:
parent
88fa597c8e
commit
0201ffa676
@ -1075,15 +1075,8 @@ extension AppControllerDesktopRuntimeHelpers on AppController {
|
||||
normalizedHost == bridgeHost &&
|
||||
(bridgePort <= 0 || endpoint.port == bridgePort);
|
||||
if (matchesBridgeEndpoint) {
|
||||
final envToken = runtimeEnvironmentValueInternal('BRIDGE_AUTH_TOKEN');
|
||||
if (envToken != null && envToken.isNotEmpty) {
|
||||
return envToken;
|
||||
}
|
||||
|
||||
final bridgeToken = (await storeInternal.loadAccountManagedSecret(
|
||||
target: kAccountManagedSecretTargetBridgeAuthToken,
|
||||
))?.trim();
|
||||
if (bridgeToken?.isNotEmpty == true) {
|
||||
final bridgeToken = await _resolveManagedBridgeAuthTokenInternal();
|
||||
if (bridgeToken != null && bridgeToken.isNotEmpty) {
|
||||
return bridgeToken;
|
||||
}
|
||||
}
|
||||
@ -1100,20 +1093,27 @@ extension AppControllerDesktopRuntimeHelpers on AppController {
|
||||
return null;
|
||||
}
|
||||
|
||||
final envToken = runtimeEnvironmentValueInternal('BRIDGE_AUTH_TOKEN');
|
||||
if (envToken != null && envToken.isNotEmpty) {
|
||||
return _normalizeAuthorizationHeaderInternal(envToken);
|
||||
}
|
||||
|
||||
final bridgeToken = (await storeInternal.loadAccountManagedSecret(
|
||||
target: kAccountManagedSecretTargetBridgeAuthToken,
|
||||
))?.trim();
|
||||
if (bridgeToken?.isNotEmpty == true) {
|
||||
return _normalizeAuthorizationHeaderInternal(bridgeToken!);
|
||||
final bridgeToken = await _resolveManagedBridgeAuthTokenInternal();
|
||||
if (bridgeToken != null && bridgeToken.isNotEmpty) {
|
||||
return _normalizeAuthorizationHeaderInternal(bridgeToken);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<String?> _resolveManagedBridgeAuthTokenInternal() async {
|
||||
final accountSyncState = settingsControllerInternal.accountSyncState;
|
||||
if (settingsControllerInternal.accountSignedIn &&
|
||||
accountSyncState?.tokenConfigured.bridge == true) {
|
||||
final bridgeToken = (await storeInternal.loadAccountManagedSecret(
|
||||
target: kAccountManagedSecretTargetBridgeAuthToken,
|
||||
))?.trim();
|
||||
return bridgeToken?.isNotEmpty == true ? bridgeToken : null;
|
||||
}
|
||||
|
||||
final envToken = runtimeEnvironmentValueInternal('BRIDGE_AUTH_TOKEN');
|
||||
return envToken?.isNotEmpty == true ? envToken : null;
|
||||
}
|
||||
|
||||
int? gatewayProfileIndexMatchingEndpointInternal(Uri endpoint) {
|
||||
final normalizedHost = endpoint.host.trim().toLowerCase();
|
||||
final normalizedScheme = endpoint.scheme.trim().toLowerCase();
|
||||
|
||||
@ -116,6 +116,16 @@ void main() {
|
||||
enableSecureStorage: false,
|
||||
);
|
||||
await store.initialize();
|
||||
await store.saveAccountSessionToken('session-token');
|
||||
await store.saveAccountSessionSummary(
|
||||
const AccountSessionSummary(
|
||||
userId: 'user-1',
|
||||
email: 'review@svc.plus',
|
||||
name: 'Review User',
|
||||
role: 'reviewer',
|
||||
mfaEnabled: true,
|
||||
),
|
||||
);
|
||||
await store.saveAccountManagedSecret(
|
||||
target: kAccountManagedSecretTargetBridgeAuthToken,
|
||||
value: 'bridge-token',
|
||||
|
||||
@ -1247,6 +1247,72 @@ void main() {
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'desktop bridge auth resolver prefers synced managed bridge token over stale environment token',
|
||||
() async {
|
||||
final storeRoot = await Directory.systemTemp.createTemp(
|
||||
'xworkmate-acp-auth-managed-bridge-env-priority-',
|
||||
);
|
||||
addTearDown(() async {
|
||||
if (await storeRoot.exists()) {
|
||||
try {
|
||||
await storeRoot.delete(recursive: true);
|
||||
} on FileSystemException {
|
||||
// Temp cleanup is best effort here. The controller may still be
|
||||
// releasing files when teardown starts.
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final store = SecureConfigStore(
|
||||
secretRootPathResolver: () async => '${storeRoot.path}/secrets',
|
||||
appDataRootPathResolver: () async => '${storeRoot.path}/app-data',
|
||||
supportRootPathResolver: () async => '${storeRoot.path}/support',
|
||||
enableSecureStorage: false,
|
||||
);
|
||||
await store.initialize();
|
||||
await store.saveAccountSessionToken('session-token');
|
||||
await store.saveAccountSessionSummary(
|
||||
const AccountSessionSummary(
|
||||
userId: 'user-1',
|
||||
email: 'review@svc.plus',
|
||||
name: 'Review User',
|
||||
role: 'reviewer',
|
||||
mfaEnabled: true,
|
||||
),
|
||||
);
|
||||
await store.saveAccountSyncState(
|
||||
AccountSyncState.defaults().copyWith(
|
||||
syncState: 'ready',
|
||||
tokenConfigured: const AccountTokenConfigured(
|
||||
bridge: true,
|
||||
vault: false,
|
||||
),
|
||||
),
|
||||
);
|
||||
await store.saveAccountManagedSecret(
|
||||
target: kAccountManagedSecretTargetBridgeAuthToken,
|
||||
value: 'fresh-bridge-token',
|
||||
);
|
||||
|
||||
final controller = AppController(
|
||||
environmentOverride: const <String, String>{
|
||||
'BRIDGE_AUTH_TOKEN': 'stale-env-token',
|
||||
},
|
||||
store: store,
|
||||
);
|
||||
addTearDown(controller.dispose);
|
||||
await controller.settingsControllerInternal.initialize();
|
||||
|
||||
final header = await controller
|
||||
.resolveGatewayAcpAuthorizationHeaderInternal(
|
||||
Uri.parse('https://xworkmate-bridge.svc.plus/acp/rpc'),
|
||||
);
|
||||
|
||||
expect(header, 'fresh-bridge-token');
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'desktop bridge auth resolver does not fallback to the remote gateway token for bridge ACP',
|
||||
() async {
|
||||
|
||||
@ -388,6 +388,16 @@ void main() {
|
||||
enableSecureStorage: false,
|
||||
);
|
||||
await store.initialize();
|
||||
await store.saveAccountSessionToken('session-token');
|
||||
await store.saveAccountSessionSummary(
|
||||
const AccountSessionSummary(
|
||||
userId: 'user-1',
|
||||
email: 'review@svc.plus',
|
||||
name: 'Review User',
|
||||
role: 'reviewer',
|
||||
mfaEnabled: true,
|
||||
),
|
||||
);
|
||||
await store.saveAccountSyncState(
|
||||
AccountSyncState.defaults().copyWith(
|
||||
syncState: 'ready',
|
||||
|
||||
Loading…
Reference in New Issue
Block a user