Update sqrlogin control to pass through input to main.js, fixes cancel and enables routing away

This commit is contained in:
Deon George 2022-12-07 21:49:52 +11:00
parent b3ef9e35e7
commit e7b9ed73d0
5 changed files with 102 additions and 64 deletions

View File

@ -4,7 +4,7 @@
;gpg_key=0@videotex ;gpg_key=0@videotex
[sqrl] [sqrl]
auth_url=https://ansitex.bbs.leenooks.net auth_url=https://sqrl.dege.au
auth_path=/sqrl/login auth_path=/sqrl/login
auth_post=/api/sqrl auth_post=/api/sqrl

View File

@ -24,8 +24,8 @@ function sqrllogin() {
var complete = false; var complete = false;
var cancel = false; var cancel = false;
log(LOG_DEBUG,'OPTIONS: '+JSON.stringify(loadOptions('sqrl')));
var sqrl = loadOptions('sqrl'); var sqrl = loadOptions('sqrl');
log(LOG_DEBUG,'OPTIONS: '+JSON.stringify(sqrl));
var http = new HTTPRequest(); var http = new HTTPRequest();
http.SetupGet(sqrl.auth_path,undefined,sqrl.auth_url); http.SetupGet(sqrl.auth_path,undefined,sqrl.auth_url);
http.request_headers.push('Accept: application/json'); http.request_headers.push('Accept: application/json');
@ -48,22 +48,45 @@ function sqrllogin() {
// Loop and see if the user has logged in // Loop and see if the user has logged in
var nut = http.body.substr(http.body.indexOf('nut='),68); var nut = http.body.substr(http.body.indexOf('nut='),68);
var read = ''; } catch (err) {
while (read !== '2') { log(LOG_INFO,'SQRL Error: '+err+' '+JSON.stringify(sqrl));
read = console.inkey(K_NONE,1000); cancel = true;
}
if (read === 2) // Called before processing for a field
cancel = true; Object.defineProperty(this, 'getName', {
get: function () {
return 'SQRL-LOGIN';
}
});
http = new HTTPRequest(); Object.defineProperty(this, 'isComplete', {
http.SetupGet(sqrl.auth_post+'?'+nut,undefined,sqrl.auth_url); get: function () {
http.request_headers.push('Accept: application/json'); return complete;
}
});
log(LOG_DEBUG,'Checking NUT in ['+nut+']'); // Nothing to do here
http.SendRequest(); this.handle=function(read) {
http.ReadResponse(); log(LOG_DEBUG,'Control SQRL-LOGIN handle() start. ('+read+')');
switch (http.response_code) { if (read === '2') {
log(LOG_INFO,'SQRL: Cancelled with 2');
cancel = true;
} else {
log(LOG_DEBUG,'SQRL read ['+read+']');
try {
http = new HTTPRequest();
http.SetupGet(sqrl.auth_post+'?'+nut,undefined,sqrl.auth_url);
http.request_headers.push('Accept: application/json');
log(LOG_DEBUG,'Checking NUT in ['+nut+']');
http.SendRequest();
http.ReadResponse();
switch (http.response_code) {
case 404: case 404:
log(LOG_DEBUG,'- NUT not Authorised yet.'); log(LOG_DEBUG,'- NUT not Authorised yet.');
break; break;
@ -120,7 +143,6 @@ function sqrllogin() {
log(LOG_DEBUG,' - SEND TO EXIT:'); log(LOG_DEBUG,' - SEND TO EXIT:');
complete = true; complete = true;
read = '2';
action = ACTION_EXIT; action = ACTION_EXIT;
if (typeof subframe === 'object') if (typeof subframe === 'object')
subframe.close(); subframe.close();
@ -129,72 +151,52 @@ function sqrllogin() {
} else { } else {
log(LOG_ERROR,'- Login Failed? '); log(LOG_ERROR,'- Login Failed? ');
cancel = true;
} }
} else { } else {
log(LOG_ERROR,'- Unhandled User Details: '+http.response_code); log(LOG_ERROR,'- Unhandled User Details: '+http.response_code);
cancel = true;
} }
} else { } else {
log(LOG_ERROR,'- Unhandled isReady msg: '+result.msg); log(LOG_ERROR,'- Unhandled isReady msg: '+result.msg);
cancel = true;
} }
complete = true; complete = true;
if (typeof subframe === 'object') if (typeof subframe === 'object')
subframe.close(); subframe.close();
// We are done
read = '2';
} else { } else {
log(LOG_ERROR,'- Unhandled isReady: '+result.isReady); log(LOG_ERROR,'- Unhandled isReady: '+result.isReady);
// We are done
read = '2';
cancel = true; cancel = true;
} }
break; break;
default: default:
log(LOG_ERROR,'- Unhandled response code: '+http.response_code); log(LOG_ERROR,'- Unhandled response code: '+http.response_code);
// We are done // We are done
read = '2';
cancel = true; cancel = true;
} }
} catch (err) {
log(LOG_INFO,'SQRL Error: '+err+' '+JSON.stringify(sqrl));
cancel = true;
}
} }
complete = true; if (cancel) {
log(LOG_INFO,'SQRL: Processing CANCEL ['+read+'].');
complete = true;
if (typeof subframe === 'object')
subframe.close();
} catch (err) { action = ACTION_GOTO;
log(LOG_INFO,'SQRL Error: '+err+' '+JSON.stringify(sqrl)); next_page = LOGIN_FRAME;
cancel = true;
}
if (cancel) {
complete = true;
if (typeof subframe === 'object')
subframe.close();
action = ACTION_GOTO;
next_page = LOGIN_FRAME;
}
// Called before processing for a field
Object.defineProperty(this, 'getName', {
get: function () {
return 'SQRL-LOGIN';
} }
});
Object.defineProperty(this, 'isComplete', {
get: function () {
return complete;
}
});
// Nothing to do here
this.handle=function(read) {
log(LOG_DEBUG,'Control SQRL-LOGIN handle() start. ('+read+')');
return read; return read;
} }

