forked from Mirrors/keyoxide-web
Merge pull request 'Add support for keys hosted on keybase' (#9) from keybase-integration into dev
Reviewed-on: https://codeberg.org/yarmo/keyoxide/pulls/9
This commit is contained in:
commit
e7f3dccfcf
4 changed files with 107 additions and 31 deletions
|
@ -205,37 +205,45 @@ async function displayProfile(opts) {
|
||||||
let userData = keyData.user.user.userId;
|
let userData = keyData.user.user.userId;
|
||||||
|
|
||||||
// Determine WKD or HKP link
|
// Determine WKD or HKP link
|
||||||
if (opts.mode == "wkd") {
|
switch (opts.mode) {
|
||||||
const [, localPart, domain] = /(.*)@(.*)/.exec(opts.input);
|
case "wkd":
|
||||||
const localEncoded = await computeWKDLocalPart(localPart.toLowerCase());
|
const [, localPart, domain] = /(.*)@(.*)/.exec(opts.input);
|
||||||
const urlAdvanced = `https://openpgpkey.${domain}/.well-known/openpgpkey/${domain}/hu/${localEncoded}`;
|
const localEncoded = await computeWKDLocalPart(localPart.toLowerCase());
|
||||||
const urlDirect = `https://${domain}/.well-known/openpgpkey/hu/${localEncoded}`;
|
const urlAdvanced = `https://openpgpkey.${domain}/.well-known/openpgpkey/${domain}/hu/${localEncoded}`;
|
||||||
|
const urlDirect = `https://${domain}/.well-known/openpgpkey/hu/${localEncoded}`;
|
||||||
|
|
||||||
try {
|
|
||||||
keyLink = await fetch(urlAdvanced).then(function(response) {
|
|
||||||
if (response.status === 200) {
|
|
||||||
return urlAdvanced;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
console.warn(e);
|
|
||||||
}
|
|
||||||
if (!keyLink) {
|
|
||||||
try {
|
try {
|
||||||
keyLink = await fetch(urlDirect).then(function(response) {
|
keyLink = await fetch(urlAdvanced).then(function(response) {
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
return urlDirect;
|
return urlAdvanced;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn(e);
|
console.warn(e);
|
||||||
}
|
}
|
||||||
}
|
if (!keyLink) {
|
||||||
if (!keyLink) {
|
try {
|
||||||
|
keyLink = await fetch(urlDirect).then(function(response) {
|
||||||
|
if (response.status === 200) {
|
||||||
|
return urlDirect;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!keyLink) {
|
||||||
|
keyLink = `https://keys.openpgp.org/pks/lookup?op=get&options=mr&search=0x${keyData.fingerprint}`;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "hkp":
|
||||||
keyLink = `https://keys.openpgp.org/pks/lookup?op=get&options=mr&search=0x${keyData.fingerprint}`;
|
keyLink = `https://keys.openpgp.org/pks/lookup?op=get&options=mr&search=0x${keyData.fingerprint}`;
|
||||||
}
|
break;
|
||||||
} else {
|
|
||||||
keyLink = `https://keys.openpgp.org/pks/lookup?op=get&options=mr&search=0x${keyData.fingerprint}`;
|
case "keybase":
|
||||||
|
keyLink = opts.keyLink;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill in various data
|
// Fill in various data
|
||||||
|
@ -261,10 +269,13 @@ async function displayProfile(opts) {
|
||||||
feedback += `<div class="profileDataItem__label">fingerprint</div>`;
|
feedback += `<div class="profileDataItem__label">fingerprint</div>`;
|
||||||
feedback += `<div class="profileDataItem__value"><a href="${keyLink}">${keyData.fingerprint}</a></div>`;
|
feedback += `<div class="profileDataItem__value"><a href="${keyLink}">${keyData.fingerprint}</a></div>`;
|
||||||
feedback += `</div>`;
|
feedback += `</div>`;
|
||||||
feedback += `<div class="profileDataItem">`;
|
|
||||||
feedback += `<div class="profileDataItem__label">qrcode</div>`;
|
if (opts.mode == "hkp") {
|
||||||
feedback += `<div class="profileDataItem__value"><a href="/util/qr/${keyData.fingerprint}">fingerprint</a></div>`;
|
feedback += `<div class="profileDataItem">`;
|
||||||
feedback += `</div>`;
|
feedback += `<div class="profileDataItem__label">qrcode</div>`;
|
||||||
|
feedback += `<div class="profileDataItem__value"><a href="/util/qr/${keyData.fingerprint}">fingerprint</a></div>`;
|
||||||
|
feedback += `</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
if (keyData.notations.length > 0) {
|
if (keyData.notations.length > 0) {
|
||||||
feedback += `<div class="profileDataItem profileDataItem--separator profileDataItem--noLabel">`;
|
feedback += `<div class="profileDataItem profileDataItem--separator profileDataItem--noLabel">`;
|
||||||
|
@ -589,6 +600,27 @@ async function fetchKeys(opts) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "keybase":
|
||||||
|
opts.keyLink = `https://keybase.io/${opts.username}/pgp_keys.asc?fingerprint=${opts.fingerprint}`;
|
||||||
|
opts.input = `${opts.username}/${opts.fingerprint}`;
|
||||||
|
try {
|
||||||
|
opts.plaintext = await fetch(opts.keyLink).then(function(response) {
|
||||||
|
if (response.status === 200) {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => response.blob())
|
||||||
|
.then(response => response.text());
|
||||||
|
} catch (e) {
|
||||||
|
throw("Error: No public keys could be fetched from the Keybase account.");
|
||||||
|
}
|
||||||
|
output.publicKey = (await openpgp.key.readArmored(opts.plaintext)).keys[0];
|
||||||
|
|
||||||
|
if (!output.publicKey) {
|
||||||
|
throw("Error: No public keys could be read from the Keybase account.");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case "signature":
|
case "signature":
|
||||||
sig = (await openpgp.signature.readArmored(opts.signature));
|
sig = (await openpgp.signature.readArmored(opts.signature));
|
||||||
if ('compressed' in sig.packets[0]) {
|
if ('compressed' in sig.packets[0]) {
|
||||||
|
@ -738,10 +770,15 @@ if (elFormVerify) {
|
||||||
case "plaintext":
|
case "plaintext":
|
||||||
opts.input = document.body.querySelector("#plaintext_input").value;
|
opts.input = document.body.querySelector("#plaintext_input").value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "keybase":
|
||||||
|
opts.username = document.body.querySelector("#keybase_username").value;
|
||||||
|
opts.fingerprint = document.body.querySelector("#keybase_fingerprint").value;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no input was detect
|
// If no input was detect
|
||||||
if (!opts.input) {
|
if (!opts.input && !opts.username) {
|
||||||
opts.mode = "signature";
|
opts.mode = "signature";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,6 +818,11 @@ if (elFormEncrypt) {
|
||||||
case "plaintext":
|
case "plaintext":
|
||||||
opts.input = document.body.querySelector("#plaintext_input").value;
|
opts.input = document.body.querySelector("#plaintext_input").value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "keybase":
|
||||||
|
opts.username = document.body.querySelector("#keybase_username").value;
|
||||||
|
opts.fingerprint = document.body.querySelector("#keybase_fingerprint").value;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
encryptMessage(opts);
|
encryptMessage(opts);
|
||||||
|
@ -850,6 +892,15 @@ if (elProfileUid) {
|
||||||
mode: elProfileMode.innerHTML
|
mode: elProfileMode.innerHTML
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "keybase":
|
||||||
|
let match = profileUid.match(/(.*)\/(.*)/);
|
||||||
|
opts = {
|
||||||
|
username: match[1],
|
||||||
|
fingerprint: match[2],
|
||||||
|
mode: elProfileMode.innerHTML
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
displayProfile(opts);
|
displayProfile(opts);
|
||||||
}
|
}
|
||||||
|
|
23
index.php
23
index.php
|
@ -21,16 +21,19 @@ $router->map('GET', '/verify', function() {}, 'verify');
|
||||||
$router->map('GET', '/encrypt', function() {}, 'encrypt');
|
$router->map('GET', '/encrypt', function() {}, 'encrypt');
|
||||||
$router->map('GET', '/proofs', function() {}, 'proofs');
|
$router->map('GET', '/proofs', function() {}, 'proofs');
|
||||||
$router->map('GET', '/verify/hkp/[**:uid]', function() {}, 'verifyHKP');
|
$router->map('GET', '/verify/hkp/[**:uid]', function() {}, 'verifyHKP');
|
||||||
$router->map('GET', '/encrypt/hkp/[**:uid]', function() {}, 'encryptHKP');
|
|
||||||
$router->map('GET', '/proofs/hkp/[**:uid]', function() {}, 'proofsHKP');
|
|
||||||
$router->map('GET', '/verify/wkd/[**:uid]', function() {}, 'verifyWKD');
|
$router->map('GET', '/verify/wkd/[**:uid]', function() {}, 'verifyWKD');
|
||||||
$router->map('GET', '/encrypt/wkd/[**:uid]', function() {}, 'encryptWKD');
|
$router->map('GET', '/verify/keybase/[:uid]/[:fp]', function() {}, 'verifyKeybase');
|
||||||
$router->map('GET', '/proofs/wkd/[**:uid]', function() {}, 'proofsWKD');
|
|
||||||
$router->map('GET', '/verify/[**:uid]', function() {}, 'verifyAUTO');
|
$router->map('GET', '/verify/[**:uid]', function() {}, 'verifyAUTO');
|
||||||
|
$router->map('GET', '/encrypt/hkp/[**:uid]', function() {}, 'encryptHKP');
|
||||||
|
$router->map('GET', '/encrypt/wkd/[**:uid]', function() {}, 'encryptWKD');
|
||||||
|
$router->map('GET', '/encrypt/keybase/[:uid]/[:fp]', function() {}, 'encryptKeybase');
|
||||||
$router->map('GET', '/encrypt/[**:uid]', function() {}, 'encryptAUTO');
|
$router->map('GET', '/encrypt/[**:uid]', function() {}, 'encryptAUTO');
|
||||||
|
$router->map('GET', '/proofs/hkp/[**:uid]', function() {}, 'proofsHKP');
|
||||||
|
$router->map('GET', '/proofs/wkd/[**:uid]', function() {}, 'proofsWKD');
|
||||||
$router->map('GET', '/proofs/[**:uid]', function() {}, 'proofsAUTO');
|
$router->map('GET', '/proofs/[**:uid]', function() {}, 'proofsAUTO');
|
||||||
$router->map('GET', '/hkp/[**:uid]', function() {}, 'profileHKP');
|
$router->map('GET', '/hkp/[**:uid]', function() {}, 'profileHKP');
|
||||||
$router->map('GET', '/wkd/[**:uid]', function() {}, 'profileWKD');
|
$router->map('GET', '/wkd/[**:uid]', function() {}, 'profileWKD');
|
||||||
|
$router->map('GET', '/keybase/[:uid]/[:fp]', function() {}, 'profileKeybase');
|
||||||
$router->map('GET', '/[**:uid]', function() {}, 'profile');
|
$router->map('GET', '/[**:uid]', function() {}, 'profile');
|
||||||
|
|
||||||
// Router matching
|
// Router matching
|
||||||
|
@ -59,6 +62,10 @@ if(is_array($match) && is_callable($match['target'])) {
|
||||||
echo $templates->render('verify', ['title' => 'Verify — ', 'mode' => 'wkd', 'wkd_input' => $match['params']['uid']]);
|
echo $templates->render('verify', ['title' => 'Verify — ', 'mode' => 'wkd', 'wkd_input' => $match['params']['uid']]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'verifyKeybase':
|
||||||
|
echo $templates->render('verify', ['title' => 'Verify — ', 'mode' => 'keybase', 'keybase_username' => htmlspecialchars($match['params']['uid']), 'keybase_fingerprint' => htmlspecialchars($match['params']['fp'])]);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'encrypt':
|
case 'encrypt':
|
||||||
echo $templates->render('encrypt', ['title' => 'Encrypt — ', 'mode' => 'auto']);
|
echo $templates->render('encrypt', ['title' => 'Encrypt — ', 'mode' => 'auto']);
|
||||||
break;
|
break;
|
||||||
|
@ -75,6 +82,10 @@ if(is_array($match) && is_callable($match['target'])) {
|
||||||
echo $templates->render('encrypt', ['title' => 'Encrypt — ', 'mode' => 'wkd', 'wkd_input' => $match['params']['uid']]);
|
echo $templates->render('encrypt', ['title' => 'Encrypt — ', 'mode' => 'wkd', 'wkd_input' => $match['params']['uid']]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'encryptKeybase':
|
||||||
|
echo $templates->render('encrypt', ['title' => 'Encrypt — ', 'mode' => 'keybase', 'keybase_username' => htmlspecialchars($match['params']['uid']), 'keybase_fingerprint' => htmlspecialchars($match['params']['fp'])]);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'proofs':
|
case 'proofs':
|
||||||
echo $templates->render('proofs', ['title' => 'Proofs — ', 'mode' => 'auto']);
|
echo $templates->render('proofs', ['title' => 'Proofs — ', 'mode' => 'auto']);
|
||||||
break;
|
break;
|
||||||
|
@ -103,6 +114,10 @@ if(is_array($match) && is_callable($match['target'])) {
|
||||||
echo $templates->render('profile', ['mode' => 'wkd', 'uid' => htmlspecialchars($match['params']['uid'])]);
|
echo $templates->render('profile', ['mode' => 'wkd', 'uid' => htmlspecialchars($match['params']['uid'])]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'profileKeybase':
|
||||||
|
echo $templates->render('profile', ['mode' => 'keybase', 'uid' => htmlspecialchars($match['params']['uid']).'/'.htmlspecialchars($match['params']['fp'])]);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'guides':
|
case 'guides':
|
||||||
echo $templates->render('guides');
|
echo $templates->render('guides');
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
<option value="wkd" <?php if ($mode=="wkd"): ?>selected<?php endif ?>>Web Key Directory</option>
|
<option value="wkd" <?php if ($mode=="wkd"): ?>selected<?php endif ?>>Web Key Directory</option>
|
||||||
<option value="hkp" <?php if ($mode=="hkp"): ?>selected<?php endif ?>>Keyserver</option>
|
<option value="hkp" <?php if ($mode=="hkp"): ?>selected<?php endif ?>>Keyserver</option>
|
||||||
<option value="plaintext" <?php if ($mode=="plaintext"): ?>selected<?php endif ?>>Plaintext</option>
|
<option value="plaintext" <?php if ($mode=="plaintext"): ?>selected<?php endif ?>>Plaintext</option>
|
||||||
|
<option value="keybase" <?php if ($mode=="keybase"): ?>selected<?php endif ?>>Keybase</option>
|
||||||
</select>
|
</select>
|
||||||
<div class="modesContainer">
|
<div class="modesContainer">
|
||||||
<div class='modes modes--auto <?php if ($mode=="auto"): ?>modes--visible<?php endif ?>'>
|
<div class='modes modes--auto <?php if ($mode=="auto"): ?>modes--visible<?php endif ?>'>
|
||||||
|
@ -25,6 +26,10 @@
|
||||||
<div class='modes modes--plaintext <?php if ($mode=="plaintext"): ?>modes--visible<?php endif ?>'>
|
<div class='modes modes--plaintext <?php if ($mode=="plaintext"): ?>modes--visible<?php endif ?>'>
|
||||||
<textarea name="plaintext_input" id="plaintext_input"></textarea>
|
<textarea name="plaintext_input" id="plaintext_input"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
<div class='modes modes--keybase <?php if ($mode=="keybase"): ?>modes--visible<?php endif ?>'>
|
||||||
|
<input type="text" name="keybase_username" id="keybase_username" placeholder="username" value="<?=$this->escape($keybase_username)?>">
|
||||||
|
<input type="text" name="keybase_fingerprint" id="keybase_fingerprint" placeholder="fingerprint" value="<?=$this->escape($keybase_fingerprint)?>">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h3>Message</h3>
|
<h3>Message</h3>
|
||||||
<textarea name="message" id="message"></textarea>
|
<textarea name="message" id="message"></textarea>
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
<option value="wkd" <?php if ($mode=="wkd"): ?>selected<?php endif ?>>Web Key Directory</option>
|
<option value="wkd" <?php if ($mode=="wkd"): ?>selected<?php endif ?>>Web Key Directory</option>
|
||||||
<option value="hkp" <?php if ($mode=="hkp"): ?>selected<?php endif ?>>Keyserver</option>
|
<option value="hkp" <?php if ($mode=="hkp"): ?>selected<?php endif ?>>Keyserver</option>
|
||||||
<option value="plaintext" <?php if ($mode=="plaintext"): ?>selected<?php endif ?>>Plaintext</option>
|
<option value="plaintext" <?php if ($mode=="plaintext"): ?>selected<?php endif ?>>Plaintext</option>
|
||||||
|
<option value="keybase" <?php if ($mode=="keybase"): ?>selected<?php endif ?>>Keybase</option>
|
||||||
</select>
|
</select>
|
||||||
<div class="modesContainer">
|
<div class="modesContainer">
|
||||||
<div class='modes modes--auto <?php if ($mode=="auto"): ?>modes--visible<?php endif ?>'>
|
<div class='modes modes--auto <?php if ($mode=="auto"): ?>modes--visible<?php endif ?>'>
|
||||||
|
@ -25,6 +26,10 @@
|
||||||
<div class='modes modes--plaintext <?php if ($mode=="plaintext"): ?>modes--visible<?php endif ?>'>
|
<div class='modes modes--plaintext <?php if ($mode=="plaintext"): ?>modes--visible<?php endif ?>'>
|
||||||
<textarea name="plaintext_input" id="plaintext_input"></textarea>
|
<textarea name="plaintext_input" id="plaintext_input"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
<div class='modes modes--keybase <?php if ($mode=="keybase"): ?>modes--visible<?php endif ?>'>
|
||||||
|
<input type="text" name="keybase_username" id="keybase_username" placeholder="username" value="<?=$this->escape($keybase_username)?>">
|
||||||
|
<input type="text" name="keybase_fingerprint" id="keybase_fingerprint" placeholder="fingerprint" value="<?=$this->escape($keybase_fingerprint)?>">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h3>Signature</h3>
|
<h3>Signature</h3>
|
||||||
<textarea name="signature" id="signature"></textarea>
|
<textarea name="signature" id="signature"></textarea>
|
||||||
|
|
Loading…
Reference in a new issue