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..68602d0bb4 --- /dev/null +++ b/Client-Side Components/Client Scripts/Dynamic Location Validation Approach/Readme.md @@ -0,0 +1,19 @@ +**User Location Validator** +This script restricts form submissions based on the physical location of the user. The current location is obtained using the browser’s geolocation API (latitude and longitude), and is then compared against the user's assigned business location stored in ServiceNow. + +**How It Works** +- The **server-side Script Include**(UserLocationUtils.js) fetches the assigned business location’s latitude, longitude, and name for the logged-in user. +- The **client-side script**(User Location Validator.js) uses the browser API to obtain the current latitude and longitude of the user at form submission. +- It calculates the distance between these two points using the **Haversine formula**, which accounts for the spherical shape of the Earth. +- The key constant `earthRadiusKm = 6371` defines the Earth's radius in kilometers and is essential for accurate distance calculation. +- If the user’s current location is outside the predefined radius (default 10 km), the form submission is blocked with an error message showing the distance and allowed location. +- If the user is within range, a confirmation info message is displayed and the submission proceeds. + +**Sample Output** +- **Success:** "Location validated successfully within range of Headquarters." +- **Failure:** "You are 15.23 km away from your registered location: Headquarters." + +**Usage Notes** +- Requires user consent for geolocation access in the browser. +- The script uses descriptive variable names for clarity and maintainability. +- Suitable for scenarios requiring geo-fencing compliance or location-based workflow restrictions. 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..44095b7110 --- /dev/null +++ b/Client-Side Components/Client Scripts/Dynamic Location Validation Approach/User Location Validator.js @@ -0,0 +1,52 @@ +function onSubmit() { + // Check if the browser supports geolocation + if ("geolocation" in navigator) { + // Request current user position + navigator.geolocation.getCurrentPosition(function(position) { + var currentLatitude = position.coords.latitude; // Current user latitude + var currentLongitude = position.coords.longitude; // Current user longitude + + // Allowed business location coordinates fetched from server + var allowedLatitude = locData.latitude; + var allowedLongitude = locData.longitude; + var locationName = locData.name; + + // Earth's radius in kilometers - constant used in distance calculation formula + var earthRadiusKm = 6371; + + // Convert degree differences to radians + var deltaLatitude = (currentLatitude - allowedLatitude) * Math.PI / 180; + var deltaLongitude = (currentLongitude - allowedLongitude) * Math.PI / 180; + + // Haversine formula components + var a = Math.sin(deltaLatitude / 2) * Math.sin(deltaLatitude / 2) + + Math.cos(allowedLatitude * Math.PI / 180) * + Math.cos(currentLatitude * Math.PI / 180) * + Math.sin(deltaLongitude / 2) * Math.sin(deltaLongitude / 2); + + var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + + // Calculate distance in kilometers between current and allowed locations + var distanceKm = earthRadiusKm * c; + + // Check if user's current distance exceeds tolerance (e.g., 10 km) + if (distanceKm > 10) { + alert("You are " + distanceKm.toFixed(2) + " km away from your registered location: " + locationName); + g_form.addErrorMessage("Location validation failed: Submission outside the allowed radius."); + return false; // Cancel form submission + } else { + g_form.addInfoMessage("Location validated successfully within range of " + locationName); + return true; // Allow form submission + } + }, function(error) { + alert("Geolocation error: " + error.message); + return false; // Stop submission if geolocation fails + }); + + // Prevent form submission while waiting for async geolocation result + return false; + } else { + g_form.addErrorMessage("Geolocation is not supported by your browser."); + return false; // Block if geolocation API unsupported + } +} diff --git a/Client-Side Components/Client Scripts/Dynamic Location Validation Approach/UserLocationUtils.js b/Client-Side Components/Client Scripts/Dynamic Location Validation Approach/UserLocationUtils.js new file mode 100644 index 0000000000..5435dbd06b --- /dev/null +++ b/Client-Side Components/Client Scripts/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' +};