Commit 09ad9902 by Mac Stephens

Add client version to mismatch errors, server logs, and connected clients

parent ca97cf69
...@@ -26,5 +26,8 @@ object ApiServerModule: TApiServerModule ...@@ -26,5 +26,8 @@ object ApiServerModule: TApiServerModule
object XDataServer1JWT: TSparkleJwtMiddleware object XDataServer1JWT: TSparkleJwtMiddleware
OnGetSecret = XDataServer1JWTGetSecret OnGetSecret = XDataServer1JWTGetSecret
end end
object XDataServer1Forward: TSparkleForwardMiddleware
OnAcceptProxy = XDataServer1ForwardAcceptProxy
end
end end
end end
...@@ -13,7 +13,7 @@ uses ...@@ -13,7 +13,7 @@ uses
Sparkle.HttpServer.Module, Sparkle.HttpServer.Context, Sparkle.HttpServer.Module, Sparkle.HttpServer.Context,
Sparkle.Comp.CompressMiddleware, Sparkle.Comp.CorsMiddleware, Sparkle.Comp.CompressMiddleware, Sparkle.Comp.CorsMiddleware,
Sparkle.Comp.GenericMiddleware, Aurelius.Drivers.UniDac, UniProvider, Sparkle.Comp.GenericMiddleware, Aurelius.Drivers.UniDac, UniProvider,
Data.DB, DBAccess, Uni; Data.DB, DBAccess, Uni, Sparkle.Comp.ForwardMiddleware;
type type
TApiServerModule = class(TDataModule) TApiServerModule = class(TDataModule)
...@@ -23,9 +23,12 @@ type ...@@ -23,9 +23,12 @@ type
XDataServer1CORS: TSparkleCorsMiddleware; XDataServer1CORS: TSparkleCorsMiddleware;
XDataServer1Compress: TSparkleCompressMiddleware; XDataServer1Compress: TSparkleCompressMiddleware;
XDataServer1JWT: TSparkleJwtMiddleware; XDataServer1JWT: TSparkleJwtMiddleware;
XDataServer1Forward: TSparkleForwardMiddleware;
procedure XDataServer1LoggingMiddlewareCreate(Sender: TObject; procedure XDataServer1LoggingMiddlewareCreate(Sender: TObject;
var Middleware: IHttpServerMiddleware); var Middleware: IHttpServerMiddleware);
procedure XDataServer1JWTGetSecret(Sender: TObject; var Secret: string); procedure XDataServer1JWTGetSecret(Sender: TObject; var Secret: string);
procedure XDataServer1ForwardAcceptProxy(Sender: TObject;
const Value: string; var Accept: Boolean);
private private
{ Private declarations } { Private declarations }
public public
...@@ -89,6 +92,12 @@ begin ...@@ -89,6 +92,12 @@ begin
Middleware := TLoggingMiddleware.Create(Logger); Middleware := TLoggingMiddleware.Create(Logger);
end; end;
procedure TApiServerModule.XDataServer1ForwardAcceptProxy(Sender: TObject;
const Value: string; var Accept: Boolean);
begin
Accept := True;
end;
procedure TApiServerModule.XDataServer1JWTGetSecret(Sender: TObject; procedure TApiServerModule.XDataServer1JWTGetSecret(Sender: TObject;
var Secret: string); var Secret: string);
begin begin
......
...@@ -168,7 +168,8 @@ var ...@@ -168,7 +168,8 @@ var
iniFile: TIniFile; iniFile: TIniFile;
webClientVersion: string; webClientVersion: string;
begin begin
Logger.Log(3, 'AuthService.VerifyVersion called'); Logger.Log(1, Format(
'Client version check started: client="%s"', [ClientVersion]));
Result := TJSONObject.Create; Result := TJSONObject.Create;
TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result); TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
...@@ -180,20 +181,26 @@ begin ...@@ -180,20 +181,26 @@ begin
if webClientVersion = '' then if webClientVersion = '' then
begin begin
Logger.Log(2, 'AuthService.VerifyVersion: webClientVersion not configured'); Logger.Log(2, Format(
'Client version check failed: client="%s", required version is not configured',
[ClientVersion]));
Result.AddPair('error', 'webClientVersion is not configured.'); Result.AddPair('error', 'webClientVersion is not configured.');
Exit; Exit;
end; end;
if clientVersion <> webClientVersion then if clientVersion <> webClientVersion then
begin begin
Logger.Log(2, 'AuthService.VerifyVersion: client version mismatch'); Logger.Log(2, Format(
'Client version check failed: client="%s", required="%s"',
[ClientVersion, webClientVersion]));
Result.AddPair('error', Result.AddPair('error',
'Your browser is running an old version of the app.' + sLineBreak + 'Your browser is running an old version of the app.' + sLineBreak +
'Please click below to reload.'); 'Please click below to reload.');
end end
else else
Logger.Log(3, 'AuthService.VerifyVersion: version check passed'); Logger.Log(1, Format(
'Client version check succeeded: client="%s", required="%s"',
[ClientVersion, webClientVersion]));
finally finally
iniFile.Free; iniFile.Free;
end; end;
......
...@@ -68,6 +68,13 @@ object FMain: TFMain ...@@ -68,6 +68,13 @@ object FMain: TFMain
end end
item item
Expanded = False Expanded = False
FieldName = 'ClientVersion'
Title.Caption = 'Version'
Width = 80
Visible = True
end
item
Expanded = False
FieldName = 'ConnectedAt' FieldName = 'ConnectedAt'
Width = 150 Width = 150
Visible = True Visible = True
...@@ -162,6 +169,11 @@ object FMain: TFMain ...@@ -162,6 +169,11 @@ object FMain: TFMain
Size = 30 Size = 30
end end
item item
Name = 'ClientVersion'
DataType = ftString
Size = 20
end
item
Name = 'ConnectedAt' Name = 'ConnectedAt'
DataType = ftDateTime DataType = ftDateTime
end> end>
......
...@@ -241,6 +241,7 @@ begin ...@@ -241,6 +241,7 @@ begin
tblConnectedClients.Append; tblConnectedClients.Append;
tblConnectedClients.FieldByName('ConnectionId').AsString := client.ConnectionId; tblConnectedClients.FieldByName('ConnectionId').AsString := client.ConnectionId;
tblConnectedClients.FieldByName('UserId').AsString := client.UserId; tblConnectedClients.FieldByName('UserId').AsString := client.UserId;
tblConnectedClients.FieldByName('ClientVersion').AsString := client.ClientVersion;
tblConnectedClients.FieldByName('ConnectedAt').AsDateTime := client.ConnectedAt; tblConnectedClients.FieldByName('ConnectedAt').AsDateTime := client.ConnectedAt;
tblConnectedClients.Post; tblConnectedClients.Post;
end; end;
......
...@@ -20,6 +20,7 @@ type ...@@ -20,6 +20,7 @@ type
TConnectedClientSnapshot = record TConnectedClientSnapshot = record
ConnectionId: string; ConnectionId: string;
UserId: string; UserId: string;
ClientVersion: string;
ConnectedAt: TDateTime; ConnectedAt: TDateTime;
end; end;
...@@ -27,6 +28,7 @@ type ...@@ -27,6 +28,7 @@ type
private private
FConnectionId: string; FConnectionId: string;
FUserId: string; FUserId: string;
FClientVersion: string;
FConnectedAt: TDateTime; FConnectedAt: TDateTime;
FLastSeenAt: TDateTime; FLastSeenAt: TDateTime;
FHeartbeatSeen: Boolean; FHeartbeatSeen: Boolean;
...@@ -35,6 +37,7 @@ type ...@@ -35,6 +37,7 @@ type
public public
property ConnectionId: string read FConnectionId write FConnectionId; property ConnectionId: string read FConnectionId write FConnectionId;
property UserId: string read FUserId write FUserId; property UserId: string read FUserId write FUserId;
property ClientVersion: string read FClientVersion write FClientVersion;
property ConnectedAt: TDateTime read FConnectedAt write FConnectedAt; property ConnectedAt: TDateTime read FConnectedAt write FConnectedAt;
property LastSeenAt: TDateTime read FLastSeenAt write FLastSeenAt; property LastSeenAt: TDateTime read FLastSeenAt write FLastSeenAt;
property HeartbeatSeen: Boolean read FHeartbeatSeen write FHeartbeatSeen; property HeartbeatSeen: Boolean read FHeartbeatSeen write FHeartbeatSeen;
...@@ -330,6 +333,7 @@ var ...@@ -330,6 +333,7 @@ var
json: TJSONValue; json: TJSONValue;
messageType: string; messageType: string;
userId: string; userId: string;
clientVersion: string;
connectionId: string; connectionId: string;
client: TConnectedClient; client: TConnectedClient;
response: TJSONObject; response: TJSONObject;
...@@ -350,6 +354,10 @@ begin ...@@ -350,6 +354,10 @@ begin
(not json.TryGetValue<string>('userId', userId)) then (not json.TryGetValue<string>('userId', userId)) then
Exit; Exit;
clientVersion := '';
if SameText(messageType, 'identify') then
json.TryGetValue<string>('clientVersion', clientVersion);
client := TConnectedClient(TTMSFNCWebSocketServerConnection(AConnection).UserData); client := TConnectedClient(TTMSFNCWebSocketServerConnection(AConnection).UserData);
if not Assigned(client) then if not Assigned(client) then
...@@ -364,7 +372,10 @@ begin ...@@ -364,7 +372,10 @@ begin
connectionId := client.ConnectionId; connectionId := client.ConnectionId;
if SameText(messageType, 'identify') then if SameText(messageType, 'identify') then
client.UserId := userId begin
client.UserId := userId;
client.ClientVersion := clientVersion;
end
else else
client.HeartbeatSeen := True; client.HeartbeatSeen := True;
finally finally
...@@ -373,7 +384,9 @@ begin ...@@ -373,7 +384,9 @@ begin
if SameText(messageType, 'identify') then if SameText(messageType, 'identify') then
begin begin
Logger.Log(1, 'WebSocket client identified: ' + connectionId + ' - ' + userId); Logger.Log(1, Format(
'WebSocket client identified: %s - %s - version %s',
[connectionId, userId, clientVersion]));
NotifyClientsChanged; NotifyClientsChanged;
end end
else else
...@@ -443,6 +456,7 @@ begin ...@@ -443,6 +456,7 @@ begin
begin begin
Result[i].ConnectionId := FClients[i].ConnectionId; Result[i].ConnectionId := FClients[i].ConnectionId;
Result[i].UserId := FClients[i].UserId; Result[i].UserId := FClients[i].UserId;
Result[i].ClientVersion := FClients[i].ClientVersion;
Result[i].ConnectedAt := FClients[i].ConnectedAt; Result[i].ConnectedAt := FClients[i].ConnectedAt;
end; end;
finally finally
......
...@@ -110,7 +110,9 @@ begin ...@@ -110,7 +110,9 @@ begin
error := ''; error := '';
if error <> '' then if error <> '' then
TFViewErrorPage.Display(error) TFViewErrorPage.Display(
error + sLineBreak + sLineBreak +
'Current client version: v' + clientVersion)
else else
SuccessProc; SuccessProc;
end, end,
......
...@@ -120,6 +120,9 @@ var ...@@ -120,6 +120,9 @@ var
implementation implementation
uses
ConnectionModule;
{%CLASSGROUP 'Vcl.Controls.TControl'} {%CLASSGROUP 'Vcl.Controls.TControl'}
{$R *.dfm} {$R *.dfm}
...@@ -619,6 +622,7 @@ begin ...@@ -619,6 +622,7 @@ begin
msg := TJSObject.new; msg := TJSObject.new;
msg['message'] := 'identify'; msg['message'] := 'identify';
msg['userId'] := userId; msg['userId'] := userId;
msg['clientVersion'] := TDMConnection.clientVersion;
EMiMobileWebSocketClient.Send(TJSJSON.stringify(msg)); EMiMobileWebSocketClient.Send(TJSJSON.stringify(msg));
except except
on E: Exception do on E: Exception do
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment