2022-02-25 03:44:50 -07:00
/ *
Copyright ( C ) 2021 Yarmo Mackenbach
This program is free software : you can redistribute it and / or modify it under
the terms of the GNU Affero General Public License as published by the Free
Software Foundation , either version 3 of the License , or ( at your option )
any later version .
This program is distributed in the hope that it will be useful , but WITHOUT
ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE . See the GNU Affero General Public License for more
details .
You should have received a copy of the GNU Affero General Public License along
with this program . If not , see < https : //www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail .
If your software can interact with users remotely through a computer network ,
you should also make sure that it provides a way for users to get its source .
For example , if your program is a web application , its interface could display
a "Source" link that leads users to an archive of the code . There are many
ways you could offer source , and different solutions will be better for different
programs ; see section 13 for the specific requirements .
You should also get your employer ( if you work as a programmer ) or school ,
if any , to sign a "copyright disclaimer" for the program , if necessary . For
more information on this , and how to apply and follow the GNU AGPL , see < https : //www.gnu.org/licenses/>.
* /
2021-05-02 04:49:52 -06:00
class Claim extends HTMLElement {
// Specify the attributes to observe
static get observedAttributes ( ) {
return [ 'data-claim' ] ;
}
constructor ( ) {
// Call super
super ( ) ;
}
attributeChangedCallback ( name , oldValue , newValue ) {
this . updateContent ( newValue ) ;
}
async verify ( ) {
const claim = new doip . Claim ( JSON . parse ( this . getAttribute ( 'data-claim' ) ) ) ;
await claim . verify ( {
proxy : {
policy : 'adaptive' ,
hostname : 'PLACEHOLDER__PROXY_HOSTNAME'
}
} ) ;
this . setAttribute ( 'data-claim' , JSON . stringify ( claim ) ) ;
}
updateContent ( value ) {
2021-05-04 05:57:33 -06:00
const root = this ;
2021-05-02 04:49:52 -06:00
const claim = new doip . Claim ( JSON . parse ( value ) ) ;
switch ( claim . matches [ 0 ] . serviceprovider . name ) {
case 'dns' :
case 'xmpp' :
case 'irc' :
2021-05-04 05:57:33 -06:00
root . querySelector ( '.info .subtitle' ) . innerText = claim . matches [ 0 ] . serviceprovider . name . toUpperCase ( ) ;
2021-05-02 04:49:52 -06:00
break ;
default :
2021-05-04 05:57:33 -06:00
root . querySelector ( '.info .subtitle' ) . innerText = claim . matches [ 0 ] . serviceprovider . name ;
2021-05-02 04:49:52 -06:00
break ;
}
2021-05-04 05:57:33 -06:00
root . querySelector ( '.info .title' ) . innerText = claim . matches [ 0 ] . profile . display ;
2021-05-02 04:49:52 -06:00
try {
if ( claim . status === 'verified' ) {
2021-05-04 05:57:33 -06:00
root . querySelector ( '.icons .verificationStatus' ) . setAttribute ( 'data-value' , claim . verification . result ? 'success' : 'failed' ) ;
2021-05-02 04:49:52 -06:00
} else {
2021-05-04 05:57:33 -06:00
root . querySelector ( '.icons .verificationStatus' ) . setAttribute ( 'data-value' , 'running' ) ;
2021-05-02 04:49:52 -06:00
}
} catch ( error ) {
2021-05-04 05:57:33 -06:00
root . querySelector ( '.icons .verificationStatus' ) . setAttribute ( 'data-value' , 'failed' ) ;
2021-05-02 04:49:52 -06:00
}
2021-05-04 05:57:33 -06:00
const elContent = root . querySelector ( '.content' ) ;
2021-05-02 04:49:52 -06:00
elContent . innerHTML = ` ` ;
// Handle failed ambiguous claim
if ( claim . status === 'verified' && ! claim . verification . result && claim . isAmbiguous ( ) ) {
2021-05-04 05:57:33 -06:00
root . querySelector ( '.info .subtitle' ) . innerText = '---' ;
2021-05-02 04:49:52 -06:00
2021-05-03 03:48:48 -06:00
const subsection _alert = elContent . appendChild ( document . createElement ( 'div' ) ) ;
subsection _alert . setAttribute ( 'class' , 'subsection' ) ;
const subsection _alert _icon = subsection _alert . appendChild ( document . createElement ( 'img' ) ) ;
subsection _alert _icon . setAttribute ( 'src' , '/static/img/alert-decagram.png' ) ;
2021-06-07 03:47:09 -06:00
subsection _alert _icon . setAttribute ( 'alt' , '' ) ;
2021-06-07 03:56:29 -06:00
subsection _alert _icon . setAttribute ( 'aria-hidden' , 'true' ) ;
2021-05-03 03:48:48 -06:00
const subsection _alert _text = subsection _alert . appendChild ( document . createElement ( 'div' ) ) ;
2021-05-02 04:49:52 -06:00
2021-05-03 03:48:48 -06:00
const message = subsection _alert _text . appendChild ( document . createElement ( 'p' ) ) ;
2021-05-02 05:06:18 -06:00
message . innerHTML = ` None of the matched service providers could be verified. Keyoxide was not able to determine which was the correct service provider or why the verification process failed. ` ;
2021-05-02 04:49:52 -06:00
return ;
}
// Links to profile and proof
2021-05-03 03:48:48 -06:00
const subsection _links = elContent . appendChild ( document . createElement ( 'div' ) ) ;
subsection _links . setAttribute ( 'class' , 'subsection' ) ;
const subsection _links _icon = subsection _links . appendChild ( document . createElement ( 'img' ) ) ;
subsection _links _icon . setAttribute ( 'src' , '/static/img/link.png' ) ;
2021-06-07 03:47:09 -06:00
subsection _links _icon . setAttribute ( 'alt' , '' ) ;
2021-06-07 03:56:29 -06:00
subsection _links _icon . setAttribute ( 'aria-hidden' , 'true' ) ;
2021-05-03 03:48:48 -06:00
const subsection _links _text = subsection _links . appendChild ( document . createElement ( 'div' ) ) ;
2021-05-02 04:49:52 -06:00
2021-05-03 03:48:48 -06:00
const profile _link = subsection _links _text . appendChild ( document . createElement ( 'p' ) ) ;
2021-05-02 04:49:52 -06:00
if ( claim . matches [ 0 ] . profile . uri ) {
2021-06-09 05:58:36 -06:00
profile _link . innerHTML = ` Profile link: <a rel="me" href=" ${ claim . matches [ 0 ] . profile . uri } " aria-label="link to profile"> ${ claim . matches [ 0 ] . profile . uri } </a> ` ;
2021-05-02 04:49:52 -06:00
} else {
profile _link . innerHTML = ` Profile link: not accessible from browser ` ;
}
2021-05-03 03:48:48 -06:00
const proof _link = subsection _links _text . appendChild ( document . createElement ( 'p' ) ) ;
2021-05-02 04:49:52 -06:00
if ( claim . matches [ 0 ] . proof . uri ) {
2021-06-09 05:58:36 -06:00
proof _link . innerHTML = ` Proof link: <a href=" ${ claim . matches [ 0 ] . proof . uri } " aria-label="link to profile"> ${ claim . matches [ 0 ] . proof . uri } </a> ` ;
2021-05-02 04:49:52 -06:00
} else {
proof _link . innerHTML = ` Proof link: not accessible from browser ` ;
}
2021-05-03 03:48:48 -06:00
// QR Code
if ( claim . matches [ 0 ] . profile . qr ) {
elContent . appendChild ( document . createElement ( 'hr' ) ) ;
const subsection _qr = elContent . appendChild ( document . createElement ( 'div' ) ) ;
subsection _qr . setAttribute ( 'class' , 'subsection' ) ;
const subsection _qr _icon = subsection _qr . appendChild ( document . createElement ( 'img' ) ) ;
subsection _qr _icon . setAttribute ( 'src' , '/static/img/qrcode.png' ) ;
2021-06-07 03:47:09 -06:00
subsection _qr _icon . setAttribute ( 'alt' , '' ) ;
2021-06-07 03:56:29 -06:00
subsection _qr _icon . setAttribute ( 'aria-hidden' , 'true' ) ;
2021-05-03 03:48:48 -06:00
const subsection _qr _text = subsection _qr . appendChild ( document . createElement ( 'div' ) ) ;
const button _profileQR = subsection _qr _text . appendChild ( document . createElement ( 'button' ) ) ;
button _profileQR . innerText = ` Show profile QR ` ;
2021-05-03 04:06:37 -06:00
button _profileQR . setAttribute ( 'onClick' , ` showQR(' ${ claim . matches [ 0 ] . profile . qr } ', 'url') ` ) ;
2021-06-09 05:58:36 -06:00
button _profileQR . setAttribute ( 'aria-label' , ` Show QR code linking to profile ` ) ;
2021-05-03 03:48:48 -06:00
}
2021-05-02 04:49:52 -06:00
elContent . appendChild ( document . createElement ( 'hr' ) ) ;
// Claim verification status
2021-05-03 03:48:48 -06:00
const subsection _status = elContent . appendChild ( document . createElement ( 'div' ) ) ;
subsection _status . setAttribute ( 'class' , 'subsection' ) ;
const subsection _status _icon = subsection _status . appendChild ( document . createElement ( 'img' ) ) ;
subsection _status _icon . setAttribute ( 'src' , '/static/img/decagram.png' ) ;
2021-06-07 03:47:09 -06:00
subsection _status _icon . setAttribute ( 'alt' , '' ) ;
2021-06-07 03:56:29 -06:00
subsection _status _icon . setAttribute ( 'aria-hidden' , 'true' ) ;
2021-05-03 03:48:48 -06:00
const subsection _status _text = subsection _status . appendChild ( document . createElement ( 'div' ) ) ;
2021-05-02 04:49:52 -06:00
2021-05-03 03:48:48 -06:00
const verification = subsection _status _text . appendChild ( document . createElement ( 'p' ) ) ;
2021-05-02 04:49:52 -06:00
if ( claim . status === 'verified' ) {
verification . innerHTML = ` Claim verification has completed. ` ;
2021-05-03 03:48:48 -06:00
subsection _status _icon . setAttribute ( 'src' , '/static/img/check-decagram.png' ) ;
2021-06-07 03:47:09 -06:00
subsection _status _icon . setAttribute ( 'alt' , '' ) ;
2021-06-07 03:56:29 -06:00
subsection _status _icon . setAttribute ( 'aria-hidden' , 'true' ) ;
2021-05-02 04:49:52 -06:00
} else {
verification . innerHTML = ` Claim verification is in progress… ` ;
return ;
}
elContent . appendChild ( document . createElement ( 'hr' ) ) ;
// Result of claim verification
2021-05-03 03:48:48 -06:00
const subsection _result = elContent . appendChild ( document . createElement ( 'div' ) ) ;
subsection _result . setAttribute ( 'class' , 'subsection' ) ;
const subsection _result _icon = subsection _result . appendChild ( document . createElement ( 'img' ) ) ;
subsection _result _icon . setAttribute ( 'src' , '/static/img/shield-search.png' ) ;
2021-06-07 03:47:09 -06:00
subsection _result _icon . setAttribute ( 'alt' , '' ) ;
2021-06-07 03:56:29 -06:00
subsection _result _icon . setAttribute ( 'aria-hidden' , 'true' ) ;
2021-05-03 03:48:48 -06:00
const subsection _result _text = subsection _result . appendChild ( document . createElement ( 'div' ) ) ;
2021-05-02 04:49:52 -06:00
2021-05-03 03:48:48 -06:00
const result = subsection _result _text . appendChild ( document . createElement ( 'p' ) ) ;
2021-05-02 04:49:52 -06:00
result . innerHTML = ` The claim <strong> ${ claim . verification . result ? 'HAS BEEN' : 'COULD NOT BE' } </strong> verified by the proof. ` ;
// Additional info
if ( claim . verification . proof . viaProxy ) {
elContent . appendChild ( document . createElement ( 'hr' ) ) ;
2021-05-03 03:48:48 -06:00
const subsection _info = elContent . appendChild ( document . createElement ( 'div' ) ) ;
subsection _info . setAttribute ( 'class' , 'subsection' ) ;
const subsection _info _icon = subsection _info . appendChild ( document . createElement ( 'img' ) ) ;
subsection _info _icon . setAttribute ( 'src' , '/static/img/information.png' ) ;
2021-06-07 03:47:09 -06:00
subsection _info _icon . setAttribute ( 'alt' , '' ) ;
2021-06-07 03:56:29 -06:00
subsection _info _icon . setAttribute ( 'aria-hidden' , 'true' ) ;
2021-05-03 03:48:48 -06:00
const subsection _info _text = subsection _info . appendChild ( document . createElement ( 'div' ) ) ;
2021-05-02 04:49:52 -06:00
2021-05-03 03:48:48 -06:00
const result _proxyUsed = subsection _info _text . appendChild ( document . createElement ( 'p' ) ) ;
2021-06-09 05:58:36 -06:00
result _proxyUsed . innerHTML = ` A proxy was used to fetch the proof: <a href="https://PLACEHOLDER__PROXY_HOSTNAME" aria-label="Link to proxy server">PLACEHOLDER__PROXY_HOSTNAME</a> ` ;
2021-05-02 04:49:52 -06:00
}
// TODO Display errors
// if (claim.verification.errors.length > 0) {
// console.log(claim.verification);
// elContent.appendChild(document.createElement('hr'));
2021-05-03 03:48:48 -06:00
// const subsection_errors = elContent.appendChild(document.createElement('div'));
// subsection_errors.setAttribute('class', 'subsection');
// const subsection_errors_icon = subsection_errors.appendChild(document.createElement('img'));
// subsection_errors_icon.setAttribute('src', '/static/img/alert-circle.png');
// const subsection_errors_text = subsection_errors.appendChild(document.createElement('div'));
2021-05-02 04:49:52 -06:00
// claim.verification.errors.forEach(message => {
2021-05-03 03:48:48 -06:00
// const error = subsection_errors_text.appendChild(document.createElement('p'));
2021-05-02 04:49:52 -06:00
// if (message instanceof Error) {
// error.innerText = message.message;
// } else {
// error.innerText = message;
// }
// });
// }
}
}
customElements . define ( 'kx-claim' , Claim ) ;