Fix Vaultwarden 429: add 5min server cache, slow widget poll
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
@@ -6,6 +6,10 @@ const router = Router()
|
|||||||
let vwCookie: string | null = null
|
let vwCookie: string | null = null
|
||||||
let vwCookieExpiry = 0
|
let vwCookieExpiry = 0
|
||||||
|
|
||||||
|
interface CacheEntry { data: unknown; ts: number }
|
||||||
|
let statsCache: CacheEntry | null = null
|
||||||
|
const CACHE_TTL = 5 * 60 * 1000 // 5 minutes
|
||||||
|
|
||||||
async function getCookie(): Promise<string> {
|
async function getCookie(): Promise<string> {
|
||||||
if (vwCookie && Date.now() < vwCookieExpiry) return vwCookie
|
if (vwCookie && Date.now() < vwCookieExpiry) return vwCookie
|
||||||
|
|
||||||
@@ -38,6 +42,11 @@ router.get('/stats', async (_req, res) => {
|
|||||||
const host = process.env.VAULTWARDEN_HOST
|
const host = process.env.VAULTWARDEN_HOST
|
||||||
if (!host) { res.status(503).json({ error: 'VAULTWARDEN_HOST not configured' }); return }
|
if (!host) { res.status(503).json({ error: 'VAULTWARDEN_HOST not configured' }); return }
|
||||||
|
|
||||||
|
if (statsCache && Date.now() - statsCache.ts < CACHE_TTL) {
|
||||||
|
res.json(statsCache.data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const cookie = await getCookie()
|
const cookie = await getCookie()
|
||||||
|
|
||||||
const [usersRes, diagRes] = await Promise.all([
|
const [usersRes, diagRes] = await Promise.all([
|
||||||
@@ -59,7 +68,7 @@ router.get('/stats', async (_req, res) => {
|
|||||||
const users: any[] = usersRes.data ?? []
|
const users: any[] = usersRes.data ?? []
|
||||||
const diag = diagRes.data ?? {}
|
const diag = diagRes.data ?? {}
|
||||||
|
|
||||||
res.json({
|
const result = {
|
||||||
version: diag.version ?? null,
|
version: diag.version ?? null,
|
||||||
signupsAllowed: diag.config?.signups_allowed ?? null,
|
signupsAllowed: diag.config?.signups_allowed ?? null,
|
||||||
userCount: users.length,
|
userCount: users.length,
|
||||||
@@ -73,7 +82,9 @@ router.get('/stats', async (_req, res) => {
|
|||||||
cipherCount: u.cipherCount ?? u.cipher_count ?? null,
|
cipherCount: u.cipherCount ?? u.cipher_count ?? null,
|
||||||
attachCount: u.attachmentCount ?? u.attachment_count ?? null,
|
attachCount: u.attachmentCount ?? u.attachment_count ?? null,
|
||||||
})),
|
})),
|
||||||
})
|
}
|
||||||
|
statsCache = { data: result, ts: Date.now() }
|
||||||
|
res.json(result)
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
if (err instanceof Error && err.message.includes('login failed')) vwCookie = null
|
if (err instanceof Error && err.message.includes('login failed')) vwCookie = null
|
||||||
const msg = err instanceof Error ? err.message : 'Unknown error'
|
const msg = err instanceof Error ? err.message : 'Unknown error'
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ function formatDate(iso: string | null): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function VaultwardenWidget() {
|
export function VaultwardenWidget() {
|
||||||
const { data, loading, error } = useApi<VaultwardenData>('/api/vaultwarden/stats')
|
const { data, loading, error } = useApi<VaultwardenData>('/api/vaultwarden/stats', 5 * 60_000)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card">
|
<div className="card">
|
||||||
|
|||||||
Reference in New Issue
Block a user