Commit 4a520774 by Michael Brachmann

unrevoke a revoked device

parent 8fc67879
...@@ -34,6 +34,7 @@ type ...@@ -34,6 +34,7 @@ type
// Device management — requires valid JWT; caller must also have user_admin = true // Device management — requires valid JWT; caller must also have user_admin = true
[HttpGet] function GetDeviceList: TDeviceList; [HttpGet] function GetDeviceList: TDeviceList;
function RevokeDevice(const CredentialId: string): TJSONObject; function RevokeDevice(const CredentialId: string): TJSONObject;
function UnrevokeDevice(const CredentialId: string): TJSONObject;
function AddPendingDevice(const DeviceName, PhoneNumber: string): TJSONObject; function AddPendingDevice(const DeviceName, PhoneNumber: string): TJSONObject;
function DeletePendingDevice(const PhoneNumber: string): TJSONObject; function DeletePendingDevice(const PhoneNumber: string): TJSONObject;
function SendAppLink(const PhoneNumber: string): TJSONObject; function SendAppLink(const PhoneNumber: string): TJSONObject;
......
...@@ -40,6 +40,7 @@ type ...@@ -40,6 +40,7 @@ type
function GetComplaintMemos(const CfsId: string): TJSONObject; function GetComplaintMemos(const CfsId: string): TJSONObject;
function GetDeviceList: TDeviceList; function GetDeviceList: TDeviceList;
function RevokeDevice(const CredentialId: string): TJSONObject; function RevokeDevice(const CredentialId: string): TJSONObject;
function UnrevokeDevice(const CredentialId: string): TJSONObject;
function AddPendingDevice(const DeviceName, PhoneNumber: string): TJSONObject; function AddPendingDevice(const DeviceName, PhoneNumber: string): TJSONObject;
function DeletePendingDevice(const PhoneNumber: string): TJSONObject; function DeletePendingDevice(const PhoneNumber: string): TJSONObject;
function SendAppLink(const PhoneNumber: string): TJSONObject; function SendAppLink(const PhoneNumber: string): TJSONObject;
...@@ -1478,6 +1479,57 @@ begin ...@@ -1478,6 +1479,57 @@ begin
end; end;
function TApiService.UnrevokeDevice(const CredentialId: string): TJSONObject;
var
conn: TUniConnection;
q: TUniQuery;
begin
RequireAdmin;
Result := TJSONObject.Create;
TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
if Trim(CredentialId) = '' then
begin
Result.AddPair('status', 'error');
Result.AddPair('message', 'CredentialId is required.');
Exit;
end;
Logger.Log(2, 'TApiService.UnrevokeDevice - credId: ' + Copy(CredentialId, 1, 20));
conn := OpenLemsConnection;
try
q := TUniQuery.Create(nil);
try
q.Connection := conn;
q.SQL.Text :=
'UPDATE lems.device_registrations ' +
'SET revoked_at = NULL, revoked_by = NULL, status = ''active'' ' +
'WHERE credential_id = :CID AND status = ''revoked''';
q.ParamByName('CID').AsString := Trim(CredentialId);
q.ExecSQL;
if q.RowsAffected > 0 then
begin
Logger.Log(2, 'TApiService.UnrevokeDevice - restored: ' + Copy(CredentialId, 1, 20));
Result.AddPair('status', 'ok');
Result.AddPair('message', 'Device access restored.');
end
else
begin
Logger.Log(2, 'TApiService.UnrevokeDevice - not found or not revoked: ' + Copy(CredentialId, 1, 20));
Result.AddPair('status', 'error');
Result.AddPair('message', 'Device not found or not revoked.');
end;
finally
q.Free;
end;
finally
conn.Free;
end;
end;
function NormalizePhoneE164Api(const APhone: string): string; function NormalizePhoneE164Api(const APhone: string): string;
var var
digits: string; digits: string;
......
...@@ -27,6 +27,7 @@ type ...@@ -27,6 +27,7 @@ type
AUserAgent, ARegisteredAt, AStatus: string); AUserAgent, ARegisteredAt, AStatus: string);
[async] procedure LoadDevices; [async] procedure LoadDevices;
[async] procedure RevokeDevice(const ACredentialId, AName: string); [async] procedure RevokeDevice(const ACredentialId, AName: string);
[async] procedure UnrevokeDevice(const ACredentialId, AName: string);
[async] procedure DeletePendingDevice(const APhoneNumber, AName: string); [async] procedure DeletePendingDevice(const APhoneNumber, AName: string);
[async] procedure SendAppLink(const APhoneNumber, AName: string); [async] procedure SendAppLink(const APhoneNumber, AName: string);
[async] procedure AddPendingDevice; [async] procedure AddPendingDevice;
...@@ -225,7 +226,18 @@ begin ...@@ -225,7 +226,18 @@ begin
end); end);
tdAction.appendChild(btn); tdAction.appendChild(btn);
end end
else if not isRevoked then else if isRevoked then
begin
btn := TJSHTMLElement(document.createElement('button'));
btn.className := 'btn btn-outline-success btn-sm';
btn.innerText := 'Unrevoke';
btn.addEventListener('click', procedure(Event: TJSMouseEvent)
begin
UnrevokeDevice(ACredentialId, AName);
end);
tdAction.appendChild(btn);
end
else
begin begin
btn := TJSHTMLElement(document.createElement('button')); btn := TJSHTMLElement(document.createElement('button'));
btn.className := 'btn btn-danger btn-sm'; btn.className := 'btn btn-danger btn-sm';
...@@ -372,6 +384,30 @@ begin ...@@ -372,6 +384,30 @@ begin
end; end;
end; end;
procedure TFViewDeviceManager.UnrevokeDevice(const ACredentialId, AName: string);
var
resp: TXDataClientResponse;
res: TJSObject;
status: string;
begin
try
resp := await(XDataWebClient.RawInvokeAsync('IApiService.UnrevokeDevice', [ACredentialId]));
res := TJSObject(resp.Result);
status := string(res['status']);
if status = 'ok' then
begin
ShowNotification('Device "' + AName + '" has been restored.', False);
LoadDevices;
end
else
ShowNotification(string(res['message']));
except
on E: Exception do
ShowNotification('Unrevoke failed: ' + E.Message);
end;
end;
procedure TFViewDeviceManager.btnAddDeviceClick(Sender: TObject); procedure TFViewDeviceManager.btnAddDeviceClick(Sender: TObject);
begin begin
AddPendingDevice; AddPendingDevice;
......
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