From 344eeef669cbeff94c478029c6896546bc24b655 Mon Sep 17 00:00:00 2001 From: Jithin P V Date: Wed, 24 Sep 2025 23:13:42 +0530 Subject: [PATCH 1/4] added a service for EbButtonPublicFormAttach's URL encryption --- Services/WebFormServices.cs | 197 ++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) diff --git a/Services/WebFormServices.cs b/Services/WebFormServices.cs index ccd7f20..092026e 100644 --- a/Services/WebFormServices.cs +++ b/Services/WebFormServices.cs @@ -32,6 +32,8 @@ using ServiceStack.Text; using System.Text; using ServiceStack.Redis; +using ExpressBase.Objects.ServiceStack_Artifacts.EbButtonPublicFormAttachServiceStackArtifacts; +using ExpressBase.Common.Helpers; namespace ExpressBase.ServiceStack.Services { @@ -3139,6 +3141,201 @@ public AttDeviceSaveRawPunchRecordsResp Post(AttDeviceSaveRawPunchRecordsReq req return resp; } + + public ResponseEbButtonPublicFormAttachServiceStackArtifact Get(RequestEbButtonPublicFormAttachServiceStackArtifact request) + { + DebugHelper.PrintObject(request); + DebugHelper.PrintObject(request.PublicFormRefId); + + if (request == null) + { + return new ResponseEbButtonPublicFormAttachServiceStackArtifact + { + Success = false, + Message = "Invalid request payload.", + Error = new ErrorEbButtonPublicFormAttachServiceStackArtifact + { + ErrorCode = "InvalidRequest", + ErrorMessage = "Request payload is null." + } + }; + } + + + if (string.IsNullOrWhiteSpace(request.PublicFormRefId)) + { + return new ResponseEbButtonPublicFormAttachServiceStackArtifact + { + Success = false, + Message = "PublicFormRefId is required.", + Error = new ErrorEbButtonPublicFormAttachServiceStackArtifact + { + ErrorCode = "MissingFormRefId", + ErrorMessage = "The 'PublicFormRefId' query parameter or path value is required." + } + }; + } + + if (string.IsNullOrWhiteSpace(request.SourceFormRefId)) + { + return new ResponseEbButtonPublicFormAttachServiceStackArtifact + { + Success = false, + Message = "SourceFormRefId is required.", + Error = new ErrorEbButtonPublicFormAttachServiceStackArtifact + { + ErrorCode = "MissingFormRefId", + ErrorMessage = "The 'SourceFormRefId' query parameter or path value is required." + } + }; + } + + + if (request.SourceFormDataId < 0) + { + return new ResponseEbButtonPublicFormAttachServiceStackArtifact + { + Success = false, + Message = "SourceFormDataId is required.", + Error = new ErrorEbButtonPublicFormAttachServiceStackArtifact + { + ErrorCode = "MissingFormRefId", + ErrorMessage = "The 'SourceFormDataId' query parameter or path value is required." + } + }; + } + + + string publicFormId = null; + int expireInDays = 0; + int expireInHours = 0; + int expireInMinutes = 0; + bool found = false; + List fieldMaps = null; + string sourceFormPrimaryTableName; + + try + { + + EbWebForm form = this.GetWebFormObject(request.SourceFormRefId, request.UserAuthId, request.SolnId); + + //DebugHelper.PrintObject(form.FormSchema.Tables); + + foreach (var table in form.FormSchema.Tables) + { + foreach (var column in table.Columns) + { + if (column.Control != null && column.Control is EbButtonPublicFormAttach control) + { + //throwing an exception as there is a mismatch in PublicFormRefId reveived from frontend + + if (request.PublicFormRefId != control.PublicFormId) + { + throw new ArgumentException($"PublicFormRefId ({request.PublicFormRefId}) does not match PublicFormId ({control.PublicFormId})."); + } + + publicFormId = control.PublicFormId; + expireInDays = control.ExpireInDays; + expireInHours = control.ExpireInHours; + expireInMinutes = control.ExpireInMinutes; + fieldMaps = control.FieldMaps; + + found = true; + break; + + } + } + + if (found) + { + break; + } + } + + form.TableRowId = request.SourceFormDataId; + form.RefreshFormData(EbConnectionFactory.DataDBRO, this); + sourceFormPrimaryTableName = form.TableName; + var _sourceFormPrimaryTableData = form.FormData.MultipleTables[sourceFormPrimaryTableName]; + List sourceFormPrimaryTableData = null; + var queryParts = new List(); + object sourceFormPrimaryTableDataValue = null; + DateTime futureDateTime; + long? futureEpoch = null; + string queryString = ""; + string queryStringEncrypted = ""; + + + foreach (var sourceFormPrimaryTableDataum in _sourceFormPrimaryTableData) + { + if(sourceFormPrimaryTableDataum.RowId == request.SourceFormDataId) + { + sourceFormPrimaryTableData = sourceFormPrimaryTableDataum.Columns; + break; + } + } + + foreach (var fieldMap in fieldMaps) + { + sourceFormPrimaryTableDataValue = sourceFormPrimaryTableData.FirstOrDefault(c => c.Name == fieldMap.SourceFormContolName)?.Value; + + if(sourceFormPrimaryTableDataValue != null) + { + queryParts.Add( + fieldMap.DesitnationFormContolName + + "=" + + sourceFormPrimaryTableDataValue.ToString() + ); + } + + } + + if (expireInDays != 0 || expireInHours != 0 || expireInMinutes != 0) + { + futureDateTime = DateTime.Now + .AddDays(expireInDays) + .AddHours(expireInHours) + .AddMinutes(expireInMinutes); + + futureEpoch = new DateTimeOffset(futureDateTime).ToUnixTimeSeconds(); + + queryParts.Add("_ebPublicFormExpiryDateTime=" + futureEpoch); + } + + if (queryParts.Any()) + { + queryString = string.Join("&", queryParts); + //var key = AesEncryptionHelper.GenerateKey(); + var key = "J4AlupPY4+sT9kVVNcyRcffoCs+Z3fGDUPaVXLZop1g="; // TODO: dummy key for testing; change before release + DebugHelper.PrintObject(key, printAsJson: true); + queryStringEncrypted = AesEncryptionHelper.EncryptString(key, queryString); + } + + + return new ResponseEbButtonPublicFormAttachServiceStackArtifact + { + Success = true, + QueryString = queryString, + QueryStringEncrypted = queryStringEncrypted, + Message = "URL generated successfully." + }; + } + catch (Exception ex) + { + DebugHelper.PrintException(ex); + + return new ResponseEbButtonPublicFormAttachServiceStackArtifact + { + Success = false, + Message = ex.Message, + Error = new ErrorEbButtonPublicFormAttachServiceStackArtifact + { + ErrorCode = "ServerError", + ErrorMessage = ex.Message + } + }; + } + } + } } From 32388f77e73bb5055e80ff9587702b18a57ec896 Mon Sep 17 00:00:00 2001 From: Jithin P V Date: Fri, 3 Oct 2025 15:50:28 +0530 Subject: [PATCH 2/4] added support for EbButtonPublicFormAttachServiceDto in ResponseEbButtonPublicFormAttachServiceStackArtifact --> Get() --- Services/WebFormServices.cs | 89 +++++++++---------------------------- 1 file changed, 21 insertions(+), 68 deletions(-) diff --git a/Services/WebFormServices.cs b/Services/WebFormServices.cs index 092026e..b4a8739 100644 --- a/Services/WebFormServices.cs +++ b/Services/WebFormServices.cs @@ -34,6 +34,7 @@ using ServiceStack.Redis; using ExpressBase.Objects.ServiceStack_Artifacts.EbButtonPublicFormAttachServiceStackArtifacts; using ExpressBase.Common.Helpers; +using ExpressBase.Objects.Dtos; namespace ExpressBase.ServiceStack.Services { @@ -3144,15 +3145,12 @@ public AttDeviceSaveRawPunchRecordsResp Post(AttDeviceSaveRawPunchRecordsReq req public ResponseEbButtonPublicFormAttachServiceStackArtifact Get(RequestEbButtonPublicFormAttachServiceStackArtifact request) { - DebugHelper.PrintObject(request); - DebugHelper.PrintObject(request.PublicFormRefId); if (request == null) { return new ResponseEbButtonPublicFormAttachServiceStackArtifact { Success = false, - Message = "Invalid request payload.", Error = new ErrorEbButtonPublicFormAttachServiceStackArtifact { ErrorCode = "InvalidRequest", @@ -3167,7 +3165,6 @@ public ResponseEbButtonPublicFormAttachServiceStackArtifact Get(RequestEbButtonP return new ResponseEbButtonPublicFormAttachServiceStackArtifact { Success = false, - Message = "PublicFormRefId is required.", Error = new ErrorEbButtonPublicFormAttachServiceStackArtifact { ErrorCode = "MissingFormRefId", @@ -3181,7 +3178,6 @@ public ResponseEbButtonPublicFormAttachServiceStackArtifact Get(RequestEbButtonP return new ResponseEbButtonPublicFormAttachServiceStackArtifact { Success = false, - Message = "SourceFormRefId is required.", Error = new ErrorEbButtonPublicFormAttachServiceStackArtifact { ErrorCode = "MissingFormRefId", @@ -3190,13 +3186,22 @@ public ResponseEbButtonPublicFormAttachServiceStackArtifact Get(RequestEbButtonP }; } + string publicFormId = null; + int expireInDays = 0; + int expireInHours = 0; + int expireInMinutes = 0; + bool found = false; + List fieldMaps = null; + EbButtonPublicFormAttachServiceDto dto; + List sourceFormPrimaryTableData = null; + + if (request.SourceFormDataId < 0) { return new ResponseEbButtonPublicFormAttachServiceStackArtifact { Success = false, - Message = "SourceFormDataId is required.", Error = new ErrorEbButtonPublicFormAttachServiceStackArtifact { ErrorCode = "MissingFormRefId", @@ -3206,20 +3211,11 @@ public ResponseEbButtonPublicFormAttachServiceStackArtifact Get(RequestEbButtonP } - string publicFormId = null; - int expireInDays = 0; - int expireInHours = 0; - int expireInMinutes = 0; - bool found = false; - List fieldMaps = null; - string sourceFormPrimaryTableName; - try { EbWebForm form = this.GetWebFormObject(request.SourceFormRefId, request.UserAuthId, request.SolnId); - //DebugHelper.PrintObject(form.FormSchema.Tables); foreach (var table in form.FormSchema.Tables) { @@ -3254,79 +3250,36 @@ public ResponseEbButtonPublicFormAttachServiceStackArtifact Get(RequestEbButtonP form.TableRowId = request.SourceFormDataId; form.RefreshFormData(EbConnectionFactory.DataDBRO, this); - sourceFormPrimaryTableName = form.TableName; - var _sourceFormPrimaryTableData = form.FormData.MultipleTables[sourceFormPrimaryTableName]; - List sourceFormPrimaryTableData = null; - var queryParts = new List(); - object sourceFormPrimaryTableDataValue = null; - DateTime futureDateTime; - long? futureEpoch = null; - string queryString = ""; - string queryStringEncrypted = ""; - - foreach (var sourceFormPrimaryTableDataum in _sourceFormPrimaryTableData) + foreach (var sourceFormPrimaryTableDataum in form.FormData.MultipleTables[form.TableName]) { - if(sourceFormPrimaryTableDataum.RowId == request.SourceFormDataId) + if (sourceFormPrimaryTableDataum.RowId == request.SourceFormDataId) { sourceFormPrimaryTableData = sourceFormPrimaryTableDataum.Columns; break; } } - foreach (var fieldMap in fieldMaps) - { - sourceFormPrimaryTableDataValue = sourceFormPrimaryTableData.FirstOrDefault(c => c.Name == fieldMap.SourceFormContolName)?.Value; - - if(sourceFormPrimaryTableDataValue != null) - { - queryParts.Add( - fieldMap.DesitnationFormContolName + - "=" + - sourceFormPrimaryTableDataValue.ToString() - ); - } - - } - - if (expireInDays != 0 || expireInHours != 0 || expireInMinutes != 0) - { - futureDateTime = DateTime.Now - .AddDays(expireInDays) - .AddHours(expireInHours) - .AddMinutes(expireInMinutes); - - futureEpoch = new DateTimeOffset(futureDateTime).ToUnixTimeSeconds(); - - queryParts.Add("_ebPublicFormExpiryDateTime=" + futureEpoch); - } - - if (queryParts.Any()) - { - queryString = string.Join("&", queryParts); - //var key = AesEncryptionHelper.GenerateKey(); - var key = "J4AlupPY4+sT9kVVNcyRcffoCs+Z3fGDUPaVXLZop1g="; // TODO: dummy key for testing; change before release - DebugHelper.PrintObject(key, printAsJson: true); - queryStringEncrypted = AesEncryptionHelper.EncryptString(key, queryString); - } - return new ResponseEbButtonPublicFormAttachServiceStackArtifact { Success = true, - QueryString = queryString, - QueryStringEncrypted = queryStringEncrypted, - Message = "URL generated successfully." + EbButtonPublicFormAttachServiceDto = new EbButtonPublicFormAttachServiceDto( + publicFormId, + expireInDays, + expireInHours, + expireInMinutes, + fieldMaps, + sourceFormPrimaryTableData + ), }; } catch (Exception ex) { - DebugHelper.PrintException(ex); return new ResponseEbButtonPublicFormAttachServiceStackArtifact { Success = false, - Message = ex.Message, Error = new ErrorEbButtonPublicFormAttachServiceStackArtifact { ErrorCode = "ServerError", From efe349e696efcf7a84214ac000aef415fb81a7f2 Mon Sep 17 00:00:00 2001 From: Jithin P V Date: Fri, 10 Oct 2025 02:06:31 +0530 Subject: [PATCH 3/4] added out directory to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 1380f9a..a316021 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ bld/ [Bb]in/ [Oo]bj/ [Ll]og/ +out # Visual Studio 2015 cache/options directory .vs/ From 4351ab8abfab5d0a26b9636aa0896b9345dc6b6e Mon Sep 17 00:00:00 2001 From: Jithin P V Date: Fri, 10 Oct 2025 02:07:33 +0530 Subject: [PATCH 4/4] added a comment --- Startup.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Startup.cs b/Startup.cs index a261ecc..49c6da3 100644 --- a/Startup.cs +++ b/Startup.cs @@ -94,6 +94,7 @@ public override void Configure(Container container) MyJwtAuthProvider jwtprovider = new MyJwtAuthProvider { HashAlgorithm = "RS256", + //TODO: base64 encode these in env PrivateKeyXml = Environment.GetEnvironmentVariable(EnvironmentConstants.EB_JWT_PRIVATE_KEY_XML), PublicKeyXml = Environment.GetEnvironmentVariable(EnvironmentConstants.EB_JWT_PUBLIC_KEY_XML), //#if (DEBUG)