58
main.js
View File

@ -130,11 +130,15 @@ while(bbs.online) {
/* ESC key sequence received */ /* ESC key sequence received */
var esc = false; var esc = false;
log(LOG_DEBUG,'- Start ACTION is ['+action+']');
// If we have no action, read from the terminal // If we have no action, read from the terminal
if (action === false) { if (action === false) {
// If a special key sequence is coming... // If a special key sequence is coming...
while ((esc || ! read) && (action !== ACTION_TERMINATE)) { while ((esc || ! read) && (action !== ACTION_TERMINATE)) {
log(LOG_DEBUG,'- READ START'); log(LOG_DEBUG,'================================================');
log(LOG_DEBUG,'- READ START : control.length='+control.length);
log(LOG_DEBUG,'- READ START : inkey_timeout='+inkey_timeout);
// Wait for a key from the user // Wait for a key from the user
read = console.inkey(K_NONE,inkey_timeout); read = console.inkey(K_NONE,inkey_timeout);
@ -183,6 +187,8 @@ while(bbs.online) {
// Calculate idle timeouts // Calculate idle timeouts
// If the user has exemption H we dont worry about timeout // If the user has exemption H we dont worry about timeout
if (! read && ! (user.security.exemptions&UFLAG_H) ) { if (! read && ! (user.security.exemptions&UFLAG_H) ) {
log(LOG_DEBUG,'- READ empty, evaluating timeouts...');
// Terminate the user if they have been inactive too long. // Terminate the user if they have been inactive too long.
if (time() > timer+((user.number ? INACTIVE_LOGIN : INACTIVE_NOLOGIN)+INKEY_TIMEOUT)/1000) { if (time() > timer+((user.number ? INACTIVE_LOGIN : INACTIVE_NOLOGIN)+INKEY_TIMEOUT)/1000) {
fo.sendBaseline('INACTIVE',false); fo.sendBaseline('INACTIVE',false);
@ -219,6 +225,10 @@ while(bbs.online) {
if (esc) { if (esc) {
log(LOG_DEBUG,'- READ SPECIAL KEY LOOP'); log(LOG_DEBUG,'- READ SPECIAL KEY LOOP');
} }
// If we are in a control, we need to break here so that the control takes the input
if (control.length)
break;
} }
} }
log(LOG_DEBUG,'READ: ['+read+'] ('+read.charCodeAt(0)+')'); log(LOG_DEBUG,'READ: ['+read+'] ('+read.charCodeAt(0)+')');
@ -241,12 +251,16 @@ while(bbs.online) {
control.pop(); control.pop();
cc = null; cc = null;
log(LOG_DEBUG,'CONTROL COMPLETE: ['+read+'] ('+control.length+')'); log(LOG_DEBUG,'CONTROL COMPLETE: ['+read+'] ('+control.length+')');
// If there are no more control items
if (control.length == 0)
inkey_timeout = INKEY_TIMEOUT;
} }
log(LOG_DEBUG,'CONTROL END: ['+read+']'); log(LOG_DEBUG,'CONTROL END: ['+read+']');
} }
log(LOG_DEBUG,'MODE START: ['+read.charCodeAt(0)+']'); log(LOG_DEBUG,'MODE START: ['+read.charCodeAt(0)+'] ('+mode+')');
switch (mode) { switch (mode) {
// Normal navigation // Normal navigation
case false: case false:
@ -272,14 +286,18 @@ while(bbs.online) {
// If are requesting a home page // If are requesting a home page
if (fo.key[read] === 0) { if (fo.key[read] === 0) {
next_page = user.number ? HOME_FRAME : LOGIN_FRAME; next_page = user.number ? HOME_FRAME : LOGIN_FRAME;
action = ACTION_GOTO;
log(LOG_DEBUG,'- false: Key ['+read+'] ['+pageStr(next_page)+']');
} else if (fo.key[read].toString().match(/^[0-9]+/)) {
next_page = {frame: fo.key[read],index: 'a'};
action = ACTION_GOTO;
log(LOG_DEBUG,'- false: Key ['+read+'] ['+pageStr(next_page)+']');
} else { } else {
next_page = {frame: fo.key[read],index: 'a'}; fo.sendBaseline('ERR_ROUTE',false);
} }
action = ACTION_GOTO;
log(LOG_DEBUG,'- false: Key ['+read+'] ['+pageStr(next_page)+']');
} else { } else {
fo.sendBaseline('ERR_ROUTE',false); fo.sendBaseline('ERR_ROUTE',false);
} }
@ -313,6 +331,8 @@ while(bbs.online) {
console.write(read); console.write(read);
} }
log(LOG_DEBUG,'- MODE_BL: cmd ['+cmd+']');
// If the user pressed backspace // If the user pressed backspace
// @todo We should get the user's configuration of backspace // @todo We should get the user's configuration of backspace
if ((read === CTRL_H || read === KEY_DEL) && cmd.length) { if ((read === CTRL_H || read === KEY_DEL) && cmd.length) {
@ -327,14 +347,18 @@ while(bbs.online) {
break; break;
} }
// Special code to launch SQRL
if (cmd === '01' && ! user.number) { if (cmd === '01' && ! user.number) {
action = ACTION_GOTO; action = ACTION_GOTO;
next_page = SQRL_FRAME; next_page = SQRL_FRAME;
cmd = '';
break; break;
} }
// Invalid system pages. // Invalid system pages.
if (cmd.match(/^0[2367]/)) { if (cmd.match(/^0[12367]/)) {
log(LOG_DEBUG,'- MODE_BL: Invalid System Page ['+cmd+']');
fo.cursorOff(); fo.cursorOff();
fo.sendBaseline('ERR_ROUTE',false); fo.sendBaseline('ERR_ROUTE',false);
mode = action = false; mode = action = false;
@ -343,6 +367,8 @@ while(bbs.online) {
// Edit specific frame // Edit specific frame
if (cmd.match(/^04/) && read.match(/[a-z]/)) { if (cmd.match(/^04/) && read.match(/[a-z]/)) {
log(LOG_DEBUG,'- MODE_BL: Edit ['+cmd+']');
// If we are not a user // If we are not a user
if (! user.number) { if (! user.number) {
fo.cursorOff(); fo.cursorOff();
@ -365,6 +391,8 @@ while(bbs.online) {
// Bookmark frame // Bookmark frame
if (cmd === '05') { if (cmd === '05') {
log(LOG_DEBUG,'- MODE_BL: Bookmark ['+cmd+']');
if (! user.number) { if (! user.number) {
fo.cursorOff(); fo.cursorOff();
fo.sendBaseline('ERR_ROUTE',false); fo.sendBaseline('ERR_ROUTE',false);
@ -384,6 +412,8 @@ while(bbs.online) {
// Report Problem // Report Problem
if (cmd === '08') { if (cmd === '08') {
log(LOG_DEBUG,'- MODE_BL: Report Problem ['+cmd+'] ('+fo.page+')');
if (! user.number) { if (! user.number) {
fo.cursorOff(); fo.cursorOff();
fo.sendBaseline('ERR_ROUTE',false); fo.sendBaseline('ERR_ROUTE',false);
@ -403,6 +433,8 @@ while(bbs.online) {
// Reload frame // Reload frame
if (cmd === '09') { if (cmd === '09') {
log(LOG_DEBUG,'- MODE_BL: Reload frame ['+cmd+'] ('+fo.page+')');
fo.cursorOff(); fo.cursorOff();
action = ACTION_GOTO; action = ACTION_GOTO;
cmd = ''; cmd = '';
@ -413,6 +445,8 @@ while(bbs.online) {
// Another star aborts the command // Another star aborts the command
if (read === '*') { if (read === '*') {
log(LOG_DEBUG,'- MODE_BL: Abort ['+cmd+'])');
fo.clearBaseline(false); fo.clearBaseline(false);
fo.cursorOff(); fo.cursorOff();
mode = action = false; mode = action = false;
@ -433,6 +467,8 @@ while(bbs.online) {
} }
if ((viewdata && read === '_') || (! viewdata && read === '#') || ((read === "\r") && (cmd.length > 0))) { if ((viewdata && read === '_') || (! viewdata && read === '#') || ((read === "\r") && (cmd.length > 0))) {
log(LOG_DEBUG,'- MODE_BL: Return Received ['+cmd+'])');
// Nothing typed between * and # // Nothing typed between * and #
// *# means go back // *# means go back
if (cmd === '') { if (cmd === '') {
@ -465,6 +501,7 @@ while(bbs.online) {
mode = false; mode = false;
} }
log(LOG_DEBUG,'- MODE_BL: END');
break; break;
// Key presses during field input. // Key presses during field input.
@ -626,7 +663,7 @@ while(bbs.online) {
log(LOG_DEBUG,' - Key 1 is:'+JSON.stringify(fo.key[1])); log(LOG_DEBUG,' - Key 1 is:'+JSON.stringify(fo.key[1]));
// If we are in a control method, complete it // If we are in a control method, complete it
if (control.count) { if (control.length) {
log(LOG_DEBUG,'Last control method is:'+JSON.stringify(control[control.length-1])); log(LOG_DEBUG,'Last control method is:'+JSON.stringify(control[control.length-1]));
control[control.length-1].process(); control[control.length-1].process();
@ -795,15 +832,13 @@ while(bbs.online) {
break; break;
// @todo MODE_CONTROL
default: default:
log(LOG_DEBUG,'- SHOULDNT GET HERE: ['+read+']'); log(LOG_DEBUG,'- SHOULDNT GET HERE: ['+read+']');
action = ACTION_TERMINATE; action = ACTION_TERMINATE;
} }
log(LOG_DEBUG,'MODE END: ['+read+']'); log(LOG_DEBUG,'MODE END: ['+read+']');
log(LOG_DEBUG,'ACTION START: ['+read+']'); log(LOG_DEBUG,'ACTION START: ['+read+'] ('+action+')');
switch (action) { switch (action) {
// Start command entry // Start command entry
case ACTION_STAR: case ACTION_STAR:
@ -1148,6 +1183,7 @@ while(bbs.online) {
log(LOG_DEBUG,'Adding SQRL to control stack'); log(LOG_DEBUG,'Adding SQRL to control stack');
require('ansitex/load/control-'+fo.key[1]+'.js','CONTROL_SQRL'); require('ansitex/load/control-'+fo.key[1]+'.js','CONTROL_SQRL');
control.push(eval('new '+fo.key[1]+'();')); control.push(eval('new '+fo.key[1]+'();'));
inkey_timeout = 1000;
} else if (fo.key[1] && (fo.type === FRAME_TYPE_RESPONSE) && (typeof(fo.key[1]) !== 'number')) { } else if (fo.key[1] && (fo.type === FRAME_TYPE_RESPONSE) && (typeof(fo.key[1]) !== 'number')) {
log(LOG_DEBUG,'Adding METHOD to control stack: '+fo.key[1]); log(LOG_DEBUG,'Adding METHOD to control stack: '+fo.key[1]);

View File

@ -1 +1 @@
{"version":1,"frame":"982","index":"a","owner":9,"cost":0,"content":"G1swbRtbMTszMG3ExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMQbWzBtDQogG1sxOzMxbdzcxNwbWzM3bSAbWzMybdzcxNwbWzM3bSAbWzM0bdzcxNwbWzM3bSAbWzMzbdzcG1swbSAbWzMwOzQ3bSDc3CAgINzcxNwg3Nwg3CAbWzM3OzQwbQ0KIBtbMTszMW3c3MSxG1szN20gG1szMm2ysRtbMzdtIBtbMzJtsRtbMzdtIBtbMzRt39/E3BtbMzdtIBtbMzNt3NwbWzBtIBtbMzA7NDdtILKxxCAgsrHE3yDf38LfIBtbMzc7NDBtDQogG1sxOzMxbbGwG1swbSAbWzE7MzFtsBtbMG0gG1sxOzMybbGwG1swbSAbWzE7MzJtsBtbMG0gG1sxOzM0bbGwG1swbSAbWzE7MzRtsBtbMG0gG1sxOzMzbbGwG1swbSAbWzMwOzQ3bSCxsCCwILGwILAgsbAgsCAbWzM3OzQwbQ0KIBtbMTszMW3f38TfG1swbSAbWzE7MzJt398bWzBtIBtbMTszMm3fG1swbSAbWzE7MzRt39/E3xtbMG0gG1sxOzMzbd/fG1swbSAbWzMwOzQ3bSDf38TfIN/fxN8g398g3yAbWzM3OzQwbQ0KG1sxOzMwbcTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExBtbMG0NCg0KG1sxbVRvIGNvbXBsZXRlIGF1dGhlbnRpY3Rpb24sIHBsZWFzZRtbMG0NChtbMW1vcGVuIHlvdXIgU1FSTCBhcHBsaWNhdGlvbiBhbmQbWzBtICAgICAgICAgICAgICAgICAbWzE7MzBtsyAgIEhPTEQgVElHSFQgICCzG1swbQ0KG1sxbXNjYW4gdGhlIFFSIENvZGUgb24gdGhlIHJpZ2h0LhtbMG0gICAgICAgICAgICAgICAgIBtbMTszMG2zICBXSElMRSBXRSBHRVQgILMbWzBtDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIBtbMTszMG2zICBZT1UgQSBRUkNPREUgILMbWzBtDQobWzFtUmVnaXN0ZXJpbmcgYW5kIHVzaW5nIHRoaXMgc3lzdGVtLBtbMG0gICAgICAgICAgICAgG1sxOzMwbbMgKG1heSB0YWtlIDMwcykgsxtbMG0NChtbMW15b3UgYWdyZWUgdG8gYWJpZGUgYnkgdGhlIHN5c3RlbRtbMG0NChtbMW1ydWxlcy4gWW91IGNhbiB2aWV3IHRob3NlIHJ1bGVzIG9uG1swbQ0KG1sxbXBhZ2UgG1szMm0qOTg4IxtbMG0NCg==","isPublic":1,"isAccessible":1,"type":"l","key":[98,"sqrllogin",98,98,null,null,null,null,null,null],"date":"2020-08-09T11:42:40.643Z"} {"version":1,"frame":"982","index":"a","owner":9,"cost":0,"content":"G1swbRtbMTszMG3ExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMQbWzBtDQogG1sxOzMxbdzcxNwbWzM3bSAbWzMybdzcxNwbWzM3bSAbWzM0bdzcxNwbWzM3bSAbWzMzbdzcG1swbSAbWzMwOzQ3bSDc3CAgINzcxNwg3Nwg3CAbWzM3OzQwbQ0KIBtbMTszMW3c3MSxG1szN20gG1szMm2ysRtbMzdtIBtbMzJtsRtbMzdtIBtbMzRt39/E3BtbMzdtIBtbMzNt3NwbWzBtIBtbMzA7NDdtILKxxCAgsrHE3yDf38LfIBtbMzc7NDBtDQogG1sxOzMxbbGwG1swbSAbWzE7MzFtsBtbMG0gG1sxOzMybbGwG1swbSAbWzE7MzJtsBtbMG0gG1sxOzM0bbGwG1swbSAbWzE7MzRtsBtbMG0gG1sxOzMzbbGwG1swbSAbWzMwOzQ3bSCxsCCwILGwILAgsbAgsCAbWzM3OzQwbQ0KIBtbMTszMW3f38TfG1swbSAbWzE7MzJt398bWzBtIBtbMTszMm3fG1swbSAbWzE7MzRt39/E3xtbMG0gG1sxOzMzbd/fG1swbSAbWzMwOzQ3bSDf38TfIN/fxN8g398g3yAbWzM3OzQwbQ0KG1sxOzMwbcTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExBtbMG0NCg0KG1sxbVRvIGNvbXBsZXRlIGF1dGhlbnRpY3Rpb24sIHBsZWFzZRtbMG0NChtbMW1vcGVuIHlvdXIgU1FSTCBhcHBsaWNhdGlvbiBhbmQbWzBtICAgICAgICAgICAgICAgICAbWzE7MzBtsyAgIEhPTEQgVElHSFQgICCzG1swbQ0KG1sxbXNjYW4gdGhlIFFSIENvZGUgb24gdGhlIHJpZ2h0LhtbMG0gICAgICAgICAgICAgICAgIBtbMTszMG2zICBXSElMRSBXRSBHRVQgILMbWzBtDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIBtbMTszMG2zICBZT1UgQSBRUkNPREUgILMbWzBtDQobWzFtUmVnaXN0ZXJpbmcgYW5kIHVzaW5nIHRoaXMgc3lzdGVtLBtbMG0gICAgICAgICAgICAgG1sxOzMwbbMgKG1heSB0YWtlIDMwcykgsxtbMG0NChtbMW15b3UgYWdyZWUgdG8gYWJpZGUgYnkgdGhlIHN5c3RlbRtbMG0NChtbMW1ydWxlcy4gWW91IGNhbiB2aWV3IHRob3NlIHJ1bGVzIG9uG1swbQ0KG1sxbXBhZ2UgG1szMm0qOTg4IxtbMG0NCg==","isPublic":1,"isAccessible":1,"type":"l","key":[null,"sqrllogin",null,null,null,null,null,null,null,null],"date":"2020-08-09T11:42:40.643Z"}

View File

@ -1 +1 @@
{"version":1,"frame":"982","index":"a","owner":9,"cost":0,"content":"ICARLGwSfGwUfCwTLBc3a38jMzdrIzUgICAgICACMDAwMTAwMDEwMSAgEX9rEn9qFC98E38XNWhvIDw9JCw1ByAgICAgICAgICAgICAgICAgIBEvLhIvKhQsLxMvF3VwenBxdXpwNSAgICAgICAgICAgICAgICAgICAgVmlkZW90ZXggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVG8gY29tcGxldGUgdGhlICAgICAgICAgICAgICAgICAgICAgICAgIGF1dGhlbnRpY2F0aW9uLCAgICAgICAgICAgICAgICAgICAgICAgICB1c2UgeW91ciBTUVJMIGFwcCAgICAgICAgA0hPTEQgVElHSFQgICAgYW5kIHNjYW4gdGhlIFFSICAgICAgICAgA1dISUxFIFdFIEdFVCAgIGNvZGUuICAgICAgICAgICAgICAgICAgIANZT1UgQSBRUkNPREUgICAgICAgICAgICAgICAgICAgICAgICAgIAMobWF5IHRha2UgMzBzKSAgUmVnaXN0ZXJpbmcgYW5kICAgICAgICAgICAgICAgICAgICAgICAgIHVzaW5nIHRoaXMgc2l0ZSAgICAgICAgICAgICAgICAgICAgICAgICB5b3UgYWdyZWUgdG8gYWJpZGUgICAgICAgICAgICAgICAgICAgICAgYnkgdGhlIHN5c3RlbSAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1bGVzLiBWaWV3IHRob3NlICAgICAgICAgICAgICAgICAgICAgICBydWxlcyBvbgIqOTg4XyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA==","isPublic":1,"isAccessible":1,"type":"l","key":[98,"sqrllogin",98,98,null,null,null,null,null,null],"frame_fields": [],"date":"2020-08-09T11:42:40.643Z"} {"version":1,"frame":"982","index":"a","owner":9,"cost":0,"content":"ICARLGwSfGwUfCwTLBc3a38jMzdrIzUgICAgICACMDAwMTAwMDEwMSAgEX9rEn9qFC98E38XNWhvIDw9JCw1ByAgICAgICAgICAgICAgICAgIBEvLhIvKhQsLxMvF3VwenBxdXpwNSAgICAgICAgICAgICAgICAgICAgVmlkZW90ZXggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVG8gY29tcGxldGUgdGhlICAgICAgICAgICAgICAgICAgICAgICAgIGF1dGhlbnRpY2F0aW9uLCAgICAgICAgICAgICAgICAgICAgICAgICB1c2UgeW91ciBTUVJMIGFwcCAgICAgICAgA0hPTEQgVElHSFQgICAgYW5kIHNjYW4gdGhlIFFSICAgICAgICAgA1dISUxFIFdFIEdFVCAgIGNvZGUuICAgICAgICAgICAgICAgICAgIANZT1UgQSBRUkNPREUgICAgICAgICAgICAgICAgICAgICAgICAgIAMobWF5IHRha2UgMzBzKSAgUmVnaXN0ZXJpbmcgYW5kICAgICAgICAgICAgICAgICAgICAgICAgIHVzaW5nIHRoaXMgc2l0ZSAgICAgICAgICAgICAgICAgICAgICAgICB5b3UgYWdyZWUgdG8gYWJpZGUgICAgICAgICAgICAgICAgICAgICAgYnkgdGhlIHN5c3RlbSAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1bGVzLiBWaWV3IHRob3NlICAgICAgICAgICAgICAgICAgICAgICBydWxlcyBvbgIqOTg4XyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA==","isPublic":1,"isAccessible":1,"type":"l","key":[null,"sqrllogin",null,null,null,null,null,null,null,null],"frame_fields": [],"date":"2020-08-09T11:42:40.643Z"}