Add automatic SSL certificate generation
All checks were successful
Build and Push / build-all (push) Successful in 8m13s

This commit is contained in:
doomtube 2026-01-06 15:22:41 -05:00
parent e13fffdaac
commit 42855330c0
11 changed files with 105 additions and 38 deletions

View file

@ -138,7 +138,7 @@
preview = preview.replace(/:(\w+):/g, (match, name) => {
const key = name.toLowerCase();
if (stickerMap && stickerMap[key]) {
return `<img src="${stickerMap[key]}" alt="${name}" class="sticker-img-small" />`;
return `<img src="${stickerMap[key]}" alt="${name}" class="sticker-img-small" onerror="this.onerror=null;this.src='/dlive2.gif';" />`;
}
return match;
});
@ -147,7 +147,7 @@
return DOMPurify.sanitize(html, {
ALLOWED_TAGS: ['p', 'img', 'br', 'strong', 'em', 'code', 'del', 'span'],
ALLOWED_ATTR: ['src', 'alt', 'class'],
ALLOWED_ATTR: ['src', 'alt', 'class', 'onerror'],
FORBID_TAGS: ['a', 'button', 'script']
});
}

View file

@ -113,7 +113,7 @@
msg = msg.replace(/:(\w+):/g, (match, name) => {
const key = name.toLowerCase();
if (stickerMap && stickerMap[key]) {
return `<img src="${stickerMap[key]}" alt="${name}" title="${name}" class="sticker-img" />`;
return `<img src="${stickerMap[key]}" alt="${name}" title="${name}" class="sticker-img" onerror="this.onerror=null;this.src='/dlive2.gif';" />`;
}
return match;
});
@ -125,7 +125,7 @@
return DOMPurify.sanitize(html, {
ALLOWED_TAGS: ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'img', 'br', 'strong', 'em', 'code', 'pre', 'del', 'span'],
ALLOWED_ATTR: ['src', 'alt', 'title', 'class', 'style'],
ALLOWED_ATTR: ['src', 'alt', 'title', 'class', 'style', 'onerror'],
FORBID_TAGS: ['a', 'button', 'script']
});
}

View file

@ -394,12 +394,40 @@
flex: 1;
}
.fingerprint-row {
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 0.25rem;
flex-wrap: wrap;
}
.fingerprint-display {
font-family: monospace;
font-size: 0.9rem;
margin-bottom: 0.25rem;
}
.key-origin-tag {
display: inline-block;
padding: 0.15rem 0.4rem;
border-radius: 4px;
font-size: 0.7rem;
font-weight: 600;
text-transform: uppercase;
}
.key-origin-tag.generated {
background: rgba(40, 167, 69, 0.15);
color: #28a745;
border: 1px solid rgba(40, 167, 69, 0.3);
}
.key-origin-tag.imported {
background: rgba(0, 123, 255, 0.15);
color: #007bff;
border: 1px solid rgba(0, 123, 255, 0.3);
}
.key-date {
color: var(--gray);
font-size: 0.85rem;
@ -796,15 +824,20 @@
{#if pgpKeys.length > 0}
{#each pgpKeys as key}
<div class="pgp-key-item">
<div
class="pgp-key-header"
<div
class="pgp-key-header"
on:click={() => toggleKey(key.fingerprint)}
on:keypress={(e) => e.key === 'Enter' && toggleKey(key.fingerprint)}
role="button"
tabindex="0"
>
<div class="pgp-key-info">
<div class="fingerprint-display">{key.fingerprint}</div>
<div class="fingerprint-row">
<div class="fingerprint-display">{key.fingerprint}</div>
<span class="key-origin-tag {key.keyOrigin || 'imported'}">
{key.keyOrigin === 'generated' ? 'Generated' : 'Imported'}
</span>
</div>
<div class="key-date">Added {new Date(key.createdAt).toLocaleDateString()}</div>
</div>
<span class="expand-icon" class:expanded={expandedKeys[key.fingerprint]}>

View file

@ -932,7 +932,8 @@
credentials: 'include',
body: JSON.stringify({
publicKey: generatedPublicKey,
fingerprint: fingerprint
fingerprint: fingerprint,
origin: 'generated'
})
});
@ -987,7 +988,8 @@
credentials: 'include',
body: JSON.stringify({
publicKey: newPublicKey,
fingerprint
fingerprint,
origin: 'imported'
})
});