feat(messenger): implement client-specific event messaging for tech password validation

This commit is contained in:
Jonathan Arndt 2026-08-19 12:38:53 -07:00
parent 12e5ff752d
commit f8738a9053
2 changed files with 45 additions and 2 deletions

View file

@ -11,6 +11,15 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
private readonly ITechPassword _room;
// Captures the id of the client whose /validateTechPassword request is in flight, so the
// TechPasswordValidateResult handler below can reply to only that client instead of
// broadcasting to every connected panel. Relies on ValidateTechPassword firing the event
// synchronously (true for all known ITechPassword implementations); if a future
// implementation validates asynchronously, _pendingClientId will already be null when the
// handler runs and this degrades to the previous broadcast behavior.
private readonly object _pendingLock = new object();
private string _pendingClientId;
public ITechPasswordMessenger(string key, string messagePath, ITechPassword room)
: base(key, messagePath, room as IKeyName)
{
@ -28,7 +37,12 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
var password = content.Value<string>("password");
_room.ValidateTechPassword(password);
lock (_pendingLock)
{
_pendingClientId = id;
_room.ValidateTechPassword(password);
_pendingClientId = null;
}
});
AddAction("/setTechPassword", (id, content) =>
@ -45,12 +59,18 @@ namespace PepperDash.Essentials.AppServer.Messengers
_room.TechPasswordValidateResult += (sender, args) =>
{
string clientId;
lock (_pendingLock)
{
clientId = _pendingClientId;
}
var evt = new ITechPasswordEventMessage
{
IsValid = args.IsValid
};
PostEventMessage(evt, "passwordValidationResult");
PostEventMessage(evt, "passwordValidationResult", clientId);
};
}

View file

@ -405,5 +405,28 @@ namespace PepperDash.Essentials.AppServer.Messengers
});
}
/// <summary>
/// Helper for posting an event message to a single client. A null/empty clientId falls back
/// to the existing broadcast behavior of the other PostEventMessage overloads.
/// </summary>
/// <param name="message"></param>
/// <param name="eventType"></param>
/// <param name="clientId">Client id that will direct the message back to only that client</param>
protected void PostEventMessage(DeviceEventMessageBase message, string eventType, string clientId)
{
message.Key = _device.Key;
message.Name = _device.Name;
message.EventType = eventType;
AppServerController?.SendMessageObject(new MobileControlMessage
{
Type = $"/event{MessagePath}/{eventType}",
ClientId = clientId,
Content = JToken.FromObject(message),
});
}
}
}