fix(google-meet): report blank Twilio setup credentials as missing (#109674)

* fix(google-meet): reject blank Twilio setup credentials

* fix: centralize Google Meet voice setup values

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
Wynne668
2026-07-17 01:54:43 -07:00
committed by GitHub
co-authored by Peter Steinberger
parent 07a36f6eda
commit 68c4cb31d2
2 changed files with 125 additions and 7 deletions
+109
View File
@@ -376,6 +376,57 @@ function requireSetupCheck(checks: unknown[] | undefined, id: string): Record<st
return check;
}
type TwilioSetupCredentials = {
accountSid: string;
authToken: string;
fromNumber: string;
};
async function getTwilioVoiceCallCredentialsCheck(params: {
env: TwilioSetupCredentials;
configured?: Partial<TwilioSetupCredentials>;
}): Promise<Record<string, unknown>> {
vi.stubEnv("TWILIO_ACCOUNT_SID", params.env.accountSid);
vi.stubEnv("TWILIO_AUTH_TOKEN", params.env.authToken);
vi.stubEnv("TWILIO_FROM_NUMBER", params.env.fromNumber);
const { tools } = setup(
{
defaultTransport: "chrome-node",
chromeNode: { node: "parallels-macos" },
},
{
fullConfig: {
plugins: {
allow: ["google-meet", "voice-call"],
entries: {
"voice-call": {
enabled: true,
config: {
provider: "twilio",
publicUrl: "https://voice.example.com/voice/webhook",
fromNumber: params.configured?.fromNumber,
twilio: {
accountSid: params.configured?.accountSid,
authToken: params.configured?.authToken,
},
},
},
},
},
},
},
);
const tool = tools[0] as {
execute: (
id: string,
params: unknown,
) => Promise<{ details: { checks?: unknown[] } }>;
};
const result = await tool.execute("id", { action: "setup_status" });
return requireSetupCheck(result.details.checks, "twilio-voice-call-credentials");
}
function requireFetchGuardCall(auditContext: string): Record<string, unknown> {
const call = (
fetchGuardMocks.fetchWithSsrFGuard.mock.calls as Array<[Record<string, unknown>]>
@@ -2604,6 +2655,64 @@ describe("google-meet plugin", () => {
expect(requireSetupCheck(result.details.checks, "twilio-voice-call-webhook").ok).toBe(true);
});
it.each([
{
label: "environment account SID",
env: { accountSid: " ", authToken: "test-auth-token", fromNumber: "+15550001234" },
},
{
label: "environment auth token",
env: { accountSid: "AC123", authToken: " ", fromNumber: "+15550001234" },
},
{
label: "environment from number",
env: { accountSid: "AC123", authToken: "test-auth-token", fromNumber: " " },
},
{
label: "configured account SID",
env: { accountSid: "", authToken: "", fromNumber: "" },
configured: { accountSid: " ", authToken: "test-auth-token", fromNumber: "+15550001234" },
},
{
label: "configured auth token",
env: { accountSid: "", authToken: "", fromNumber: "" },
configured: { accountSid: "AC123", authToken: " ", fromNumber: "+15550001234" },
},
{
label: "configured from number",
env: { accountSid: "", authToken: "", fromNumber: "" },
configured: { accountSid: "AC123", authToken: "test-auth-token", fromNumber: " " },
},
])("reports a blank $label as missing", async ({ env, configured }) => {
const check = await getTwilioVoiceCallCredentialsCheck({ env, configured });
expect(check.ok).toBe(false);
});
it.each([
{
label: "environment",
env: {
accountSid: " AC123 ",
authToken: " test-auth-token ",
fromNumber: " +15550001234 ",
},
},
{
label: "configuration",
env: { accountSid: "", authToken: "", fromNumber: "" },
configured: {
accountSid: " AC123 ",
authToken: " test-auth-token ",
fromNumber: " +15550001234 ",
},
},
])("accepts padded Twilio credentials from $label", async ({ env, configured }) => {
const check = await getTwilioVoiceCallCredentialsCheck({ env, configured });
expect(check.ok).toBe(true);
});
it("reports missing voice-call wiring for explicit Twilio transport", async () => {
vi.stubEnv("TWILIO_ACCOUNT_SID", "");
vi.stubEnv("TWILIO_AUTH_TOKEN", "");
+16 -7
View File
@@ -36,6 +36,10 @@ function isProviderUnreachableWebhookUrl(webhookUrl: string): boolean {
}
}
function resolveVoiceCallSetupValue(configured: unknown, fallback: unknown): string | undefined {
return normalizeOptionalString(configured) ?? normalizeOptionalString(fallback);
}
function getVoiceCallWebhookExposureCheck(voiceCallConfig: Record<string, unknown>): SetupCheck {
const publicUrl = normalizeOptionalString(voiceCallConfig.publicUrl);
const tunnel = asRecord(voiceCallConfig.tunnel);
@@ -240,14 +244,19 @@ export function getGoogleMeetSetupStatus(
const provider = normalizeOptionalString(voiceCallConfig.provider) ?? "twilio";
if (provider === "twilio") {
const accountSid = normalizeOptionalString(voiceCallTwilioConfig.accountSid);
const authToken = normalizeOptionalString(voiceCallTwilioConfig.authToken);
const fromNumber = normalizeOptionalString(voiceCallConfig.fromNumber);
const twilioReady = Boolean(
(accountSid || env.TWILIO_ACCOUNT_SID) &&
(authToken || env.TWILIO_AUTH_TOKEN) &&
(fromNumber || env.TWILIO_FROM_NUMBER),
const accountSid = resolveVoiceCallSetupValue(
voiceCallTwilioConfig.accountSid,
env.TWILIO_ACCOUNT_SID,
);
const authToken = resolveVoiceCallSetupValue(
voiceCallTwilioConfig.authToken,
env.TWILIO_AUTH_TOKEN,
);
const fromNumber = resolveVoiceCallSetupValue(
voiceCallConfig.fromNumber,
env.TWILIO_FROM_NUMBER,
);
const twilioReady = Boolean(accountSid && authToken && fromNumber);
checks.push({
id: "twilio-voice-call-credentials",
ok: twilioReady,