From bb9245ab999994d5d70ecc96b6b5b2f158a538f8 Mon Sep 17 00:00:00 2001
From: Christomatt
Date: Mon, 26 Jan 2026 19:11:09 +0100
Subject: [PATCH] feat(admin): Enhance Turnstile configuration UI and add
GitHub commit links
- Move Turnstile status indicator above input fields for better visibility
- Mask secret key input with placeholder dots when already configured
- Update secret key helper text to indicate configuration status
- Enhance version API endpoint to include GitHub commit URL
- Add githubUrl field to version response for direct commit linking
- Implement emoji sizing styles for post content and compose input
- Update RightSidebar version state type to include githubUrl
- Add clickable GitHub commit link in version display when available
- Improve security by hiding sensitive Turnstile secret key values
---
src/app/admin/page.tsx | 29 +++++++++++++-------------
src/app/api/version/route.ts | 37 +++++++++++++++++++++++++++------
src/app/globals.css | 13 +++++++++++-
src/components/RightSidebar.tsx | 22 +++++++++++++++-----
4 files changed, 75 insertions(+), 26 deletions(-)
diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx
index 538fae6..fef25fa 100644
--- a/src/app/admin/page.tsx
+++ b/src/app/admin/page.tsx
@@ -474,6 +474,19 @@ export default function AdminPage() {
Cloudflare Dashboard
.
+ {nodeSettings.turnstileSiteKey && nodeSettings.turnstileSecretKey && (
+
+ ✓ Turnstile is enabled and will be shown on login/registration
+
+ )}
@@ -501,25 +514,13 @@ export default function AdminPage() {
type="password"
value={nodeSettings.turnstileSecretKey}
onChange={e => setNodeSettings({ ...nodeSettings, turnstileSecretKey: e.target.value })}
- placeholder="0x4AAAAAAA..."
+ placeholder={nodeSettings.turnstileSecretKey ? '••••••••••••••••' : '0x4AAAAAAA...'}
style={{ fontFamily: 'monospace', fontSize: '13px' }}
/>
- Secret key for server-side verification
+ {nodeSettings.turnstileSecretKey ? 'Secret key is configured (hidden for security)' : 'Secret key for server-side verification'}
- {nodeSettings.turnstileSiteKey && nodeSettings.turnstileSecretKey && (
-
- ✓ Turnstile is enabled and will be shown on login/registration
-
- )}
diff --git a/src/app/api/version/route.ts b/src/app/api/version/route.ts
index 3c18894..99fcac3 100644
--- a/src/app/api/version/route.ts
+++ b/src/app/api/version/route.ts
@@ -9,26 +9,51 @@ export async function GET() {
stdio: ['pipe', 'pipe', 'ignore'] // Ignore stderr
}).trim();
- // Also get the short hash for reference
+ // Get the short hash for reference
const commitHash = execSync('git rev-parse --short HEAD', {
encoding: 'utf-8',
stdio: ['pipe', 'pipe', 'ignore']
}).trim();
+ const fullHash = execSync('git rev-parse HEAD', {
+ encoding: 'utf-8',
+ stdio: ['pipe', 'pipe', 'ignore']
+ }).trim();
+
+ // Try to get the GitHub repo URL
+ let githubUrl = null;
+ try {
+ const remoteUrl = execSync('git config --get remote.origin.url', {
+ encoding: 'utf-8',
+ stdio: ['pipe', 'pipe', 'ignore']
+ }).trim();
+
+ // Convert git URL to GitHub web URL
+ // Handle both SSH (git@github.com:user/repo.git) and HTTPS (https://github.com/user/repo.git)
+ if (remoteUrl.includes('github.com')) {
+ let cleanUrl = remoteUrl
+ .replace('git@github.com:', 'https://github.com/')
+ .replace(/\.git$/, '');
+
+ githubUrl = `${cleanUrl}/commit/${fullHash}`;
+ }
+ } catch (e) {
+ // If we can't get the remote URL, that's okay
+ }
+
return NextResponse.json({
count: parseInt(commitCount, 10),
hash: commitHash,
- fullHash: execSync('git rev-parse HEAD', {
- encoding: 'utf-8',
- stdio: ['pipe', 'pipe', 'ignore']
- }).trim()
+ fullHash: fullHash,
+ githubUrl: githubUrl
});
} catch (error) {
// If git is not available or not a git repo, return unknown
return NextResponse.json({
count: null,
hash: 'unknown',
- fullHash: null
+ fullHash: null,
+ githubUrl: null
});
}
}
diff --git a/src/app/globals.css b/src/app/globals.css
index 2a69737..ad97bea 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -1797,4 +1797,15 @@ a.btn-primary:visited {
.thread-line {
margin-left: 20px;
border-left: 1px solid var(--border);
-}
\ No newline at end of file
+}
+
+
+/* Big Emojis! */
+.post-content img.emoji,
+.compose-input img.emoji {
+ display: inline;
+ height: 2.5em;
+ width: 2.5em;
+ margin: 0 0.05em 0 0.1em;
+ vertical-align: -0.5em;
+}
diff --git a/src/components/RightSidebar.tsx b/src/components/RightSidebar.tsx
index 68f1b73..20abf4b 100644
--- a/src/components/RightSidebar.tsx
+++ b/src/components/RightSidebar.tsx
@@ -19,7 +19,7 @@ export function RightSidebar() {
bannerUrl: '',
admins: [] as Admin[],
});
- const [version, setVersion] = useState<{ count: number | null; hash: string; fullHash: string | null } | null>(null);
+ const [version, setVersion] = useState<{ count: number | null; hash: string; fullHash: string | null; githubUrl: string | null } | null>(null);
const [loading, setLoading] = useState(true);
@@ -45,7 +45,7 @@ export function RightSidebar() {
fetch('/api/version')
.then(res => res.json())
.then(data => setVersion(data))
- .catch(() => setVersion({ count: null, hash: 'unknown', fullHash: null }));
+ .catch(() => setVersion({ count: null, hash: 'unknown', fullHash: null, githubUrl: null }));
}, []);
if (loading) {
@@ -119,9 +119,21 @@ export function RightSidebar() {
{version && version.count !== null && (
<>
{' • '}
-
- Commit {version.count}
-
+ {version.githubUrl ? (
+
+ Commit {version.count}
+
+ ) : (
+
+ Commit {version.count}
+
+ )}
>
)}