mirror of
https://codeberg.org/valpackett/tiddlypwa.git
synced 2025-12-06 02:30:48 -08:00
Plugin: add supporter key thingy
This commit is contained in:
parent
0590d41883
commit
98f9bece17
3 changed files with 95 additions and 0 deletions
10
plugins/tiddlypwa/config-support.tid
Normal file
10
plugins/tiddlypwa/config-support.tid
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
title: $:/plugins/valpackett/tiddlypwa/config-xsupport
|
||||||
|
tags: $:/tags/ControlPanel/TiddlyPWA
|
||||||
|
caption: Support TiddlyPWA
|
||||||
|
|
||||||
|
[[TiddlyPWA|https://tiddly.packett.cool/]] is free software in both senses of the word; you can support its development by purchasing a supporter key or signing up for a monthly subscription [[on Patreon|https://www.patreon.com/valpackett]] (if you subscribe you can ask for a key using Patreon messages).
|
||||||
|
The key does not change the behavior of the software in any way, it only gives you a warm fuzzy feeling of being a supporter of independent free software development and shows a cute message below:
|
||||||
|
|
||||||
|
<$tiddlypwa-supporter-key key={{$:/TiddlyPWASupporterKey}} />
|
||||||
|
|
||||||
|
(To apply/change the key, save it as a tiddler called [[$:/TiddlyPWASupporterKey]].)
|
||||||
|
|
@ -10,6 +10,8 @@ Licensed under 0BSD, see license.tid.
|
||||||
.tiddlypwa-form input, .tiddlypwa-form button, .tiddlypwa-form details { display: block; width: 100%; margin: 0.5em 0; }
|
.tiddlypwa-form input, .tiddlypwa-form button, .tiddlypwa-form details { display: block; width: 100%; margin: 0.5em 0; }
|
||||||
.tiddlypwa-form input, .tiddlypwa-form button { padding: 0.25em; border-radius: 3px; border: 1px solid #999; color: inherit; }
|
.tiddlypwa-form input, .tiddlypwa-form button { padding: 0.25em; border-radius: 3px; border: 1px solid #999; color: inherit; }
|
||||||
.tiddlypwa-form-error { color: #ee1111; font-weight: bolder; }
|
.tiddlypwa-form-error { color: #ee1111; font-weight: bolder; }
|
||||||
|
.tiddlypwa-supporter { font: 1.5em cursive; }
|
||||||
|
.tiddlypwa-supporter-tier { font-weight: bold; color: pink; text-shadow: -1px 0 0 #fff, 1px 0 0 #fff, 0 -1px #fff, 0 1px #fff, -1px -1px #fff, 1px 1px #fff, -1px 1px #fff, 1px -1px #fff, 0 0 6px rebeccapurple; display: inline-block; transform: rotateZ(-3deg); }
|
||||||
html body svg.tiddlypwa-image-sync-button-dynamic .tiddlypwa-image-sync-button-dynamic-idle { visibility: visible; }
|
html body svg.tiddlypwa-image-sync-button-dynamic .tiddlypwa-image-sync-button-dynamic-idle { visibility: visible; }
|
||||||
html body svg.tiddlypwa-image-sync-button-dynamic .tiddlypwa-image-sync-button-dynamic-syncing { visibility: hidden; fill: <<colour dirty-indicator>>; }
|
html body svg.tiddlypwa-image-sync-button-dynamic .tiddlypwa-image-sync-button-dynamic-syncing { visibility: hidden; fill: <<colour dirty-indicator>>; }
|
||||||
html body.tiddlypwa-syncing svg.tiddlypwa-image-sync-button-dynamic .tiddlypwa-image-sync-button-dynamic-idle { visibility: hidden; }
|
html body.tiddlypwa-syncing svg.tiddlypwa-image-sync-button-dynamic .tiddlypwa-image-sync-button-dynamic-idle { visibility: hidden; }
|
||||||
|
|
|
||||||
83
plugins/tiddlypwa/supporter-key.js
Normal file
83
plugins/tiddlypwa/supporter-key.js
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*\
|
||||||
|
title: $:/plugins/valpackett/tiddlypwa/supporter-key
|
||||||
|
type: application/javascript
|
||||||
|
module-type: widget
|
||||||
|
|
||||||
|
Licensed under 0BSD, see license.tid.
|
||||||
|
Formatted with `deno fmt`.
|
||||||
|
\*/
|
||||||
|
/// <reference types="npm:tw5-typed" />
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
if (!$tw.browser || !('crypto' in window)) return;
|
||||||
|
|
||||||
|
const b64udec = (x) => Uint8Array.from(atob(x.replace(/_/g, '/').replace(/-/g, '+')), (c) => c.charCodeAt(0));
|
||||||
|
|
||||||
|
const pubkey = crypto.subtle.importKey(
|
||||||
|
'jwk',
|
||||||
|
{
|
||||||
|
'crv': 'P-256',
|
||||||
|
'kid': 'xuf485BsGcWBWQF4GHvz32DM39Ls0zYLLTkczSBbdmw',
|
||||||
|
'kty': 'EC',
|
||||||
|
'use': 'sig',
|
||||||
|
'x': 'HU_Qr8MJQdj58A7cDHXggO_-SGN-kaFc1kMnwH34vvM',
|
||||||
|
'y': 'XMl52EulmwbzOoMmVWJEnZ6hw2UG4_xEixNUUU_TPwM',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ECDSA',
|
||||||
|
namedCurve: 'P-256',
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
['verify'],
|
||||||
|
);
|
||||||
|
|
||||||
|
const Widget = require('$:/core/modules/widgets/widget.js').widget;
|
||||||
|
|
||||||
|
exports['tiddlypwa-supporter-key'] = class TSK extends Widget {
|
||||||
|
#parent;
|
||||||
|
render(parent, nextSibling) {
|
||||||
|
this.computeAttributes();
|
||||||
|
if (parent) this.#parent = parent;
|
||||||
|
const node = this.document.createElement('p');
|
||||||
|
this.#parent.insertBefore(node, nextSibling);
|
||||||
|
this.domNodes.push(node);
|
||||||
|
const key = this.getAttribute('key', '');
|
||||||
|
if (key.length === 0) {
|
||||||
|
node.innerText = '-key not found-';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const [prot, pl, sig] = key.trim().split('.');
|
||||||
|
if (!prot || !pl || !sig) {
|
||||||
|
node.innerText = '-key format not valid-';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
node.innerText = '...';
|
||||||
|
pubkey
|
||||||
|
.then((k) =>
|
||||||
|
crypto.subtle.verify(
|
||||||
|
{ name: 'ECDSA', hash: { name: 'SHA-256' } },
|
||||||
|
k,
|
||||||
|
b64udec(sig),
|
||||||
|
new TextEncoder().encode(prot + '.' + pl),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.then((res) => {
|
||||||
|
if (res) node.innerHTML = JSON.parse(new TextDecoder().decode(b64udec(pl))).h;
|
||||||
|
else node.innerText = '-key signature not valid-';
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
console.error(e);
|
||||||
|
node.innerText = '-key validation error-';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh(_chg) {
|
||||||
|
if (this.computeAttributes().key) {
|
||||||
|
this.refreshSelf();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
Loading…
Add table
Add a link
Reference in a new issue