Localize connection-string login validation and connectivity messages

Move the hardcoded SQL/Tables/Gremlin connection-string login strings into en/Resources.json and reference them via the type-safe Keys object (t(Keys.connectExplorer.errors.*)).
This commit is contained in:
Asier Isayas
2026-08-11 11:38:15 -04:00
parent 6a524be12f
commit 2e2763f80f
3 changed files with 25 additions and 12 deletions
+14 -1
View File
@@ -1174,5 +1174,18 @@
"retryConsoleMessage": "Data transfer job \"{{jobName}}\" in progress, total count: {{totalCount}}, processed count: {{processedCount}}" "retryConsoleMessage": "Data transfer job \"{{jobName}}\" in progress, total count: {{totalCount}}, processed count: {{processedCount}}"
} }
} }
},
"connectExplorer": {
"errors": {
"connectionStringMissing": "Connection string is missing.",
"accountNameMissing": "Account name is missing from the connection string.",
"endpointHostMissing": "Endpoint host is missing from the connection string.",
"endpointHostNotAllowed": "Endpoint host is not allowed.",
"accountNameMismatch": "Account name does not match the endpoint host.",
"accountKeyMissing": "Account key is missing from the connection string.",
"connectivityInvalid": "Unable to connect to the account with the provided connection string.",
"connectivityUnreachable": "Unable to connect to the account. Please verify the connection string is correct and that the account is reachable.",
"connectFailed": "Failed to connect using the provided connection string. Please verify it is correct and try again."
}
} }
} }
@@ -1,5 +1,6 @@
import { useBoolean } from "@fluentui/react-hooks"; import { useBoolean } from "@fluentui/react-hooks";
import { client } from "Common/CosmosClient"; import { client } from "Common/CosmosClient";
import { Keys, t } from "Localization";
import { updateUserContext, userContext } from "UserContext"; import { updateUserContext, userContext } from "UserContext";
import * as React from "react"; import * as React from "react";
import ConnectImage from "../../../../images/HdeConnectCosmosDB.svg"; import ConnectImage from "../../../../images/HdeConnectCosmosDB.svg";
@@ -60,7 +61,7 @@ export const validateDirectConnectionStringConnectivity = async (
): Promise<string | undefined> => { ): Promise<string | undefined> => {
const masterKey = extractAccountKeyFromConnectionString(connectionString); const masterKey = extractAccountKeyFromConnectionString(connectionString);
if (!metadata?.documentEndpoint || !masterKey) { if (!metadata?.documentEndpoint || !masterKey) {
return "Unable to connect to the account with the provided connection string."; return t(Keys.connectExplorer.errors.connectivityInvalid);
} }
// Configure the client the same way the Data Explorer will, then issue a lightweight authenticated // Configure the client the same way the Data Explorer will, then issue a lightweight authenticated
@@ -76,7 +77,7 @@ export const validateDirectConnectionStringConnectivity = async (
await client().getDatabaseAccount(); await client().getDatabaseAccount();
return undefined; return undefined;
} catch { } catch {
return "Unable to connect to the account. Please verify the connection string is correct and that the account is reachable."; return t(Keys.connectExplorer.errors.connectivityUnreachable);
} }
}; };
@@ -148,9 +149,7 @@ export const ConnectExplorer: React.FunctionComponent<Props> = ({
setEncryptedToken(encryptedToken); setEncryptedToken(encryptedToken);
setAuthType(AuthType.ConnectionString); setAuthType(AuthType.ConnectionString);
} catch (error) { } catch (error) {
setErrorMessage( setErrorMessage(t(Keys.connectExplorer.errors.connectFailed));
"Failed to connect using the provided connection string. Please verify it is correct and try again.",
);
} }
}} }}
> >
+7 -6
View File
@@ -1,5 +1,6 @@
import { AccountKind, CapabilityNames } from "../../Common/Constants"; import { AccountKind, CapabilityNames } from "../../Common/Constants";
import { AccessInputMetadata, ApiKind } from "../../Contracts/DataModels"; import { AccessInputMetadata, ApiKind } from "../../Contracts/DataModels";
import { Keys, t } from "../../Localization";
import { DefaultExperienceUtility } from "../../Shared/DefaultExperienceUtility"; import { DefaultExperienceUtility } from "../../Shared/DefaultExperienceUtility";
import { userContext } from "../../UserContext"; import { userContext } from "../../UserContext";
@@ -133,16 +134,16 @@ export function validateDirectConnectionStringLogin(
metadata: AccessInputMetadata, metadata: AccessInputMetadata,
): string | undefined { ): string | undefined {
if (!connectionString) { if (!connectionString) {
return "Connection string is missing."; return t(Keys.connectExplorer.errors.connectionStringMissing);
} }
if (!metadata || !metadata.accountName) { if (!metadata || !metadata.accountName) {
return "Account name is missing from the connection string."; return t(Keys.connectExplorer.errors.accountNameMissing);
} }
const host = extractEndpointHostFromConnectionString(connectionString); const host = extractEndpointHostFromConnectionString(connectionString);
if (!host) { if (!host) {
return "Endpoint host is missing from the connection string."; return t(Keys.connectExplorer.errors.endpointHostMissing);
} }
// The host must belong to one of the allowlisted runtime endpoint zones. // The host must belong to one of the allowlisted runtime endpoint zones.
@@ -150,17 +151,17 @@ export function validateDirectConnectionStringLogin(
host.toLowerCase().endsWith(`.${zone.toLowerCase()}`), host.toLowerCase().endsWith(`.${zone.toLowerCase()}`),
); );
if (!isAllowlistedHost) { if (!isAllowlistedHost) {
return "Endpoint host is not allowed."; return t(Keys.connectExplorer.errors.endpointHostNotAllowed);
} }
// The account name must be the first DNS label of the host. // The account name must be the first DNS label of the host.
if (host.split(".")[0].toLowerCase() !== metadata.accountName.toLowerCase()) { if (host.split(".")[0].toLowerCase() !== metadata.accountName.toLowerCase()) {
return "Account name does not match the endpoint host."; return t(Keys.connectExplorer.errors.accountNameMismatch);
} }
// Direct login signs requests with the account key, so it must be present in the connection string. // Direct login signs requests with the account key, so it must be present in the connection string.
if (!extractAccountKeyFromConnectionString(connectionString)) { if (!extractAccountKeyFromConnectionString(connectionString)) {
return "Account key is missing from the connection string."; return t(Keys.connectExplorer.errors.accountKeyMissing);
} }
return undefined; return undefined;