This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
1
Web Server - Ask For Help / Re: Antimalware Service Executable
« on: January 31, 2024, 12:34:49 AM »
Hi Richard,
Run RegEdit and Edit
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SecurityHealthService
Set Start to 3
My EC2s are on Windows Server 2019 Data Centre, so maybe it varies from version to version. That should disable it altogether.
Regards
Bill
Run RegEdit and Edit
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SecurityHealthService
Set Start to 3
My EC2s are on Windows Server 2019 Data Centre, so maybe it varies from version to version. That should disable it altogether.
Regards
Bill
2
Web Server - Share Knowledge / Re: Finally - Push Notifications for iOS Safari
« on: March 30, 2023, 08:53:29 PM »
Hi Don,
Thanks for the heads up. I didnt bother adding notifications into my PWA until i could get support from iOS, not just Android.
Regards
Bill
Thanks for the heads up. I didnt bother adding notifications into my PWA until i could get support from iOS, not just Android.
Regards
Bill
3
Web Server - Ask For Help / Re: Telephone field?
« on: February 14, 2023, 05:44:00 PM »
This is his code:
// ==================================================
//
// jquery-input-mask-phone-number v1.0
//
// Licensed (The MIT License)
//
// Copyright © Raja Rama Mohan Thavalam <rajaram.tavalam@gmail.com>
//
// ==================================================
;
(function ($) {
$.fn.usPhoneFormat = function (options) {
var params = $.extend({
format: 'xxx-xxx-xxxx',
international: false,
}, options);
if (params.format === 'xxx-xxx-xxxx') {
$(this).bind('paste', function (e) {
e.preventDefault();
var inputValue = e.originalEvent.clipboardData.getData('Text');
if (!$.isNumeric(inputValue)) {
return false;
} else {
inputValue = String(inputValue.replace(/(\d{3})(\d{3})(\d{4})/, "$1-$2-$3"));
$(this).val(inputValue);
$(this).val('');
inputValue = inputValue.substring(0, 12);
$(this).val(inputValue);
}
});
$(this).on('keypress', function (e) {
if (e.which != 8 && e.which != 0 && (e.which < 48 || e.which > 57)) {
return false;
}
var curchr = this.value.length;
var curval = $(this).val();
if (curchr == 3) {
$(this).val(curval + "-");
} else if (curchr == 7) {
$(this).val(curval + "-");
}
$(this).attr('maxlength', '12');
});
} else if (params.format === '(xxx) xxx-xxxx') {
$(this).on('keypress', function (e) {
if (e.which != 8 && e.which != 0 && (e.which < 48 || e.which > 57)) {
return false;
}
var curchr = this.value.length;
var curval = $(this).val();
if (curchr == 3) {
$(this).val('(' + curval + ')' + " ");
} else if (curchr == 9) {
$(this).val(curval + "-");
}
$(this).attr('maxlength', '14');
});
$(this).bind('paste', function (e) {
e.preventDefault();
var inputValue = e.originalEvent.clipboardData.getData('Text');
if (!$.isNumeric(inputValue)) {
return false;
} else {
inputValue = String(inputValue.replace(/(\d{3})(\d{3})(\d{4})/, "($1) $2-$3"));
$(this).val(inputValue);
$(this).val('');
inputValue = inputValue.substring(0, 14);
$(this).val(inputValue);
}
});
}
}
}(jQuery));
He is doing formatting on the client side in JQuery.
He is registering this function on the page with this:
$(document).ready(function () {
$('#yourphone').usPhoneFormat({
format: '(xxx) xxx-xxxx',
});
});
You could do a similar thing.
In NT rather than a function you'd probably bind this formatting to a class. Meaning, any fields where you want this formatting, add your "format into phone number" class to the html input and add your jquery that looks for this class and applies the formatting.
// ==================================================
//
// jquery-input-mask-phone-number v1.0
//
// Licensed (The MIT License)
//
// Copyright © Raja Rama Mohan Thavalam <rajaram.tavalam@gmail.com>
//
// ==================================================
;
(function ($) {
$.fn.usPhoneFormat = function (options) {
var params = $.extend({
format: 'xxx-xxx-xxxx',
international: false,
}, options);
if (params.format === 'xxx-xxx-xxxx') {
$(this).bind('paste', function (e) {
e.preventDefault();
var inputValue = e.originalEvent.clipboardData.getData('Text');
if (!$.isNumeric(inputValue)) {
return false;
} else {
inputValue = String(inputValue.replace(/(\d{3})(\d{3})(\d{4})/, "$1-$2-$3"));
$(this).val(inputValue);
$(this).val('');
inputValue = inputValue.substring(0, 12);
$(this).val(inputValue);
}
});
$(this).on('keypress', function (e) {
if (e.which != 8 && e.which != 0 && (e.which < 48 || e.which > 57)) {
return false;
}
var curchr = this.value.length;
var curval = $(this).val();
if (curchr == 3) {
$(this).val(curval + "-");
} else if (curchr == 7) {
$(this).val(curval + "-");
}
$(this).attr('maxlength', '12');
});
} else if (params.format === '(xxx) xxx-xxxx') {
$(this).on('keypress', function (e) {
if (e.which != 8 && e.which != 0 && (e.which < 48 || e.which > 57)) {
return false;
}
var curchr = this.value.length;
var curval = $(this).val();
if (curchr == 3) {
$(this).val('(' + curval + ')' + " ");
} else if (curchr == 9) {
$(this).val(curval + "-");
}
$(this).attr('maxlength', '14');
});
$(this).bind('paste', function (e) {
e.preventDefault();
var inputValue = e.originalEvent.clipboardData.getData('Text');
if (!$.isNumeric(inputValue)) {
return false;
} else {
inputValue = String(inputValue.replace(/(\d{3})(\d{3})(\d{4})/, "($1) $2-$3"));
$(this).val(inputValue);
$(this).val('');
inputValue = inputValue.substring(0, 14);
$(this).val(inputValue);
}
});
}
}
}(jQuery));
He is doing formatting on the client side in JQuery.
He is registering this function on the page with this:
$(document).ready(function () {
$('#yourphone').usPhoneFormat({
format: '(xxx) xxx-xxxx',
});
});
You could do a similar thing.
In NT rather than a function you'd probably bind this formatting to a class. Meaning, any fields where you want this formatting, add your "format into phone number" class to the html input and add your jquery that looks for this class and applies the formatting.
4
Web Server - Ask For Help / _utfdecode in NetWeb.CLW
« on: January 17, 2023, 11:21:18 PM »
Hi Bruce,
There is a bug in the _utfdecode function. Its in NT10 and also the latest NT12.
NetWebServer._utfdecode Procedure (String p_text)
ReturnValue long
code
case len(p_text)
of 1
returnvalue = band(val(p_text[1]),1111111b)
of 2
returnvalue = bshift(band(val(p_text[1]),11111b),6) + band(val(p_text[2]),111111b)
of 3
returnvalue = bshift(band(val(p_text[1]),1111b),12) + bshift(band(val(p_text[2]),11111b),6) + band(val(p_text[3]),111111b)
of 4
returnvalue = bshift(band(val(p_text[1]),1111b),18) + bshift(band(val(p_text[2]),111111b),12) + bshift(band(val(p_text[3]),111111b),6) + band(val(p_text[4]),111111b)
end
return returnValue
should read
NetWebServer._utfdecode Procedure (String p_text)
ReturnValue long
code
case len(p_text)
of 1
returnvalue = band(val(p_text[1]),1111111b)
of 2
returnvalue = bshift(band(val(p_text[1]),11111b),6) + band(val(p_text[2]),111111b)
of 3
returnvalue = bshift(band(val(p_text[1]),1111b),12) + bshift(band(val(p_text[2]),111111b),6) + band(val(p_text[3]),111111b) <--- this line
of 4
returnvalue = bshift(band(val(p_text[1]),1111b),18) + bshift(band(val(p_text[2]),111111b),12) + bshift(band(val(p_text[3]),111111b),6) + band(val(p_text[4]),111111b)
end
return returnValue
The second byte of a three byte UTF should be masked with 111111b not 11111b.
Also the first byte of a four byte UTF should be masked with 111b not 1111b, but as the value in the 4th bit is always 0, this doesnt cause an issue.
This caused certain Chinese, Korean and Japanese characters to get mangled.
Regards
Bill
There is a bug in the _utfdecode function. Its in NT10 and also the latest NT12.
NetWebServer._utfdecode Procedure (String p_text)
ReturnValue long
code
case len(p_text)
of 1
returnvalue = band(val(p_text[1]),1111111b)
of 2
returnvalue = bshift(band(val(p_text[1]),11111b),6) + band(val(p_text[2]),111111b)
of 3
returnvalue = bshift(band(val(p_text[1]),1111b),12) + bshift(band(val(p_text[2]),11111b),6) + band(val(p_text[3]),111111b)
of 4
returnvalue = bshift(band(val(p_text[1]),1111b),18) + bshift(band(val(p_text[2]),111111b),12) + bshift(band(val(p_text[3]),111111b),6) + band(val(p_text[4]),111111b)
end
return returnValue
should read
NetWebServer._utfdecode Procedure (String p_text)
ReturnValue long
code
case len(p_text)
of 1
returnvalue = band(val(p_text[1]),1111111b)
of 2
returnvalue = bshift(band(val(p_text[1]),11111b),6) + band(val(p_text[2]),111111b)
of 3
returnvalue = bshift(band(val(p_text[1]),1111b),12) + bshift(band(val(p_text[2]),111111b),6) + band(val(p_text[3]),111111b) <--- this line
of 4
returnvalue = bshift(band(val(p_text[1]),1111b),18) + bshift(band(val(p_text[2]),111111b),12) + bshift(band(val(p_text[3]),111111b),6) + band(val(p_text[4]),111111b)
end
return returnValue
The second byte of a three byte UTF should be masked with 111111b not 11111b.
Also the first byte of a four byte UTF should be masked with 111b not 1111b, but as the value in the 4th bit is always 0, this doesnt cause an issue.
This caused certain Chinese, Korean and Japanese characters to get mangled.
Regards
Bill
5
Web Server - Ask For Help / Re: (Nettalk) Webserver security?
« on: January 10, 2023, 06:48:55 PM »
Hi AtoB,
I use Fortigates to protect my infrastructure (which includes NetTalk servers).
They will protect against DOS and DDOS (assuming the network people know what they are doing and you pay for that part of the Fortinet).
They will also protect against a huge number of hack attempts (the vast majority a nettalk server is already protected against).
You must already have some sort of firewall, that is forwarding port 443 to your NetTalk (you cannot trust Windows!), if not, you need some type of firewall.
Assuming you have an existing firewall... these Network folks are wrong. They don't understand the stack that is NetTalk (nor would you expect them to). As long as you are only forwarding port 443 traffic to the NetTalk server you are safe.
The bigger Fortigates are also very very expensive.
Regards
Bill
I use Fortigates to protect my infrastructure (which includes NetTalk servers).
They will protect against DOS and DDOS (assuming the network people know what they are doing and you pay for that part of the Fortinet).
They will also protect against a huge number of hack attempts (the vast majority a nettalk server is already protected against).
You must already have some sort of firewall, that is forwarding port 443 to your NetTalk (you cannot trust Windows!), if not, you need some type of firewall.
Assuming you have an existing firewall... these Network folks are wrong. They don't understand the stack that is NetTalk (nor would you expect them to). As long as you are only forwarding port 443 traffic to the NetTalk server you are safe.
The bigger Fortigates are also very very expensive.
Regards
Bill
6
Web Server - Ask For Help / Re: NetwebBrowse not always refreshing after an update
« on: January 09, 2023, 02:52:34 AM »
Hi Sean,
Maybe if the browse update is occuring via ajax (without seeing your app - im guessing), the new browse is returning invalid XHMTL.
If so, you'll get exactly the behavour you are describing.
I use Chrome to inspect the ajax packet that is sent immediately after the update, to check its valid XHTML.
Regards
Bill
Maybe if the browse update is occuring via ajax (without seeing your app - im guessing), the new browse is returning invalid XHMTL.
If so, you'll get exactly the behavour you are describing.
I use Chrome to inspect the ajax packet that is sent immediately after the update, to check its valid XHTML.
Regards
Bill
7
Web Server - Ask For Help / Re: Larges Reports on NT
« on: December 27, 2022, 11:39:38 PM »
Oh.. in direct answer to your question, this bit does it, its at the bottom, and its called when the page loads:
packet.Append( '$.get('''&CLIP(lURL)&CLIP(st.GetValue())&'&m=c&f=''+reportfn);'&CRLF)
Its a bit confusing as you can't see all my code (and I have a lot of other stuff going on). This bit:
$.get('/YourReport?f=thefilenameyouwant');
packet.Append( '$.get('''&CLIP(lURL)&CLIP(st.GetValue())&'&m=c&f=''+reportfn);'&CRLF)
Its a bit confusing as you can't see all my code (and I have a lot of other stuff going on). This bit:
$.get('/YourReport?f=thefilenameyouwant');
8
Web Server - Ask For Help / Re: Larges Reports on NT
« on: December 27, 2022, 09:47:50 PM »
Here is my methodology:
1. The report will have a predetermined filename (this is so I can check for its existence).
2. I start printing the report. Then I take them to a NetWebPage that has two parts. (technically, I take them to this page then do an ajax call to start printing, then do the following)
(a) A Message saying wait
(b) Javascript that calls the server and asks if the report is complete (being able to open the filename in write mode, means its been completed).
3. If the report is complete, I open it (with Javascript)
4. If the report took too long, i open another page saying its taking too long and it will arrive later.
Below is the javascript I use at step 2b. This code checks every 1.5 seconds, ten times, if it doesnt turn up by then, it checks every 5 seconds another 10 times, again it checks each 10 seconds another 10 times, if the report doesnt turn up by them it redirects to a NetWebPage called SlowReport which shows a message, telling them it will turn up later.
So if a report takes longer than 2:45 you'll get a message. The slower polling is to maximise responsivness at the begining and not waste server power if its taking longer.
The ReportWrap mentioned in the Javascript is where I take them when the report finishes. Mine is a bit more complicated than necessary as the report preview is placed in an iFrame, so the report can also be emailed at this point in time.
The GenReport function checks to see if the report has been completed.
packet.Append( '<script>'&CRLF)
packet.Append( 'var reportTimer = setInterval(CheckReportProgress,1500);'&CRLF)
packet.Append( 'var intCount=0;'&CRLF)
packet.Append( 'var reportfn='''&CLIP(Encode7Bit(lFilename))&''';'&CRLF)
packet.Append( 'function CheckReportProgress(){{'&CRLF)
packet.Append( 'var jqxhr = $.ajax({{url: "'&CLIP(lURL)&'/GenReport?f='&CLIP(Encode7Bit(lFilename))&'",dataType: "json",data: {{'&CRLF)
packet.Append( ' result : "name",'&CRLF)
packet.Append( ' value : "value" } } '&CRLF)
packet.Append( ' ).done (function(data) {{'&CRLF)
packet.Append( ' console.log(''Result: '' + data.result); ;'&CRLF)
packet.Append( ' if (data.result==1) {{'&CRLF)
packet.Append( ' clearInterval(reportTimer);'&CRLF)
packet.Append( ' document.getElementById(''openReport'').style.display = "block";'&CRLF)
packet.Append( ' location.href=''/ReportWrap?fn='&CLIP(Encode7Bit(ReplaceBackSlashWithSlash(lFilename)))&''';'&CRLF)
packet.Append( ' } else {{'&CRLF)
packet.Append( ' intCount++;'&CRLF)
packet.Append( ' if (intCount>30) {{;'&CRLF)
packet.Append( ' clearInterval(reportTimer);'&CRLF)
packet.Append( ' location.href=''/SlowReport'';'&CRLF)
packet.Append( ' } else {{'&CRLF)
packet.Append( ' if (intCount>20) {{'&CRLF)
packet.Append( ' clearInterval(reportTimer);'&CRLF)
packet.Append( ' reportTimer = setInterval(CheckReportProgress,10000);'&CRLF)
packet.Append( ' } else {{'&CRLF)
packet.Append( ' if (intCount>10) {{'&CRLF)
packet.Append( ' clearInterval(reportTimer);'&CRLF)
packet.Append( ' reportTimer = setInterval(CheckReportProgress,5000);'&CRLF)
packet.Append( ' }'&CRLF)
packet.Append( ' }'&CRLF)
packet.Append( ' } '&CRLF)
packet.Append( ' } '&CRLF)
packet.Append( ' });'&CRLF)
packet.Append( '};'&CRLF)
packet.Append( '$.get('''&CLIP(lURL)&CLIP(st.GetValue())&'&m=c&f=''+reportfn);'&CRLF)
packet.Append( '</script>'&CRLF)
DO SendPacket
1. The report will have a predetermined filename (this is so I can check for its existence).
2. I start printing the report. Then I take them to a NetWebPage that has two parts. (technically, I take them to this page then do an ajax call to start printing, then do the following)
(a) A Message saying wait
(b) Javascript that calls the server and asks if the report is complete (being able to open the filename in write mode, means its been completed).
3. If the report is complete, I open it (with Javascript)
4. If the report took too long, i open another page saying its taking too long and it will arrive later.
Below is the javascript I use at step 2b. This code checks every 1.5 seconds, ten times, if it doesnt turn up by then, it checks every 5 seconds another 10 times, again it checks each 10 seconds another 10 times, if the report doesnt turn up by them it redirects to a NetWebPage called SlowReport which shows a message, telling them it will turn up later.
So if a report takes longer than 2:45 you'll get a message. The slower polling is to maximise responsivness at the begining and not waste server power if its taking longer.
The ReportWrap mentioned in the Javascript is where I take them when the report finishes. Mine is a bit more complicated than necessary as the report preview is placed in an iFrame, so the report can also be emailed at this point in time.
The GenReport function checks to see if the report has been completed.
packet.Append( '<script>'&CRLF)
packet.Append( 'var reportTimer = setInterval(CheckReportProgress,1500);'&CRLF)
packet.Append( 'var intCount=0;'&CRLF)
packet.Append( 'var reportfn='''&CLIP(Encode7Bit(lFilename))&''';'&CRLF)
packet.Append( 'function CheckReportProgress(){{'&CRLF)
packet.Append( 'var jqxhr = $.ajax({{url: "'&CLIP(lURL)&'/GenReport?f='&CLIP(Encode7Bit(lFilename))&'",dataType: "json",data: {{'&CRLF)
packet.Append( ' result : "name",'&CRLF)
packet.Append( ' value : "value" } } '&CRLF)
packet.Append( ' ).done (function(data) {{'&CRLF)
packet.Append( ' console.log(''Result: '' + data.result); ;'&CRLF)
packet.Append( ' if (data.result==1) {{'&CRLF)
packet.Append( ' clearInterval(reportTimer);'&CRLF)
packet.Append( ' document.getElementById(''openReport'').style.display = "block";'&CRLF)
packet.Append( ' location.href=''/ReportWrap?fn='&CLIP(Encode7Bit(ReplaceBackSlashWithSlash(lFilename)))&''';'&CRLF)
packet.Append( ' } else {{'&CRLF)
packet.Append( ' intCount++;'&CRLF)
packet.Append( ' if (intCount>30) {{;'&CRLF)
packet.Append( ' clearInterval(reportTimer);'&CRLF)
packet.Append( ' location.href=''/SlowReport'';'&CRLF)
packet.Append( ' } else {{'&CRLF)
packet.Append( ' if (intCount>20) {{'&CRLF)
packet.Append( ' clearInterval(reportTimer);'&CRLF)
packet.Append( ' reportTimer = setInterval(CheckReportProgress,10000);'&CRLF)
packet.Append( ' } else {{'&CRLF)
packet.Append( ' if (intCount>10) {{'&CRLF)
packet.Append( ' clearInterval(reportTimer);'&CRLF)
packet.Append( ' reportTimer = setInterval(CheckReportProgress,5000);'&CRLF)
packet.Append( ' }'&CRLF)
packet.Append( ' }'&CRLF)
packet.Append( ' } '&CRLF)
packet.Append( ' } '&CRLF)
packet.Append( ' });'&CRLF)
packet.Append( '};'&CRLF)
packet.Append( '$.get('''&CLIP(lURL)&CLIP(st.GetValue())&'&m=c&f=''+reportfn);'&CRLF)
packet.Append( '</script>'&CRLF)
DO SendPacket
9
Web Server - Ask For Help / Re: Larges Reports on NT
« on: December 27, 2022, 05:11:47 AM »
I take a slightly different approach.
I start generating the report.
I give the user a message to say its generating.
If it generates quickly, I open the report.
If it takes longer (in my case a few minutes), I give them a message to say it will appear later in the "reports" section. My program has a place where all past reports are stored and viewable (by user) so they can refer back to them. So this makes sense to them.
In my case, duration not filesize is the reliable indication. I don't use the progress indicatior as I wrote all this before it existed, and on the web users would just rather go and do something else and go back and check (or be notified) that the report has finished.
Technically, most of this is done client side within the browser.
Regards
Bill
I start generating the report.
I give the user a message to say its generating.
If it generates quickly, I open the report.
If it takes longer (in my case a few minutes), I give them a message to say it will appear later in the "reports" section. My program has a place where all past reports are stored and viewable (by user) so they can refer back to them. So this makes sense to them.
In my case, duration not filesize is the reliable indication. I don't use the progress indicatior as I wrote all this before it existed, and on the web users would just rather go and do something else and go back and check (or be notified) that the report has finished.
Technically, most of this is done client side within the browser.
Regards
Bill
10
Web Server - Ask For Help / Re: NetWebClient : sending "HTTPS" to an insecure server
« on: October 12, 2022, 11:42:59 PM »
Hi,
You cannot get an SSL certificate to work for a local IP like 192.168.X.X or 10.X.X.X or 127.0.0.1.
But, if you edit your hosts file (c:\windows\system32\drivers\etc\hosts) You can make a domain name point to a local address.
For example I have a domain inhabit.com.au, I can edit the hosts file on my local machine and add
192.168.0.100 inhabit.com.au
If I do this, if I try to go to inhabit.com.au it will go to the IP 192.168.0.100 (which could be my local machine) and in doing so, the SSL will work.
Not sure if this is what you need to know, but its how i do local ssl stuff.
Regards
Bill
You cannot get an SSL certificate to work for a local IP like 192.168.X.X or 10.X.X.X or 127.0.0.1.
But, if you edit your hosts file (c:\windows\system32\drivers\etc\hosts) You can make a domain name point to a local address.
For example I have a domain inhabit.com.au, I can edit the hosts file on my local machine and add
192.168.0.100 inhabit.com.au
If I do this, if I try to go to inhabit.com.au it will go to the IP 192.168.0.100 (which could be my local machine) and in doing so, the SSL will work.
Not sure if this is what you need to know, but its how i do local ssl stuff.
Regards
Bill
11
Web Server - Ask For Help / Re: json format in post data
« on: August 16, 2021, 04:00:10 AM »
Hi Jason,
Use {{ to escape the single { in clarion code.
Don't do it for }
Regards
Bill
Use {{ to escape the single { in clarion code.
Don't do it for }
Regards
Bill
12
Web Server - Ask For Help / Re: How to be a consultant?
« on: July 25, 2021, 06:38:10 PM »
Hi Jeff,
Sure.
bshields at inhabit.com.au
My mobile is 0410884907
Regards
Bill
Sure.
bshields at inhabit.com.au
My mobile is 0410884907
Regards
Bill
13
Web Server - Ask For Help / Re: JWT Json Web Token
« on: July 22, 2021, 12:36:42 AM »
Hi Bruce,
Awesome! Thanks. I'll clean up my code.
Regards
Bill
Awesome! Thanks. I'll clean up my code.
Regards
Bill
14
Web Server - Ask For Help / Re: JWT Json Web Token
« on: July 21, 2021, 03:19:36 AM »
Hi Jason,
I thought I should post the solution here incase anyone was interested (after we worked through it on Slack).
TestVonage PROCEDURE ! Declare Procedure
lToken STRING(1024)
lPayload STRING(1024)
lSecret STRING(255)
lAPIKey STRING(255)
CODE
lSecret = 'b845bb0a8b2xxxxxxxxxxxxxx30c108da7bd755b'
lAPIKey = 'xxxxxxx'
lPayload = '{{"iss": "'&CLIP(lAPIKey)&'","iat": '&TimestampZ()&',"exp": '&TimestampZ()+180&',"ist": "Inhabit","jti": "'&RandomString(16)&'"}'
lToken = CreateJWTToken(CLIP(lPayload),CLIP(lSecret))
WriteDebugInfo('Payload: '&CLIP(lPayload))
WriteDebugInfo('Token: '&CLIP(lToken))
CreateJWTToken FUNCTION (STRING lPayload,STRING lSecret) ! Declare Procedure
stHeader StringTheory
stPayload StringTheory
stToEncrypt StringTheory
stSignature StringTheory
Crypto Cryptonite
CODE ! Begin processed code
stHeader.SetValue('{{"typ":"JWT","alg":"HS256"}')
stPayload.SetValue(CLIP(lPayload))
stHeader.Base64Encode(1)
stHeader.Replace('+','-')
stHeader.Replace('/','_')
stHeader.Replace('=','')
stPayload.Base64Encode(1)
stPayload.Replace('+','-')
stPayload.Replace('/','_')
stPayload.Replace('=','')
stToEncrypt.SetValue(stHeader.GetValue()&'.'&stPayload.GetValue())
Crypto.MakeHMAC(stToEncrypt,CLIP(lSecret),cs:CALG_SHA_256,0)
stToEncrypt.Base64Encode(1)
stToEncrypt.Replace('+','-')
stToEncrypt.Replace('/','_')
stToEncrypt.Replace('=','')
RETURN stHeader.GetValue()&'.'&stPayload.GetValue()&'.'&stToEncrypt.GetValue()
A quick dirty demo, but it can be verified at https://jwt.io.
Regards
Bill
I thought I should post the solution here incase anyone was interested (after we worked through it on Slack).
TestVonage PROCEDURE ! Declare Procedure
lToken STRING(1024)
lPayload STRING(1024)
lSecret STRING(255)
lAPIKey STRING(255)
CODE
lSecret = 'b845bb0a8b2xxxxxxxxxxxxxx30c108da7bd755b'
lAPIKey = 'xxxxxxx'
lPayload = '{{"iss": "'&CLIP(lAPIKey)&'","iat": '&TimestampZ()&',"exp": '&TimestampZ()+180&',"ist": "Inhabit","jti": "'&RandomString(16)&'"}'
lToken = CreateJWTToken(CLIP(lPayload),CLIP(lSecret))
WriteDebugInfo('Payload: '&CLIP(lPayload))
WriteDebugInfo('Token: '&CLIP(lToken))
CreateJWTToken FUNCTION (STRING lPayload,STRING lSecret) ! Declare Procedure
stHeader StringTheory
stPayload StringTheory
stToEncrypt StringTheory
stSignature StringTheory
Crypto Cryptonite
CODE ! Begin processed code
stHeader.SetValue('{{"typ":"JWT","alg":"HS256"}')
stPayload.SetValue(CLIP(lPayload))
stHeader.Base64Encode(1)
stHeader.Replace('+','-')
stHeader.Replace('/','_')
stHeader.Replace('=','')
stPayload.Base64Encode(1)
stPayload.Replace('+','-')
stPayload.Replace('/','_')
stPayload.Replace('=','')
stToEncrypt.SetValue(stHeader.GetValue()&'.'&stPayload.GetValue())
Crypto.MakeHMAC(stToEncrypt,CLIP(lSecret),cs:CALG_SHA_256,0)
stToEncrypt.Base64Encode(1)
stToEncrypt.Replace('+','-')
stToEncrypt.Replace('/','_')
stToEncrypt.Replace('=','')
RETURN stHeader.GetValue()&'.'&stPayload.GetValue()&'.'&stToEncrypt.GetValue()
A quick dirty demo, but it can be verified at https://jwt.io.
Regards
Bill
15
Web Server - Ask For Help / Re: How to be a consultant?
« on: July 21, 2021, 01:21:08 AM »
Hi Jeff,
I can help with Australian Law.
I've negotiated dozens of long term development contracts and drafted many (in conjunction with my lawyers).
I'm happy to talk, if you want.
Regards
Bill Shields
I can help with Australian Law.
I've negotiated dozens of long term development contracts and drafted many (in conjunction with my lawyers).
I'm happy to talk, if you want.
Regards
Bill Shields