Skip to content

Commit

Permalink
Add the ability to follow Mastodon account
Browse files Browse the repository at this point in the history
  • Loading branch information
wiktor-k committed Nov 26, 2019
1 parent 99093a5 commit c2919b0
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 5 deletions.
10 changes: 10 additions & 0 deletions index.html
Expand Up @@ -8,12 +8,22 @@
<link rel=pgpkey href="https://metacode.biz/.well-known/openpgpkey/hu/gebusffkx9g581i6ch4t3ewgwd6dctmp">
-->
<meta name=keyserver content=keys.openpgp.org>
<meta name=proofs content=/openpgp/proofs.json>
<style>
body { line-height: 1.7; max-width: 800px; margin: 0 auto}
main { margin: 20px; }
.props { list-style-type: none; margin-left: 0; padding-left: 0; }
i { padding-right: 5px; }
.proof { font-size: small; margin-left: 10px; color: #73a6ff }
.follow { font-size: small; margin-left: 10px;
background-color: #2b90d9;
color: white;
padding: 3px 6px;
border-radius: 3px;
border: none;
text-decoration: none; }
.follow:hover { background-color: #419bdd }
.follow:active { box-shadow: inset 0 0 2px #000000;}
.verification { font-size: small; margin-left: 5px; cursor: pointer }
summary { cursor: pointer }
.verified { color: green }
Expand Down
39 changes: 36 additions & 3 deletions openpgp-key.tsx
Expand Up @@ -97,7 +97,8 @@ async function loadKeys(keyUrl: string, _keys: any) {
expirationTime: lastPrimarySig.getExpirationTime()
}];

const p = (await (await fetch('proofs.json')).json()).proofs;
const proofsUrl = (document.querySelector('meta[name="proofs"]') as HTMLMetaElement).content;
const p = (await (await fetch(proofsUrl)).json()).proofs;
const notations: [string, any][] = lastPrimarySig.notations || [];
const proofs = notations
.filter(notation => notation[0] === 'proof@metacode.biz' && typeof notation[1] === 'string')
Expand Down Expand Up @@ -147,8 +148,8 @@ async function checkProofs() {
const checks = JSON.parse(proofLink.dataset.checks || '');
const url = proofLink.dataset.proofJson || '';
try {
await verify(url, checks);
proofLink.textContent = 'verified proof';
await verify(await getJson(url), checks);
proofLink.textContent = 'verified';
proofLink.classList.add('verified');
} catch(e) {
console.error('Could not verify proof: ' + e);
Expand Down Expand Up @@ -180,6 +181,38 @@ async function clickElement(this: any, e: Event) {
});
console.log(verified);
alert('The signature is ' + (verified.signatures[0].valid ? '✅ correct.' : '❌ incorrect.'));
} else if (target.classList.contains('follow')) {
e.preventDefault();
const url = target.dataset.profile;
const handle: string = (prompt(`You are going to follow ${url}.\n\nEnter your username@domain to proceed.`) || '');
if (!handle) {
return;
}
const parts = handle.split('@');
const domain = encodeURIComponent(parts.pop() || '');
const username = encodeURIComponent(parts.pop() || '');
if (!domain || !username) {
alert('Could not recognize account: ' + handle);
return;
}
fetch(`https://${domain}/.well-known/webfinger?resource=acct:${username}@${domain}`, {
headers: {
accept: 'application/json'
}
}).then(response => {
if (response.ok) {
return response.json()
}
throw new Error('Request failed: ' + response.statusText);
}).then(json => {
const { template } = json.links.filter((link: any) => link.rel === 'http://ostatus.org/schema/1.0/subscribe')[0];
if (!template) {
throw new Error('No subscription address.');
}
location.href = template.replace('{uri}', encodeURIComponent(url) || '');
}).catch(e => {
alert('Could not complete action: ' + e);
});
}
}

Expand Down
41 changes: 39 additions & 2 deletions scripts.js
Expand Up @@ -302,6 +302,9 @@ System.register("ui", ["local", "openpgp"], function (exports_5, context_5) {
local.createElement("a", { rel: "me noopener nofollow", target: "_blank", href: proof.profile },
local.createElement("i", { class: serviceToClassName(proof.service) }),
proof.username),
proof.service === 'mastodon' ?
local.createElement("a", { rel: "noopener nofollow", href: "#follow", class: "follow", "data-profile": proof.profile }, "follow")
: null,
local.createElement("a", { rel: "noopener nofollow", target: "_blank", href: proof.proofUrl, class: "proof", "data-proof-json": proof.proofJson, "data-checks": JSON.stringify(proof.checks) },
local.createElement("i", { class: "fas fa-certificate" }),
"proof")))))),
Expand Down Expand Up @@ -446,7 +449,8 @@ System.register("openpgp-key", ["local", "renderer", "verifier", "openpgp", "ui"
algorithmInfo: key.primaryKey.getAlgorithmInfo(),
expirationTime: lastPrimarySig.getExpirationTime()
}];
const p = (await (await fetch('proofs.json')).json()).proofs;
const proofsUrl = document.querySelector('meta[name="proofs"]').content;
const p = (await (await fetch(proofsUrl)).json()).proofs;
const notations = lastPrimarySig.notations || [];
const proofs = notations
.filter(notation => notation[0] === 'proof@metacode.biz' && typeof notation[1] === 'string')
Expand Down Expand Up @@ -493,7 +497,7 @@ System.register("openpgp-key", ["local", "renderer", "verifier", "openpgp", "ui"
const url = proofLink.dataset.proofJson || '';
try {
await verifier_2.verify(await verifier_2.getJson(url), checks);
proofLink.textContent = 'verified proof';
proofLink.textContent = 'verified';
proofLink.classList.add('verified');
}
catch (e) {
Expand Down Expand Up @@ -528,6 +532,39 @@ System.register("openpgp-key", ["local", "renderer", "verifier", "openpgp", "ui"
console.log(verified);
alert('The signature is ' + (verified.signatures[0].valid ? '✅ correct.' : '❌ incorrect.'));
}
else if (target.classList.contains('follow')) {
e.preventDefault();
const url = target.dataset.profile;
const handle = (prompt(`You are going to follow ${url}.\n\nEnter your username@domain to proceed.`) || '');
if (!handle) {
return;
}
const parts = handle.split('@');
const domain = encodeURIComponent(parts.pop() || '');
const username = encodeURIComponent(parts.pop() || '');
if (!domain || !username) {
alert('Could not recognize account: ' + handle);
return;
}
fetch(`https://${domain}/.well-known/webfinger?resource=acct:${username}@${domain}`, {
headers: {
accept: 'application/json'
}
}).then(response => {
if (response.ok) {
return response.json();
}
throw new Error('Request failed: ' + response.statusText);
}).then(json => {
const { template } = json.links.filter((link) => link.rel === 'http://ostatus.org/schema/1.0/subscribe')[0];
if (!template) {
throw new Error('No subscription address.');
}
location.href = template.replace('{uri}', encodeURIComponent(url) || '');
}).catch(e => {
alert('Could not complete action: ' + e);
});
}
}
return {
setters: [
Expand Down
3 changes: 3 additions & 0 deletions ui.tsx
Expand Up @@ -93,6 +93,9 @@ export function renderInfo(keyUrl: string, name: string, emails: string[], profi
<li>
<a rel="me noopener nofollow" target="_blank" href={proof.profile}>
<i class={serviceToClassName(proof.service)}></i>{proof.username}</a>
{proof.service === 'mastodon' ?
<a rel="noopener nofollow" href="#follow" class="follow" data-profile={proof.profile}>follow</a>
: null}
<a rel="noopener nofollow" target="_blank" href={proof.proofUrl} class="proof" data-proof-json={proof.proofJson} data-checks={JSON.stringify(proof.checks)}>
<i class="fas fa-certificate"></i>proof</a>
</li>
Expand Down

0 comments on commit c2919b0

Please sign in to comment.