From a7b7262bc8a2241cfac0699c3432212b18f37537 Mon Sep 17 00:00:00 2001 From: Charanjeet <35090930+Charanjet@users.noreply.github.com> Date: Wed, 15 Oct 2025 00:36:56 +0530 Subject: [PATCH 1/7] Create Readme.md --- .../Business Rules/Smart Attachment Size Limiter/Readme.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Server-Side Components/Business Rules/Smart Attachment Size Limiter/Readme.md diff --git a/Server-Side Components/Business Rules/Smart Attachment Size Limiter/Readme.md b/Server-Side Components/Business Rules/Smart Attachment Size Limiter/Readme.md new file mode 100644 index 0000000000..502c913352 --- /dev/null +++ b/Server-Side Components/Business Rules/Smart Attachment Size Limiter/Readme.md @@ -0,0 +1,7 @@ +Smart Attachment Size Limiter +This Business Rule limits attachment sizes uploaded to ServiceNow records by enforcing a maximum size configured via the system property com.glide.attachment.max_size (in bytes). If the attachment exceeds the configured limit, the upload is blocked with an error message shown to the user. You can create or modify this system property to change the max size and update the property name in the script accordingly. + +Scoped Application Note: +If deploying in a scoped application, configure Cross-Scope Access under System Applications > Application Cross-Scope Access to allow your app permission to access the sys_attachment table and related resources, avoiding security restrictions. + +This approach keeps your instance performant by managing attachment size transparently without hardcoded limits. From fc57af84360c26cb8690147e8c39272f0940d09e Mon Sep 17 00:00:00 2001 From: Charanjeet <35090930+Charanjet@users.noreply.github.com> Date: Wed, 15 Oct 2025 00:39:50 +0530 Subject: [PATCH 2/7] Create Smart Attachment Size Limiter.js --- .../Smart Attachment Size Limiter.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 Server-Side Components/Business Rules/Smart Attachment Size Limiter/Smart Attachment Size Limiter.js diff --git a/Server-Side Components/Business Rules/Smart Attachment Size Limiter/Smart Attachment Size Limiter.js b/Server-Side Components/Business Rules/Smart Attachment Size Limiter/Smart Attachment Size Limiter.js new file mode 100644 index 0000000000..644e7b7b22 --- /dev/null +++ b/Server-Side Components/Business Rules/Smart Attachment Size Limiter/Smart Attachment Size Limiter.js @@ -0,0 +1,14 @@ +(function executeRule(current, previous /*null when async*/ ) { + if (current.table_name == 'incident') { //here multiple tables can be looped I am just using incident table + var maxSize = gs.getProperty('com.glide.attachment.max_size'); + maxSize = parseInt(maxSize, 10); + if (current.size_bytes > maxSize) { + var maxSizeMB = (maxSize / (1024 * 1024)).toFixed(2); + var attachmentSizeMB = (current.size_bytes / (1024 * 1024)).toFixed(2); + // Prevent insert by setting error message + gs.addErrorMessage("Attachment '" + current.file_name + "' size (" + attachmentSizeMB + " MB) exceeds the max allowed size of " + maxSizeMB + " MB. Please reduce the file size."); + // Cancel the insert operation + current.setAbortAction(true); + } + } +})(current, previous); From 9149ae9683e71f189966245d42c2c88daef2b327 Mon Sep 17 00:00:00 2001 From: Charanjeet <35090930+Charanjet@users.noreply.github.com> Date: Wed, 15 Oct 2025 00:44:14 +0530 Subject: [PATCH 3/7] Delete Server-Side Components/Business Rules/Smart Attachment Size Limiter directory --- .../Smart Attachment Size Limiter/Readme.md | 7 ------- .../Smart Attachment Size Limiter.js | 14 -------------- 2 files changed, 21 deletions(-) delete mode 100644 Server-Side Components/Business Rules/Smart Attachment Size Limiter/Readme.md delete mode 100644 Server-Side Components/Business Rules/Smart Attachment Size Limiter/Smart Attachment Size Limiter.js diff --git a/Server-Side Components/Business Rules/Smart Attachment Size Limiter/Readme.md b/Server-Side Components/Business Rules/Smart Attachment Size Limiter/Readme.md deleted file mode 100644 index 502c913352..0000000000 --- a/Server-Side Components/Business Rules/Smart Attachment Size Limiter/Readme.md +++ /dev/null @@ -1,7 +0,0 @@ -Smart Attachment Size Limiter -This Business Rule limits attachment sizes uploaded to ServiceNow records by enforcing a maximum size configured via the system property com.glide.attachment.max_size (in bytes). If the attachment exceeds the configured limit, the upload is blocked with an error message shown to the user. You can create or modify this system property to change the max size and update the property name in the script accordingly. - -Scoped Application Note: -If deploying in a scoped application, configure Cross-Scope Access under System Applications > Application Cross-Scope Access to allow your app permission to access the sys_attachment table and related resources, avoiding security restrictions. - -This approach keeps your instance performant by managing attachment size transparently without hardcoded limits. diff --git a/Server-Side Components/Business Rules/Smart Attachment Size Limiter/Smart Attachment Size Limiter.js b/Server-Side Components/Business Rules/Smart Attachment Size Limiter/Smart Attachment Size Limiter.js deleted file mode 100644 index 644e7b7b22..0000000000 --- a/Server-Side Components/Business Rules/Smart Attachment Size Limiter/Smart Attachment Size Limiter.js +++ /dev/null @@ -1,14 +0,0 @@ -(function executeRule(current, previous /*null when async*/ ) { - if (current.table_name == 'incident') { //here multiple tables can be looped I am just using incident table - var maxSize = gs.getProperty('com.glide.attachment.max_size'); - maxSize = parseInt(maxSize, 10); - if (current.size_bytes > maxSize) { - var maxSizeMB = (maxSize / (1024 * 1024)).toFixed(2); - var attachmentSizeMB = (current.size_bytes / (1024 * 1024)).toFixed(2); - // Prevent insert by setting error message - gs.addErrorMessage("Attachment '" + current.file_name + "' size (" + attachmentSizeMB + " MB) exceeds the max allowed size of " + maxSizeMB + " MB. Please reduce the file size."); - // Cancel the insert operation - current.setAbortAction(true); - } - } -})(current, previous); From a9c13f78de536b3cf8c36689b1a94455fd477f35 Mon Sep 17 00:00:00 2001 From: Charanjeet <35090930+Charanjet@users.noreply.github.com> Date: Thu, 16 Oct 2025 00:19:19 +0530 Subject: [PATCH 4/7] Add UserLocationUtils for retrieving user location --- .../UserLocationUtils.js | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Server-Side Components/Script Includes/Dynamic Location Validation Approach/UserLocationUtils.js diff --git a/Server-Side Components/Script Includes/Dynamic Location Validation Approach/UserLocationUtils.js b/Server-Side Components/Script Includes/Dynamic Location Validation Approach/UserLocationUtils.js new file mode 100644 index 0000000000..5435dbd06b --- /dev/null +++ b/Server-Side Components/Script Includes/Dynamic Location Validation Approach/UserLocationUtils.js @@ -0,0 +1,22 @@ +var UserLocationUtils = Class.create(); +UserLocationUtils.prototype = { + initialize: function() { + + }, + getUserLocationCoords: function() { + var user = gs.getUser(); + var loc = user.getRecord().location; + if (loc) { + var locGR = new GlideRecord('cmn_location'); + if (locGR.get(loc)) + return { + latitude: parseFloat(locGR.latitude), + longitude: parseFloat(locGR.longitude), + name: locGR.name.toString() + }; + } + return null; + }, + + type: 'UserLocationUtils' +}; From 9fa52c785a7dd952040aac26754978e3858b7faa Mon Sep 17 00:00:00 2001 From: Charanjeet <35090930+Charanjet@users.noreply.github.com> Date: Thu, 16 Oct 2025 00:23:24 +0530 Subject: [PATCH 5/7] Add Readme for User Location Validator solution This document explains the User Location Validator solution, detailing how it restricts form submissions based on user location. --- .../Dynamic Location Validation Approach/Readme.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Server-Side Components/Script Includes/Dynamic Location Validation Approach/Readme.md diff --git a/Server-Side Components/Script Includes/Dynamic Location Validation Approach/Readme.md b/Server-Side Components/Script Includes/Dynamic Location Validation Approach/Readme.md new file mode 100644 index 0000000000..de0a46863e --- /dev/null +++ b/Server-Side Components/Script Includes/Dynamic Location Validation Approach/Readme.md @@ -0,0 +1,4 @@ +User Location Validator +This solution ensures only users within their assigned business location can submit ServiceNow forms. The Script Include (Server-Side Components/Script Includes/Dynamic Location Validation Approach/UserLocationUtils.js) fetches location coordinates from the user’s profile. The Client Script (Client-Side Components/Client Scripts/Dynamic Location Validation Approach/User Location Validator.js) compares these with the actual browser location, blocking submission if the user is outside the allowed area. Update office location in the user record to adjust the validation. + +If using a scoped application, ensure cross-scope access is allowed for Script Include calls. From c15fe8922b995f0a82113252bf3bcdb8ce6e3383 Mon Sep 17 00:00:00 2001 From: Charanjeet <35090930+Charanjet@users.noreply.github.com> Date: Thu, 16 Oct 2025 00:24:33 +0530 Subject: [PATCH 6/7] Add README for User Location Validator solution This document explains the User Location Validator solution, which restricts ServiceNow form submissions based on user location. It details the functionality of the Script Include and Client Script involved in the validation process. --- .../Dynamic Location Validation Approach/Readme.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Client-Side Components/Client Scripts/Dynamic Location Validation Approach/Readme.md diff --git a/Client-Side Components/Client Scripts/Dynamic Location Validation Approach/Readme.md b/Client-Side Components/Client Scripts/Dynamic Location Validation Approach/Readme.md new file mode 100644 index 0000000000..de0a46863e --- /dev/null +++ b/Client-Side Components/Client Scripts/Dynamic Location Validation Approach/Readme.md @@ -0,0 +1,4 @@ +User Location Validator +This solution ensures only users within their assigned business location can submit ServiceNow forms. The Script Include (Server-Side Components/Script Includes/Dynamic Location Validation Approach/UserLocationUtils.js) fetches location coordinates from the user’s profile. The Client Script (Client-Side Components/Client Scripts/Dynamic Location Validation Approach/User Location Validator.js) compares these with the actual browser location, blocking submission if the user is outside the allowed area. Update office location in the user record to adjust the validation. + +If using a scoped application, ensure cross-scope access is allowed for Script Include calls. From ce7e10f165ee6dd757f75696523f0603094386ac Mon Sep 17 00:00:00 2001 From: Charanjeet <35090930+Charanjet@users.noreply.github.com> Date: Thu, 16 Oct 2025 00:25:20 +0530 Subject: [PATCH 7/7] Implement user location validation on form submission --- .../User Location Validator.js | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Client-Side Components/Client Scripts/Dynamic Location Validation Approach/User Location Validator.js diff --git a/Client-Side Components/Client Scripts/Dynamic Location Validation Approach/User Location Validator.js b/Client-Side Components/Client Scripts/Dynamic Location Validation Approach/User Location Validator.js new file mode 100644 index 0000000000..2526f580a2 --- /dev/null +++ b/Client-Side Components/Client Scripts/Dynamic Location Validation Approach/User Location Validator.js @@ -0,0 +1,39 @@ +function onSubmit() { + var ga = new GlideAjax('UserLocationUtils'); + ga.addParam('sysparm_name', 'getUserLocationCoords'); + ga.getXMLAnswer(function(response) { + var locData = JSON.parse(response); + if (!locData) { + g_form.addErrorMessage("No assigned location found for your profile."); + return false; + } + + navigator.geolocation.getCurrentPosition(function(position) { + var userLat = position.coords.latitude; + var userLng = position.coords.longitude; + var allowedLat = locData.latitude; + var allowedLng = locData.longitude; + var locName = locData.name; + + var R = 6371; + var dLat = (userLat - allowedLat) * Math.PI / 180; + var dLng = (userLng - allowedLng) * Math.PI / 180; + var a = Math.sin(dLat / 2) ** 2 + + Math.cos(allowedLat * Math.PI / 180) * + Math.cos(userLat * Math.PI / 180) * + Math.sin(dLng / 2) ** 2; + var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + var distance = R * c; + + if (distance > 10) { // 10 km tolerance + alert("You are " + distance.toFixed(2) + " km away from your registered office: " + locName); + g_form.addErrorMessage("Location validation failed."); + return false; + } else { + g_form.addInfoMessage("Location validated successfully within range of " + locName); + return true; + } + }); + }); + return false; // Wait for async location validation +}