clean up and add affiliates

This commit is contained in:
Amolith 2019-12-08 16:12:55 -05:00
parent aa5e436c1b
commit efacc8eba5
Signed by: Amolith
GPG Key ID: CA3EFC40662C19BA
7 changed files with 83 additions and 43537 deletions

37
affiliates.md Normal file
View File

@ -0,0 +1,37 @@
---
layout: page
title: Affiliates
subtitle: Support NixNet by making purchases and using these links
description: Support NixNet by making purchases with affiliate links and vouchers
---
One of the easiest ways to support NixNet is to purchase products on these websites using the provided affiliate links.
# netcup
[netcup](https://netcup.eu) is currently where the most services are running. They have fantastic offerings at most price points and incredible deals. I've been very happy with their service and *highly* recommend them.
## Voucher codes
These are single-use vouchers for various products. When you use one, please [send me a message](/contact) so I can generate a new one.
### 5€ for anything except domains
* [36nc15758387844](https://www.netcup.eu/bestellen/gutschein_einloesen.php?gutschein=36nc15758387844)
* [36nc15758387843](https://www.netcup.eu/bestellen/gutschein_einloesen.php?gutschein=36nc15758387843)
* [36nc15758387842](https://www.netcup.eu/bestellen/gutschein_einloesen.php?gutschein=36nc15758387842)
* [36nc15758387841](https://www.netcup.eu/bestellen/gutschein_einloesen.php?gutschein=36nc15758387841)
* [36nc15758387840](https://www.netcup.eu/bestellen/gutschein_einloesen.php?gutschein=36nc15758387840)
### 10% off the 200 G8
* [2052nc15758390090](https://www.netcup.eu/bestellen/gutschein_einloesen.php?gutschein=2052nc15758390090)
* [2052nc15758390091](https://www.netcup.eu/bestellen/gutschein_einloesen.php?gutschein=2052nc15758390091)
### 10% off the 500 G8
* [2053nc15758393980](https://www.netcup.eu/bestellen/gutschein_einloesen.php?gutschein=2053nc15758393980)
* [2053nc15758393981](https://www.netcup.eu/bestellen/gutschein_einloesen.php?gutschein=2053nc15758393981)
### 10% off the 1000 G8
* [2054nc15758394201](https://www.netcup.eu/bestellen/gutschein_einloesen.php?gutschein=2054nc15758394201)
* [2054nc15758394200](https://www.netcup.eu/bestellen/gutschein_einloesen.php?gutschein=2054nc15758394200)
### 10% off the 2000 G8
* [2056nc15758394800](https://www.netcup.eu/bestellen/gutschein_einloesen.php?gutschein=2056nc15758394800)
* [2056nc15758394801](https://www.netcup.eu/bestellen/gutschein_einloesen.php?gutschein=2056nc15758394801)

108
app.js
View File

@ -1,108 +0,0 @@
$(function(){
var model = {
// renomear
dat: [
],
read_json: function() {
$.ajax({
url: "/cards.json",
dataType: 'json',
async: false,
success: function(data) {
$(data["cards"]).each(function(){
var card_info = $(this)[0];
model.set_data(card_info);
});
}
});
},
set_data: function(d) {
model.dat.push(d);
},
get_data: function() {
return model.dat;
},
filter_data: function(conteudo) {
var $d = model.dat;
var $filter = [];
var $c = conteudo.toLowerCase();
$($d).each(function(i){
if(
$d[i].name.toLowerCase().indexOf($c) >= 0 ||
$d[i].description.toLowerCase().indexOf($c) >= 0 ||
$d[i].button_text.toLowerCase().indexOf($c) >= 0
) {
$filter.push($d[i]);
}
});
return $filter;
},
init: function() {
model.read_json();
}
};
var octopus = {
init: function() {
model.init();
view.init();
octopus.create_card(model.get_data());
},
create_card: function(d) {
$.each(d, function(i){
view.create_card(d[i].name, d[i].description, d[i].button_text, d[i].link, d[i].tor);
});
},
filter_data: function(c) {
var d = model.filter_data(c);
$.each(d, function(i){
view.create_card(d[i].name, d[i].description, d[i].button_text, d[i].link, d[i].tor);
});
},
recreate_cards: function() {
octopus.create_card(model.get_data());
}
};
// Renomear
var view = {
init: function() {
this.container = $(".flex-cards");
this.search_field = $("#search_field");
view.events();
},
events: function(){
this.search_field.on('input',function(){
var $conteudo = $(this).val();
view.clean_cards();
if($conteudo.length == 0){
octopus.recreate_cards();
}else {
octopus.filter_data($conteudo);
}
});
},
create_card: function(name, desc, bt_txt, link, tor){
var $card = $("<div>").addClass("card");
var $h1 = $("<h1>").text(name);
var $desc = $("<p>").text(desc);
var $button = $("<button>").addClass("button").text(bt_txt);
var $icon = $("<button>").addClass("tor").text("Tor");
var $a = $("<a>").attr("href", link);
var $tor = $("<a>").attr("href", tor);
$a.append($button);
$tor.append($icon);
if (tor == "#") {
$card.append($h1).append($desc).append($a);
} else {
$card.append($h1).append($desc).append($a).append($tor);
}
this.container.append($card);
},
clean_cards: function() {
this.container.empty();
}
};
octopus.init();
});

View File

@ -9,14 +9,14 @@
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="158.75mm"
height="83.34375mm"
viewBox="0 0 158.75 83.34375"
width="315"
height="315"
viewBox="0 0 83.343752 83.343752"
version="1.1"
id="svg8"
inkscape:export-filename="/home/amolith/repos/nixnet/logo.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
inkscape:export-filename="/tmp/sticker.png"
inkscape:export-xdpi="152.38"
inkscape:export-ydpi="152.38"
inkscape:version="0.92.4 5da689c313, 2019-01-14"
sodipodi:docname="logo.svg">
<defs
@ -28,10 +28,10 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="339.47007"
inkscape:cy="163.84677"
inkscape:document-units="mm"
inkscape:zoom="0.70710678"
inkscape:cx="54.864303"
inkscape:cy="98.02578"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
showborder="false"
@ -40,11 +40,22 @@
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1366"
inkscape:window-height="768"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0" />
inkscape:window-width="1336"
inkscape:window-height="698"
inkscape:window-x="15"
inkscape:window-y="35"
inkscape:window-maximized="0"
units="px"
inkscape:snap-bbox="true"
inkscape:bbox-paths="true"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:snap-bbox-midpoints="true"
inkscape:snap-nodes="true"
inkscape:object-paths="true"
inkscape:snap-intersection-paths="true"
inkscape:snap-smooth-nodes="true"
inkscape:snap-midpoints="true" />
<metadata
id="metadata5">
<rdf:RDF>
@ -61,17 +72,15 @@
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-128.38222,22.853529)">
<rect
style="opacity:1;fill:#333333;fill-opacity:1;stroke:none;stroke-width:0.31644166;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect95912"
width="158.75"
height="83.34375"
x="128.38222"
y="-22.853529" />
transform="translate(-128.38222,22.853531)">
<path
style="fill:#333333;fill-opacity:1;stroke:none;stroke-width:1.8438884;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 211.72597,18.818345 A 41.671876,41.671872 0 0 1 170.0541,60.490217 41.671876,41.671872 0 0 1 128.38222,18.818345 41.671876,41.671872 0 0 1 170.0541,-22.853527 41.671876,41.671872 0 0 1 211.72597,18.818345 Z"
id="path96013"
inkscape:connector-curvature="0" />
<g
id="g95919"
transform="matrix(0.84116788,0,0,0.84116788,14.976495,1.9821852)">
transform="matrix(0.78478307,0,0,0.78478307,-9.8042309,3.1107386)">
<path
inkscape:connector-curvature="0"
id="rect819"
@ -102,5 +111,18 @@
d="m 229.04267,-5.1482062 c 2.02111,0 3.64822,1.6165249 3.64822,3.6244951 V 41.226748 c 0,2.00797 -1.62711,3.624495 -3.64822,3.624495 -2.02112,0 -3.64823,-1.616525 -3.64823,-3.624495 V -1.5237111 c 0,-2.0079702 1.62711,-3.6244951 3.64823,-3.6244951 z"
style="opacity:1;fill:#b3b3b3;fill-opacity:1;stroke:none;stroke-width:0.01318607;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.58333397px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458335"
x="-198.78204"
y="80.002522"
id="text96064"><tspan
sodipodi:role="line"
id="tspan96062">hello world</tspan></text>
<path
style="fill:none;stroke:#333333;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 136.67061,43.760032 c 0,0 31.75567,37.773979 66.76697,0"
id="path96072"
inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -1,4 +0,0 @@
{
"title": "NixNet",
"description": "NixNet.xyz is a network of websites and services hosted by the pseudonymous Amolith (me). It's also a blog!"
}

BIN
logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

42864
openpgp.js

File diff suppressed because one or more lines are too long

View File

@ -1,537 +0,0 @@
System.register("local", [], function (exports_1, context_1) {
"use strict";
var __moduleName = context_1 && context_1.id;
function createElement(name, attributes, ...children) {
return {
name,
attributes: attributes || {},
children: Array.prototype.concat(...(children || []))
};
}
exports_1("createElement", createElement);
return {
setters: [],
execute: function () {
}
};
});
System.register("renderer", [], function (exports_2, context_2) {
"use strict";
var __moduleName = context_2 && context_2.id;
function render(element) {
if (element == null)
return '';
if (typeof element !== "object")
element = String(element);
if (typeof element === "string")
return element.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
//if (element instanceof Raw) return element.html;
console.assert(!!element.attributes, 'Element attributes must be defined:\n' + JSON.stringify(element));
const elementAttributes = element.attributes;
let attributes = Object.keys(elementAttributes).filter(key => {
const value = elementAttributes[key];
return value != null;
}).map(key => {
const value = elementAttributes[key];
if (value === true) {
return key;
}
return `${key}="${String(value).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;')}"`;
}).join(' ');
if (attributes.length > 0) {
attributes = ' ' + attributes;
}
const children = element.children.length > 0 ? `>${element.children.map(child => render(child)).join('')}` : '>';
return `<${element.name}${attributes}${children}</${element.name}>`;
}
exports_2("render", render);
return {
setters: [],
execute: function () {
}
};
});
/*
Copyright 2019 Wiktor Kwapisiewicz
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
System.register("openpgp-key", ["local", "renderer"], function (exports_3, context_3) {
"use strict";
var local, renderer, proofs, dateFormat;
var __moduleName = context_3 && context_3.id;
function getLatestSignature(signatures, date = new Date()) {
let signature = signatures[0];
for (let i = 1; i < signatures.length; i++) {
if (signatures[i].created >= signature.created &&
(signatures[i].created <= date || date === null)) {
signature = signatures[i];
}
}
return signature;
}
function getVerifier(proofUrl, fingerprint) {
for (const proof of proofs) {
const matches = proofUrl.match(proof.matcher);
if (!matches)
continue;
const bound = Object.entries(proof.variables).map(([key, value]) => [key, matches[value || 0]]).reduce((previous, current) => { previous[current[0]] = current[1]; return previous; }, { FINGERPRINT: fingerprint });
const profile = proof.profile.replace(/\{([A-Z]+)\}/g, (_, name) => bound[name]);
const proofJson = proof.proof.replace(/\{([A-Z]+)\}/g, (_, name) => bound[name]);
const username = proof.username.replace(/\{([A-Z]+)\}/g, (_, name) => bound[name]);
return {
profile,
proofUrl,
proofJson,
username,
service: proof.service,
checks: (proof.checks || []).map((check) => ({
relation: check.relation,
proof: check.proof,
claim: check.claim.replace(/\{([A-Z]+)\}/g, (_, name) => bound[name])
}))
};
}
return null;
}
async function verify(proofJson, checks) {
const response = await fetch(proofJson, {
headers: {
Accept: 'application/json'
},
credentials: 'omit'
});
if (!response.ok) {
throw new Error('Response failed: ' + response.status);
}
const json = await response.json();
for (const check of checks) {
const proofValue = check.proof.reduce((previous, current) => {
if (current == null || previous == null)
return null;
if (Array.isArray(previous) && typeof current === 'string') {
return previous.map(value => value[current]);
}
return previous[current];
}, json);
const claimValue = check.claim;
if (check.relation === 'eq') {
if (proofValue !== claimValue) {
throw new Error(`Proof value ${proofValue} !== claim value ${claimValue}`);
}
}
else if (check.relation === 'contains') {
if (!proofValue || proofValue.indexOf(claimValue) === -1) {
throw new Error(`Proof value ${proofValue} does not contain claim value ${claimValue}`);
}
}
else if (check.relation === 'oneOf') {
if (!proofValue || proofValue.indexOf(claimValue) === -1) {
throw new Error(`Proof value ${proofValue} does not contain claim value ${claimValue}`);
}
}
}
}
function serviceToClassName(service) {
if (service === 'github') {
return 'fab fa-github';
}
else if (service === 'reddit') {
return 'fab fa-reddit';
}
else if (service === 'hackernews') {
return 'fab fa-hacker-news';
}
else if (service === 'mastodon') {
return 'fab fa-mastodon';
}
else if (service === 'dns') {
return 'fas fa-globe';
}
else {
return '';
}
}
async function lookupKey(query) {
const result = document.getElementById('result');
result.innerHTML = renderer.render(local.createElement("span", null,
"Looking up ",
query,
"..."));
let keys, keyUrl;
const keyLink = document.querySelector('[rel="pgpkey"]');
if (!keyLink) {
const keyserver = document.querySelector('meta[name="keyserver"]').content;
keyUrl = `https://${keyserver}/pks/lookup?op=get&options=mr&search=${query}`;
const response = await fetch(keyUrl);
const key = await response.text();
keys = (await openpgp.key.readArmored(key)).keys;
}
else {
keyUrl = keyLink.href;
const response = await fetch(keyUrl);
const key = await response.arrayBuffer();
keys = (await openpgp.key.read(new Uint8Array(key))).keys;
}
if (keys.length > 0) {
loadKeys(keyUrl, keys).catch(e => {
result.innerHTML = renderer.render(local.createElement("span", null,
"Could not display this key: ",
String(e)));
});
}
else {
result.innerHTML = renderer.render(local.createElement("span", null,
query,
": not found"));
}
}
async function loadKeys(keyUrl, _keys) {
const key = _keys[0];
window.key = key;
const primaryUser = await key.getPrimaryUser();
for (var i = key.users.length - 1; i >= 0; i--) {
try {
if (await key.users[i].verify(key.primaryKey) === openpgp.enums.keyStatus.valid) {
continue;
}
}
catch (e) {
console.error('User verification error:', e);
}
//key.users.splice(i, 1);
}
for (const user of key.users) {
user.revoked = await user.isRevoked();
}
const lastPrimarySig = primaryUser.selfCertification;
const keys = [{
fingerprint: key.primaryKey.getFingerprint(),
status: await key.verifyPrimaryKey(),
keyFlags: lastPrimarySig.keyFlags,
created: key.primaryKey.created,
algorithmInfo: key.primaryKey.getAlgorithmInfo(),
expirationTime: lastPrimarySig.getExpirationTime()
}];
//console.log(lastPrimarySig);
const proofs = (lastPrimarySig.notations || [])
.filter((notation) => notation[0] === 'proof@metacode.biz' && typeof notation[1] === 'string')
.map((notation) => notation[1])
.map((proofUrl) => getVerifier(proofUrl, key.primaryKey.getFingerprint()))
.filter((verifier) => !!verifier);
/*
proofs.push(getVerifier('https://www.reddit.com/user/wiktor-k/comments/bo5oih/test/', key.primaryKey.getFingerprint()));
proofs.push(getVerifier('https://news.ycombinator.com/user?id=wiktor-k', key.primaryKey.getFingerprint()));
proofs.push(getVerifier('https://gist.github.com/wiktor-k/389d589dd19250e1f9a42bc3d5d40c16', key.primaryKey.getFingerprint()));
proofs.push(getVerifier('https://metacode.biz/@wiktor', key.primaryKey.getFingerprint()));
proofs.push(getVerifier('dns:metacode.biz?type=TXT', key.primaryKey.getFingerprint()));
*/
for (const subKey of key.subKeys) {
const lastSig = getLatestSignature(subKey.bindingSignatures);
let reasonForRevocation;
if (subKey.revocationSignatures.length > 0) {
reasonForRevocation = subKey.revocationSignatures[subKey.revocationSignatures.length - 1].reasonForRevocationString;
}
keys.push({
fingerprint: subKey.keyPacket.getFingerprint(),
status: await subKey.verify(key.primaryKey),
reasonForRevocation,
keyFlags: lastSig.keyFlags,
created: lastSig.created,
algorithmInfo: subKey.keyPacket.getAlgorithmInfo(),
expirationTime: await subKey.getExpirationTime()
});
}
//key.users.splice(primaryUser.index, 1);
const profileHash = await openpgp.crypto.hash.md5(openpgp.util.str_to_Uint8Array(primaryUser.user.userId.email)).then((u) => openpgp.util.str_to_hex(openpgp.util.Uint8Array_to_str(u)));
const now = new Date();
// there is index property on primaryUser
document.title = primaryUser.user.userId.name + ' - OpenPGP key';
const info = local.createElement("div", null,
local.createElement("div", { class: "wrapper" },
local.createElement("div", { class: "bio" },
local.createElement("img", { class: "avatar", src: "https://seccdn.libravatar.org/avatar/" + profileHash + "?s=148&d=" + encodeURIComponent("https://www.gravatar.com/avatar/" + profileHash + "?s=148&d=mm") }),
local.createElement("h2", null, primaryUser.user.userId.name)),
local.createElement("div", null,
local.createElement("ul", { class: "props" },
local.createElement("li", { title: key.primaryKey.getFingerprint() },
local.createElement("a", { href: keyUrl, target: "_blank", rel: "nofollow noopener" },
"\uD83D\uDD11\u00A0",
local.createElement("code", null, key.primaryKey.getFingerprint()))),
key.users.filter((user) => !user.revoked && user.userId).map((user) => user.userId.email).filter((email) => !!email).map((email) => local.createElement("li", null,
local.createElement("a", { href: "mailto:" + email },
"\uD83D\uDCE7 ",
email
//formatAttribute(user.userAttribute)
))),
proofs.filter((proof) => !!proof).map((proof) => local.createElement("li", null,
local.createElement("a", { rel: "me noopener nofollow", target: "_blank", href: proof.profile },
local.createElement("i", { class: serviceToClassName(proof.service) }),
proof.username),
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")))))),
local.createElement("details", null,
local.createElement("summary", null, "\uD83D\uDD12 Encrypt"),
local.createElement("textarea", { placeholder: "Message to encrypt...", id: "message" }),
local.createElement("input", { type: "button", value: "Encrypt", id: "encrypt" }),
' ',
local.createElement("input", { type: "button", id: "send", "data-recipient": primaryUser.user.userId.email, value: "Send to " + primaryUser.user.userId.email })),
local.createElement("details", null,
local.createElement("summary", null, "\uD83D\uDD8B Verify"),
local.createElement("textarea", { placeholder: "Clearsigned message to verify...", id: "signed" }),
local.createElement("input", { type: "button", value: "Verify", id: "verify" })),
local.createElement("details", null,
local.createElement("summary", null, "\uD83D\uDD11 Key details"),
local.createElement("p", null, "Subkeys:"),
local.createElement("ul", null, keys.map((subKey) => local.createElement("li", null,
local.createElement("div", null,
getStatus(subKey.status, subKey.reasonForRevocation),
" ",
getIcon(subKey.keyFlags),
" ",
local.createElement("code", null, subKey.fingerprint.substring(24).match(/.{4}/g).join(" ")),
" ",
formatAlgorithm(subKey.algorithmInfo.algorithm),
" (",
subKey.algorithmInfo.bits,
")"),
local.createElement("div", null,
"created: ",
formatDate(subKey.created),
", expire",
now > subKey.expirationTime ? "d" : "s",
": ",
formatDate(subKey.expirationTime)))))));
document.getElementById('result').innerHTML = renderer.render(info);
checkProofs();
}
async function checkProofs() {
const proofs = document.querySelectorAll('[data-checks]');
for (const proofLink of proofs) {
const checks = JSON.parse(proofLink.dataset.checks || '');
const url = proofLink.dataset.proofJson || '';
try {
await verify(url, checks);
proofLink.textContent = 'verified proof';
proofLink.classList.add('verified');
}
catch (e) {
console.error('Could not verify proof: ' + e);
}
}
}
async function verifyProof(e) {
const target = e.target;
if (target.id === 'encrypt') {
const text = document.getElementById('message');
openpgp.encrypt({
message: openpgp.message.fromText(text.value),
publicKeys: [window.key],
armor: true
}).then((cipherText) => {
text.value = cipherText.data;
}, (e) => alert(e));
}
else if (target.id === 'send') {
location.href = "mailto:" + target.dataset.recipient + "?subject=Encrypted%20message&body=" + encodeURIComponent(document.getElementById('message').value);
}
else if (target.id === 'verify') {
const text = document.getElementById('signed');
const message = await openpgp.cleartext.readArmored(text.value);
const verified = await openpgp.verify({
message,
publicKeys: [window.key]
});
console.log(verified);
alert('The signature is ' + (verified.signatures[0].valid ? '✅ correct.' : '❌ incorrect.'));
}
}
function formatAttribute(userAttribute) {
if (userAttribute.attributes[0][0] === String.fromCharCode(1)) {
return local.createElement("img", { src: "data:image/jpeg;base64," + btoa(userAttribute.attributes[0].substring(17)) });
}
if (userAttribute.attributes[0][0] === 'e') {
const url = userAttribute.attributes[0].substring(userAttribute.attributes[0].indexOf('@') + 1);
return local.createElement("a", { href: url, rel: "noopener nofollow" }, url);
}
return 'unknown attribute';
}
function formatAlgorithm(name) {
if (name === 'rsa_encrypt_sign')
return "RSA";
return name;
}
function formatDate(date) {
if (date === Infinity)
return "never";
if (typeof date === 'number')
return 'x';
return dateFormat.format(date);
}
function getStatus(status, details) {
if (status === openpgp.enums.keyStatus.invalid) {
return local.createElement("span", { title: "Invalid key" }, "\u274C");
}
if (status === openpgp.enums.keyStatus.expired) {
return local.createElement("span", { title: "Key expired" }, "\u23F0");
}
if (status === openpgp.enums.keyStatus.revoked) {
return local.createElement("span", { title: "Key revoked: " + details }, "\u274C");
}
if (status === openpgp.enums.keyStatus.valid) {
return local.createElement("span", { title: "Valid key" }, "\u2705");
}
if (status === openpgp.enums.keyStatus.no_self_cert) {
return local.createElement("span", { title: "Key not certified" }, "\u274C");
}
return "unknown:" + status;
}
function getIcon(keyFlags) {
if (!keyFlags || !keyFlags[0]) {
return "";
}
let flags = [];
if ((keyFlags[0] & openpgp.enums.keyFlags.certify_keys) !== 0) {
flags.push(local.createElement("span", { title: "Certyfing key" }, "\uD83C\uDFF5\uFE0F"));
}
if ((keyFlags[0] & openpgp.enums.keyFlags.sign_data) !== 0) {
flags.push(local.createElement("span", { title: 'Signing key' }, "\uD83D\uDD8B"));
}
if (((keyFlags[0] & openpgp.enums.keyFlags.encrypt_communication) !== 0) ||
((keyFlags[0] & openpgp.enums.keyFlags.encrypt_storage) !== 0)) {
flags.push(local.createElement("span", { title: 'Encryption key' }, "\uD83D\uDD12"));
}
if ((keyFlags[0] & openpgp.enums.keyFlags.authentication) !== 0) {
flags.push(local.createElement("span", { title: 'Authentication key' }, "\uD83D\uDCB3"));
}
return flags;
}
return {
setters: [
function (local_1) {
local = local_1;
},
function (renderer_1) {
renderer = renderer_1;
}
],
execute: function () {
openpgp.config.show_version = false;
openpgp.config.show_comment = false;
proofs = [
{
matcher: /^https:\/\/gist\.github\.com\/([A-Za-z0-9_-]+)\/([0-9a-f]+)$/,
variables: {
USERNAME: 1,
PROOFID: 2
},
profile: 'https://github.com/{USERNAME}',
proof: 'https://api.github.com/gists/{PROOFID}',
username: '{USERNAME}',
service: 'github',
checks: [{
relation: 'eq',
proof: ['owner', 'login'],
claim: '{USERNAME}'
}, {
relation: 'eq',
proof: ['owner', 'html_url'],
claim: 'https://github.com/{USERNAME}'
}, {
relation: 'contains',
proof: ['files', 'openpgp.md', 'content'],
claim: '[Verifying my OpenPGP key: openpgp4fpr:{FINGERPRINT}]'
}]
},
{
matcher: /^https:\/\/news\.ycombinator\.com\/user\?id=([A-Za-z0-9-]+)$/,
variables: {
USERNAME: 1,
PROFILE: 0
},
profile: '{PROFILE}',
proof: 'https://hacker-news.firebaseio.com/v0/user/{USERNAME}.json',
username: '{USERNAME}',
service: 'hackernews',
checks: [{
relation: 'contains',
proof: ['about'],
claim: '[Verifying my OpenPGP key: openpgp4fpr:{FINGERPRINT}]'
}]
},
{
matcher: /^https:\/\/www\.reddit\.com\/user\/([^/]+)\/comments\/([^/]+)\/([^/]+\/)?$/,
variables: {
USERNAME: 1,
PROOF: 2
},
profile: 'https://www.reddit.com/user/{USERNAME}',
proof: 'https://www.reddit.com/user/{USERNAME}/comments/{PROOF}.json',
username: '{USERNAME}',
service: 'reddit',
checks: [{
relation: 'contains',
proof: [0, 'data', 'children', 0, 'data', 'selftext'],
claim: 'Verifying my OpenPGP key: openpgp4fpr:{FINGERPRINT}'
}, {
relation: 'eq',
proof: [0, 'data', 'children', 0, 'data', 'author'],
claim: '{USERNAME}'
}]
},
{
matcher: /^https:\/\/([^/]+)\/@([A-Za-z0-9_-]+)$/,
variables: {
INSTANCE: 1,
USERNAME: 2,
PROFILE: 0
},
profile: '{PROFILE}',
proof: '{PROFILE}',
username: '@{USERNAME}@{INSTANCE}',
service: 'mastodon',
checks: [{
relation: 'oneOf',
proof: ['attachment', 'value'],
claim: '{FINGERPRINT}'
}]
},
{
matcher: /^dns:([^?]+)\?type=TXT$/,
variables: {
DOMAIN: 1
},
profile: 'https://{DOMAIN}',
proof: 'https://dns.google.com/resolve?name={DOMAIN}&type=TXT',
username: '{DOMAIN}',
service: 'dns',
checks: [{
relation: 'oneOf',
proof: ['Answer', 'data'],
claim: '\"openpgp4fpr:{FINGERPRINT}\"'
}]
}
];
window.onload = window.onhashchange = function () {
lookupKey(location.hash.substring(1));
};
;
document.addEventListener('click', verifyProof);
dateFormat = new Intl.DateTimeFormat(undefined, {
year: 'numeric', month: 'numeric', day: 'numeric',
hour: 'numeric', minute: 'numeric', second: 'numeric',
});
}
};
});