I will update the code on Github eventually, but until then, here is what needs modification … this is just to get things working with the new Authentication methods. It isn’t perfect, but it works - I will improve this later.
#Configure a User and Password to use
The defaultUser
and defaultUserPassword
needs to be set in config.js
to match.

#Configure the Application
The GQLclientId
needs to be set in config.js
to match.
#Update GQL Modules code (GQL Authentication) Files
The following files need to be modified:
config.js
(GQLclientId, GQLMsecret, defaultUser, defaultUserPassword)
gqlqueries.js
(gql.Authorize, gql.AuthorizeRefresh, gql.EXEC)
sputils.js
(fix for getBattery function is broken in FF52)
##config.js
##
The variables GQLclientId
, ‘GQLsecret’ and defaultUserPassword
are new.
// GraphQL server
var GQLhost = msgsrv;
var GQLport = '9898'; // generally, this is the only parameter that might need to change
var GQLpath = '/api/graphql/';
var GQLurl = webProto + '//' + GQLhost + ':' + GQLport + GQLpath;
var GQLclientId = 'GQLModules'; // Client Id needs to be configured in SambaPOS Users > Application
var GQLsecret = 'GQLMsecret'; // optional Secret Key when SambaPOS Application configured to use Secret Key
////////////////////////
// set default User and Terminal to use if Authentication is Bypassed
var defaultTerminal = 'Server';
var defaultUser = 'Admin';
var defaultUserPassword = '123456789'; // this is the account PASSWORD, NOT the PIN
##gqlqueries.js
##
Modified Functions: gql.EXEC
and gql.Authorize
New Function: gql.AuthorizeRefresh
//----------------------------------------------------------------------------
// main AJAX function to Post GQL Queries/Mutations and Receive data
//----------------------------------------------------------------------------
gql.EXEC = function (query, callback) {
spu.consoleLog('EXEC GQL:' +query);
var data = JSON.stringify({ query: query });
countTrafficBytes(data,'gql','sent');
return jQuery.ajax({
'type': 'POST',
'url': GQLurl,
headers: {'Authorization':'Bearer '+accessToken},
'contentType': 'application/json',
'data': data,
'dataType': 'json',
// 'success': callback,
'error': function(jqXHR, exception) {
if (jqXHR.status === 0) {
spu.consoleLog('!!! AJAX ERROR !!! ['+jqXHR.status+'] Could not connect. Verify Network.');
} else if (jqXHR.status == 401) {
spu.consoleLog('!!! AJAX ERROR !!! ['+jqXHR.status+'] Unauthorized. [401]');
var refreshToken = clientSetting('refreshToken');
if (refreshToken) {
gql.AuthorizeRefresh(refreshToken,function ra(resp){
var accessToken = resp.accessToken
var refreshToken = resp.refresh_token
if (refreshToken) {
clientSetting('refreshToken',refreshToken,'set');
spu.consoleLog('Re-Authentication SUCCESS !!!');
} else {
spu.consoleLog('Re-Authentication FAILED !!!');
showErrorMessage('!!! Re-Authentication FAILED !!!');
// goto login
}
});
} else {
// goto login
}
} else if (jqXHR.status == 404) {
spu.consoleLog('!!! AJAX ERROR !!! ['+jqXHR.status+'] Requested page not found. [404]');
} else if (jqXHR.status == 500) {
spu.consoleLog('!!! AJAX ERROR !!! ['+jqXHR.status+'] Internal Server Error [500].');
} else if (exception === 'parsererror') {
alert('Requested JSON parse failed.');
} else if (exception === 'timeout') {
alert('Time out error.');
} else if (exception === 'abort') {
alert('Ajax request aborted.');
} else if (jqXHR.status == 400) {
spu.consoleLog('!!! BAD REQUEST !!! ['+jqXHR.status+'] Bad Request [400].' + jqXHR.responseText);
showErrorMessage('!!! BAD REQUEST !!! ['+jqXHR.status+'] Bad Request [400].' + "\r\n\r\n" + jqXHR.responseText);
} else {
spu.consoleLog('Uncaught Error: ['+jqXHR.status+']' + jqXHR.responseText);
showErrorMessage('Uncaught Error: ['+jqXHR.status+']' + "\r\n\r\n" + jqXHR.responseText);
}
//callback(jqXHR.responseText);
jqXHR.responseJSON.GQLquery = data;
callback(jqXHR.responseJSON);
}
})
.done(callback
).then(
function(response){
var payload = JSON.stringify(response.data);
countTrafficBytes(payload,'gql','rcvd');
}
);
};
////////////////////////
//----------------------------------------------------------------------------
// GQL Authorization added in SambaPOS v5.1.61 and changed in v5.1.62
//----------------------------------------------------------------------------
gql.Authorize = function (user, password, callback) {
var aurl = 'http://' + GQLhost + ':' + GQLport + '/Token';
var clientId = (GQLclientId ? GQLclientId : 'unknown');
var clientSecret = (GQLsecret ? GQLsecret : '');
user = (user ? user : defaultUser);
password = (password ? password : defaultUserPassword);
spu.consoleLog('AUTHORIZING GQL ('+clientId+') ...');
spu.consoleLog('URL: '+aurl);
//spu.consoleLog('PW: '+password);
jQuery.ajax({
'type': 'POST',
'url': aurl,
cache:false,
headers: {'Content-Type':'application/x-www-form-urlencoded'},
data: $.param({grant_type:'password', username:user, password:password, client_id:clientId, client_secret:clientSecret})
})
.done(function d(response){
accessToken = response.access_token;
refreshToken = response.refresh_token;
clientSetting('accessToken',accessToken,'set');
clientSetting('refreshToken',refreshToken,'set');
spu.consoleLog('AUTHORIZED GQL ACCESS TOKEN: ' + accessToken.substr(0,20) + ' ...');
if (callback) {
callback(accessToken);
}
});
};
gql.AuthorizeRefresh = function (refreshToken, callback) {
var aurl = 'http://' + GQLhost + ':' + GQLport + '/Token';
var clientId = (GQLclientId ? GQLclientId : 'unknown');
var clientSecret = (GQLsecret ? GQLsecret : '');
var refreshToken = (refreshToken ? refreshToken : '');
spu.consoleLog('AUTHORIZING GQL ('+clientId+') ... REFRESH TOKEN: ' + refreshToken.substr(0,20) + ' ...');
spu.consoleLog('URL: '+aurl);
jQuery.ajax({
'type': 'POST',
'url': config.GQLserv + '/Token',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: $.param({grant_type:'refresh_token', refresh_token: refreshToken, client_id:clientId, client_secret:clientSecret})
}).done(function d(response){
accessToken = response.access_token;
refreshToken = response.refresh_token;
clientSetting('accessToken',accessToken,'set');
clientSetting('refreshToken',refreshToken,'set');
spu.consoleLog('AUTHORIZED GQL (REFRESH): ' + accessToken.substr(0,20) + ' ...');
callback(response);
}).fail(function d(response){
callback(response);
});
}
##sputils.js
##
Modified Functions: getBatteryLevel()
This is a workaround for a change in Firefox 52 where navigator.getBattery
now requires a special setting to be made in the Browser, so in this case, this modification will suppress the error that is raised.
function getBatteryLevel() {
if (isiDevice || navigator.sayswho.indexOf('IE ') > -1 || !navigator.getBattery) {
//
$('#battery').html('');
clearInterval(batteryTimer);
} else {
navigator.getBattery().then(function(battery) {
var battLevel = battery.level * 100;
$('#battery').html(battLevel.toFixed(0)+'%');
return battLevel;
});
}
}