Using Javascript to lock down an App or a Scene to a set of specific public IP

Hi to all,

Another piece of code for you Knack fellows!

Here's how to lock down your entire App or specific Scene(s) to a list of whitelisted IPs. I know there's the ablity in Knack to restrict ths whole App to some IPs, but this is not flexible enough for me. I need to have complete control over each Scene individually if I want to. This also enables me to decide if I want to apply the IP rule to all Accounts, or exclude some users like myself as a roaming developer who can be anywhere in the world. My IP changes all the time, so this is beneficial.

Here's the code, enjoy!

Norm

//Example showing how to lock an app or scene to a specific set of public IPs.
const MY_SCENE_1 = 'scene_123';
const MY_SCENE_2 = 'scene_456';

var authorizedIPs = ['111.112.113.114', '221.222.223.224']; //For example, these could be the official customer's IP and the developper's IP.

///////////////////////////////////////////////////
$(document).on('knack-scene-render.any', function (event, scene) {
//Here, you can filter for a specific set of scenes.
if (scene.key === MY_SCENE_1 || scene.key === MY_SCENE_2) {
getPublicIP()
.then(function (publicIP) {
console.log('IP has a valid format: ' + publicIP);

//Check if app can run from this machine.
if (authorizedIPs.includes(publicIP) /*|| or logged-in account is a priviledged power-user*/) {
console.log('Ok to run from this public IP.');//$$$
} else {
console.log('You do not have authorization to run from this public IP.');//$$$

/* Normally, you want to redirect to an error page in Knack. Here, the URL is simply: access-denied.
ex: https://mycompany.knack.com/myapp#access-denied/
Use a no-login blank page with Rich Text that states the cause of error. */
var index = window.location.href.indexOf('#');
var newlink = window.location.href.slice(0, index + 1) + 'access-denied/';

window.open(newlink, '_self');
}
}).catch(function (publicIP) {
console.log('IP has an invalid format: ' + publicIP);
});
}
});

//////////////////////////////////////////////////////////////////
function getPublicIP() {
return new Promise(function (resolve, reject) {
$.get('https://www.cloudflare.com/cdn-cgi/trace', function (data) {
var index = data.indexOf('ip=') + 3;
var publicIP = data.substr(index);
index = publicIP.indexOf('\n');
publicIP = publicIP.substr(0, index);
if (ipFormatOk(publicIP))
resolve(publicIP);
else
reject(publicIP);
});
});
}

//////////////////////////////////////////////////////////////////
function ipFormatOk(ipAddress) {
var ipFormat = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
if (ipAddress.match(ipFormat))
return true;
else
return false;
}

Ha ha!! Indeed I started coding in assembly language back in 1983 on a Tandy Coco I with 4k of ram! Then professionally in Pascal, C and C++ since 1994. Then recently, Python, Qt and Javascript. But academically, I come from an electronic design background with lots of embedded experience. I also do a lot of mechanical design and 3D printing. So I've been doing lots of different stuff, all fascinating and rewarding.

Norm

ctrnd.com

Hilarious you say you are a newbie coder. You must have come from another language i've been coding for 25 years and been doing intermittent javascript and you are still better than me lol

I upvoted it back to even you can't even see the upvote the code isn't wrapping and pushing it off the screen i sat here for 5 minutes trying to figure out why i can't see it lol

-

Thanks Tony!

I will post more and more as I gain experience. I wish more people do it because these support pages are rather thin, imo. Either way too basic, too complicated or with code that's hard to understand.

BTW, did you notice that someone downvoted this post? !!! I wonder why...

To all people reading this, I don't mind being criticized and even downvoted, but at least take a moment to tell me why. If my solution is wrong or not sub-optimal, I'll be glad to know where and learn about it, and will definitely update the post accordingly.

Cheers,
Norm

You are my new favorite poster! Awesome yesterday and today.