fix(notifications): validate Twilio AccountSid format at save — closes the un-escaped URI interpolation door
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
This commit is contained in:
@@ -32,7 +32,7 @@ public class SmsConfigurationPageTests : BunitContext
|
||||
private const string SecretToken = "super-secret-auth-token";
|
||||
|
||||
private static SmsConfiguration Sample() =>
|
||||
new("ACtest_account_sid", "+15551234567")
|
||||
new("ACcccccccccccccccccccccccccccccccc", "+15551234567")
|
||||
{
|
||||
Id = 1,
|
||||
MessagingServiceSid = "MGtest_messaging_service",
|
||||
@@ -63,7 +63,7 @@ public class SmsConfigurationPageTests : BunitContext
|
||||
cut.WaitForAssertion(() =>
|
||||
{
|
||||
// Config row fields render.
|
||||
Assert.Contains("ACtest_account_sid", cut.Markup);
|
||||
Assert.Contains("ACcccccccccccccccccccccccccccccccc", cut.Markup);
|
||||
Assert.Contains("+15551234567", cut.Markup);
|
||||
Assert.Contains("MGtest_messaging_service", cut.Markup);
|
||||
// Auth Token shows a presence indicator only — never the value.
|
||||
@@ -81,7 +81,7 @@ public class SmsConfigurationPageTests : BunitContext
|
||||
WireAuth();
|
||||
|
||||
var cut = Render<SmsConfigurationPage>();
|
||||
cut.WaitForState(() => cut.Markup.Contains("ACtest_account_sid"));
|
||||
cut.WaitForState(() => cut.Markup.Contains("ACcccccccccccccccccccccccccccccccc"));
|
||||
|
||||
cut.FindAll("button").First(b => b.TextContent.Contains("Edit")).Click();
|
||||
|
||||
@@ -109,7 +109,7 @@ public class SmsConfigurationPageTests : BunitContext
|
||||
|
||||
// Re-query between each Change(): two-way binding re-renders the form and
|
||||
// invalidates previously found element references.
|
||||
cut.FindAll("input[type=text]")[0].Change("ACnew_account"); // Account SID
|
||||
cut.FindAll("input[type=text]")[0].Change("ACdddddddddddddddddddddddddddddddd"); // Account SID
|
||||
cut.FindAll("input[type=text]")[1].Change("+15559876543"); // From Number
|
||||
cut.FindAll("input[type=password]").First().Change("new-token");
|
||||
|
||||
@@ -119,7 +119,7 @@ public class SmsConfigurationPageTests : BunitContext
|
||||
{
|
||||
repo.Received().AddSmsConfigurationAsync(
|
||||
Arg.Is<SmsConfiguration>(c =>
|
||||
c.AccountSid == "ACnew_account" &&
|
||||
c.AccountSid == "ACdddddddddddddddddddddddddddddddd" &&
|
||||
c.FromNumber == "+15559876543" &&
|
||||
c.AuthToken == "new-token"));
|
||||
repo.Received().SaveChangesAsync();
|
||||
@@ -141,7 +141,7 @@ public class SmsConfigurationPageTests : BunitContext
|
||||
cut.FindAll("button").First(b => b.TextContent.Contains("Add SMS configuration")).Click();
|
||||
|
||||
// Account SID + Messaging Service SID, leaving From Number (index 1) blank.
|
||||
cut.FindAll("input[type=text]")[0].Change("ACmsg_account"); // Account SID
|
||||
cut.FindAll("input[type=text]")[0].Change("ACeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"); // Account SID
|
||||
cut.FindAll("input[type=text]")[2].Change("MGmessaging_service"); // Messaging Service SID
|
||||
cut.FindAll("input[type=password]").First().Change("new-token");
|
||||
|
||||
@@ -151,7 +151,7 @@ public class SmsConfigurationPageTests : BunitContext
|
||||
{
|
||||
repo.Received().AddSmsConfigurationAsync(
|
||||
Arg.Is<SmsConfiguration>(c =>
|
||||
c.AccountSid == "ACmsg_account" &&
|
||||
c.AccountSid == "ACeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" &&
|
||||
c.FromNumber == null &&
|
||||
c.MessagingServiceSid == "MGmessaging_service" &&
|
||||
c.AuthToken == "new-token"));
|
||||
@@ -168,7 +168,7 @@ public class SmsConfigurationPageTests : BunitContext
|
||||
WireAuth();
|
||||
|
||||
var cut = Render<SmsConfigurationPage>();
|
||||
cut.WaitForState(() => cut.Markup.Contains("ACtest_account_sid"));
|
||||
cut.WaitForState(() => cut.Markup.Contains("ACcccccccccccccccccccccccccccccccc"));
|
||||
|
||||
cut.FindAll("button").First(b => b.TextContent.Contains("Edit")).Click();
|
||||
// Leave the (blank) Auth Token input untouched, then save.
|
||||
@@ -193,7 +193,7 @@ public class SmsConfigurationPageTests : BunitContext
|
||||
WireAuth();
|
||||
|
||||
var cut = Render<SmsConfigurationPage>();
|
||||
cut.WaitForState(() => cut.Markup.Contains("ACtest_account_sid"));
|
||||
cut.WaitForState(() => cut.Markup.Contains("ACcccccccccccccccccccccccccccccccc"));
|
||||
|
||||
cut.FindAll("button").First(b => b.TextContent.Contains("Edit")).Click();
|
||||
cut.FindAll("input[type=password]").First().Change("rotated-token");
|
||||
|
||||
Reference in New Issue
Block a user