Skip to content

Commit 639e1ba

Browse files
authored
Dynamic Location Validation Approach (#2200)
* Create Readme.md * Create Smart Attachment Size Limiter.js * Delete Server-Side Components/Business Rules/Smart Attachment Size Limiter directory * Add UserLocationUtils for retrieving user location * 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. * 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. * Implement user location validation on form submission * Refactor location validation using Haversine formula * Revise README for User Location Validator Updated the README to clarify the User Location Validator functionality, including details on how it works, sample output, and usage notes. * Revise Readme for User Location Validator script Updated the readme to clarify the functionality and usage of the User Location Validator script, including details on how it works and sample output. * Implement UserLocationUtils for location retrieval * Update Readme with corrected script references * Delete Server-Side Components/Script Includes/Dynamic Location Validation Approach/Readme.md * Delete Server-Side Components/Script Includes/Dynamic Location Validation Approach/UserLocationUtils.js
1 parent 666e90a commit 639e1ba

File tree

3 files changed

+93
-0
lines changed

3 files changed

+93
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
**User Location Validator**
2+
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.
3+
4+
**How It Works**
5+
- The **server-side Script Include**(UserLocationUtils.js) fetches the assigned business location’s latitude, longitude, and name for the logged-in user.
6+
- 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.
7+
- It calculates the distance between these two points using the **Haversine formula**, which accounts for the spherical shape of the Earth.
8+
- The key constant `earthRadiusKm = 6371` defines the Earth's radius in kilometers and is essential for accurate distance calculation.
9+
- 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.
10+
- If the user is within range, a confirmation info message is displayed and the submission proceeds.
11+
12+
**Sample Output**
13+
- **Success:** "Location validated successfully within range of Headquarters."
14+
- **Failure:** "You are 15.23 km away from your registered location: Headquarters."
15+
16+
**Usage Notes**
17+
- Requires user consent for geolocation access in the browser.
18+
- The script uses descriptive variable names for clarity and maintainability.
19+
- Suitable for scenarios requiring geo-fencing compliance or location-based workflow restrictions.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
function onSubmit() {
2+
// Check if the browser supports geolocation
3+
if ("geolocation" in navigator) {
4+
// Request current user position
5+
navigator.geolocation.getCurrentPosition(function(position) {
6+
var currentLatitude = position.coords.latitude; // Current user latitude
7+
var currentLongitude = position.coords.longitude; // Current user longitude
8+
9+
// Allowed business location coordinates fetched from server
10+
var allowedLatitude = locData.latitude;
11+
var allowedLongitude = locData.longitude;
12+
var locationName = locData.name;
13+
14+
// Earth's radius in kilometers - constant used in distance calculation formula
15+
var earthRadiusKm = 6371;
16+
17+
// Convert degree differences to radians
18+
var deltaLatitude = (currentLatitude - allowedLatitude) * Math.PI / 180;
19+
var deltaLongitude = (currentLongitude - allowedLongitude) * Math.PI / 180;
20+
21+
// Haversine formula components
22+
var a = Math.sin(deltaLatitude / 2) * Math.sin(deltaLatitude / 2) +
23+
Math.cos(allowedLatitude * Math.PI / 180) *
24+
Math.cos(currentLatitude * Math.PI / 180) *
25+
Math.sin(deltaLongitude / 2) * Math.sin(deltaLongitude / 2);
26+
27+
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
28+
29+
// Calculate distance in kilometers between current and allowed locations
30+
var distanceKm = earthRadiusKm * c;
31+
32+
// Check if user's current distance exceeds tolerance (e.g., 10 km)
33+
if (distanceKm > 10) {
34+
alert("You are " + distanceKm.toFixed(2) + " km away from your registered location: " + locationName);
35+
g_form.addErrorMessage("Location validation failed: Submission outside the allowed radius.");
36+
return false; // Cancel form submission
37+
} else {
38+
g_form.addInfoMessage("Location validated successfully within range of " + locationName);
39+
return true; // Allow form submission
40+
}
41+
}, function(error) {
42+
alert("Geolocation error: " + error.message);
43+
return false; // Stop submission if geolocation fails
44+
});
45+
46+
// Prevent form submission while waiting for async geolocation result
47+
return false;
48+
} else {
49+
g_form.addErrorMessage("Geolocation is not supported by your browser.");
50+
return false; // Block if geolocation API unsupported
51+
}
52+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
var UserLocationUtils = Class.create();
2+
UserLocationUtils.prototype = {
3+
initialize: function() {
4+
5+
},
6+
getUserLocationCoords: function() {
7+
var user = gs.getUser();
8+
var loc = user.getRecord().location;
9+
if (loc) {
10+
var locGR = new GlideRecord('cmn_location');
11+
if (locGR.get(loc))
12+
return {
13+
latitude: parseFloat(locGR.latitude),
14+
longitude: parseFloat(locGR.longitude),
15+
name: locGR.name.toString()
16+
};
17+
}
18+
return null;
19+
},
20+
21+
type: 'UserLocationUtils'
22+
};

0 commit comments

Comments
 (0)