function toggle_outlet(svg) { let sub_dev = svg.parentElement; let params = { device_id: sub_dev.parentElement.parentElement.id, sub_dev_id: sub_dev.id }; let query = Object.keys(params) .map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k])) .join('&'); fetch(window.location.href + 'toggle?' + query) .then(function(response) { return response.json(); }) .then(function(json) { if (!json.ok) { throw new Error('HTTP error, status = ' + json.status + ', message = ' + json.message); } if (json[sub_dev.id]) { svg.classList.remove('off'); svg.classList.add('on'); } else { svg.classList.remove('on'); svg.classList.add('off'); } }); } function edit_field(field) { let value = field.firstElementChild.innerText; let input = document.createElement('input'); input.value = value; field.firstElementChild.replaceWith(input); let save = document.createElement('span'); save.innerHTML = ''; save.className = 'save'; save.setAttribute('onclick', 'save_field(this.parentElement)'); field.children[1].replaceWith(save); } function save_field(field) { let value = field.firstElementChild.value; let device_id = field.parentElement.id; let sub_dev_id; if (field.parentElement.className.includes('sub_device')) { sub_dev_id = device_id; device_id = field.parentElement.parentElement.parentElement.id; } else { sub_dev_id = ''; } let params = { device_id: device_id, sub_dev_id: sub_dev_id, field: field.className, value: value }; let query = Object.keys(params) .map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k])) .join('&'); fetch(window.location.href + 'edit?' + query) .then(function(response) { return response.json(); }) .then(function(json) { if (!json.ok) { throw new Error('HTTP error, status = ' + json.status + ', message = ' + json.message); } let span = document.createElement('span'); span.innerText = json['value']; span.className = 'field_value'; field.firstElementChild.replaceWith(span); let edit = document.createElement('span'); edit.innerHTML = ''; edit.className = 'edit'; edit.setAttribute('onclick', 'edit_field(this.parentElement)'); field.children[1].replaceWith(edit); }); } function register() { fetch(url_prefix + '/api/register/begin', { method: 'POST', }).then(function(response) { if(!response.ok) { throw new Error('Error getting registration data!'); } return response.arrayBuffer(); }).then(CBOR.decode).then(function(options) { return navigator.credentials.create(options); }).then(function(attestation) { return fetch(url_prefix + '/api/register/complete', { method: 'POST', headers: {'Content-Type': 'application/cbor'}, body: CBOR.encode({ "attestationObject": new Uint8Array(attestation.response.attestationObject), "clientDataJSON": new Uint8Array(attestation.response.clientDataJSON), }) }); }).then(function(response) { let stat = response.ok ? 'successful' : 'unsuccessful'; alert('Registration ' + stat + ' More details in server log...'); }, function(reason) { alert(reason); }).then(function() { window.location = url_prefix; }); } function login() { fetch(url_prefix + '/api/authenticate/begin', { method: 'POST', }).then(function(response) { if(!response.ok) { throw new Error('No credential available to authenticate!'); } return response.arrayBuffer(); }).then(CBOR.decode).then(function(options) { return navigator.credentials.get(options); }).then(function(assertion) { return fetch(url_prefix + '/api/authenticate/complete', { method: 'POST', headers: {'Content-Type': 'application/cbor'}, body: CBOR.encode({ "credentialId": new Uint8Array(assertion.rawId), "authenticatorData": new Uint8Array(assertion.response.authenticatorData), "clientDataJSON": new Uint8Array(assertion.response.clientDataJSON), "signature": new Uint8Array(assertion.response.signature) }) }) }).then(function(response) { let stat = response.ok ? 'successful' : 'unsuccessful'; alert('Authentication ' + stat + ' More details in server log...'); }, function(reason) { alert(reason); }).then(function() { window.location = url_prefix; }); }