Replace IP-based auth with XenForo OAuth2

Also, resolves the long standing issues #2 and #3
This commit is contained in:
2026-05-17 19:06:39 -04:00
parent a92be6c681
commit 94cb2a98c4
24 changed files with 870 additions and 343 deletions
+26 -6
View File
@@ -1,15 +1,35 @@
server:
bind-address: 0.0.0.0
port: 27192
logging: false
# Logging. The HTTPD writes one line per request and rate-limit event.
logging:
file: true # write to <data-folder>/httpd.log
file-path: "httpd.log" # relative to the module's data folder
console: false # also mirror to the Bukkit console
# Token-bucket rate limiting. Defaults are sized for a small sized server.
# capacity = burst, per-second = sustained rate. Disable globally with enabled: false.
rate-limit:
enabled: true
global:
capacity: 200
per-second: 100
per-ip:
capacity: 30
per-second: 10
authentication:
enabled: false
# Providers: discord
provider:
name: discord
redirectUri: ""
discord: # Fill if using discord provider
# Absolute URL the XenForo authorize page will redirect back to.
# Must match the redirect URI registered on the OAuth2 client in XenForo.
redirectUri: "https://example.com/oauth2/callback"
xenforo:
# XenForo site domain (no scheme, no trailing slash). The /oauth2/authorize,
# /api/oauth2/token, /api/oauth2/revoke, and /api/me paths are derived from it.
domain: "totalfreedom.tf"
clientId: ""
token: "" # Can also use environment variable or system property BOT_TOKEN
clientSecret: ""
# How long a successful login stays valid, in minutes.
sessionMinutes: 1440
+20 -1
View File
@@ -324,7 +324,8 @@
</a>
</nav>
<div class="hidden items-center gap-2 md:flex">
<div class="flex items-center gap-2">
<div id="plex-auth" class="hidden md:flex items-center gap-2"></div>
<button type="button" onclick="window.plexToggleTheme()" class="ring-card inline-flex size-8 items-center justify-center rounded-full bg-card text-muted-foreground transition-colors hover:bg-muted hover:text-foreground" aria-label="Toggle theme">
<svg class="size-4 hidden dark:block" aria-hidden="true"><use href="#i-sun"/></svg>
<svg class="size-4 block dark:hidden" aria-hidden="true"><use href="#i-moon"/></svg>
@@ -347,6 +348,24 @@
document.querySelectorAll('.nav-link').forEach(a => {
if (a.classList.contains('active')) a.setAttribute('data-active', 'true');
});
(function () {
const mount = document.getElementById('plex-auth');
if (!mount) return;
const linkClasses = 'ring-card inline-flex h-8 items-center gap-1.5 rounded-full bg-card px-3 text-sm text-muted-foreground transition-colors hover:bg-muted hover:text-foreground';
const escape = (s) => String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
fetch('/oauth2/me', { credentials: 'same-origin', headers: { 'Accept': 'application/json' } })
.then(r => r.json().catch(() => ({})).then(j => ({ status: r.status, body: j })))
.then(({ status, body }) => {
if (body && body.authenticated === false && body.reason === 'disabled') return;
if (status === 200 && body.authenticated) {
mount.innerHTML = '<span class="text-xs text-muted-foreground">' + escape(body.username) + '</span>'
+ '<a href="/oauth2/logout" class="' + linkClasses + '">Sign out</a>';
} else {
mount.innerHTML = '<a href="/oauth2/login" class="' + linkClasses + '">Sign in</a>';
}
})
.catch(() => {});
})();
</script>
</body>