feat: more version checking options

This commit is contained in:
diced
2025-05-15 21:09:44 -07:00
parent f70eea97b0
commit a35d8b87ee
8 changed files with 81 additions and 15 deletions

View File

@@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "Zipline" ADD COLUMN "featuresVersionAPI" TEXT NOT NULL DEFAULT 'https://zipline-version.diced.sh',
ADD COLUMN "featuresVersionChecking" BOOLEAN NOT NULL DEFAULT true;

View File

@@ -1,3 +1,3 @@
# Please do not edit this file manually # Please do not edit this file manually
# It should be added in your version-control system (e.g., Git) # It should be added in your version-control system (e.g., Git)
provider = "postgresql" provider = "postgresql"

View File

@@ -58,6 +58,9 @@ model Zipline {
featuresMetricsAdminOnly Boolean @default(false) featuresMetricsAdminOnly Boolean @default(false)
featuresMetricsShowUserSpecific Boolean @default(true) featuresMetricsShowUserSpecific Boolean @default(true)
featuresVersionChecking Boolean @default(true)
featuresVersionAPI String @default("https://zipline-version.diced.sh")
invitesEnabled Boolean @default(true) invitesEnabled Boolean @default(true)
invitesLength Int @default(6) invitesLength Int @default(6)

View File

@@ -1,5 +1,15 @@
import { Response } from '@/lib/api/response'; import { Response } from '@/lib/api/response';
import { Button, LoadingOverlay, NumberInput, Paper, SimpleGrid, Switch, Title } from '@mantine/core'; import {
Anchor,
Button,
LoadingOverlay,
NumberInput,
Paper,
SimpleGrid,
Switch,
TextInput,
Title,
} from '@mantine/core';
import { useForm } from '@mantine/form'; import { useForm } from '@mantine/form';
import { IconDeviceFloppy } from '@tabler/icons-react'; import { IconDeviceFloppy } from '@tabler/icons-react';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
@@ -25,6 +35,8 @@ export default function ServerSettingsFeatures({
featuresMetricsEnabled: true, featuresMetricsEnabled: true,
featuresMetricsAdminOnly: false, featuresMetricsAdminOnly: false,
featuresMetricsShowUserSpecific: true, featuresMetricsShowUserSpecific: true,
featuresVersionChecking: true,
featuresVersionAPI: 'https://zipline-version.diced.sh/',
}, },
}); });
@@ -43,6 +55,8 @@ export default function ServerSettingsFeatures({
featuresMetricsEnabled: data?.featuresMetricsEnabled ?? true, featuresMetricsEnabled: data?.featuresMetricsEnabled ?? true,
featuresMetricsAdminOnly: data?.featuresMetricsAdminOnly ?? false, featuresMetricsAdminOnly: data?.featuresMetricsAdminOnly ?? false,
featuresMetricsShowUserSpecific: data?.featuresMetricsShowUserSpecific ?? true, featuresMetricsShowUserSpecific: data?.featuresMetricsShowUserSpecific ?? true,
featuresVersionChecking: data?.featuresVersionChecking ?? true,
featuresVersionAPI: data?.featuresVersionAPI ?? 'https://zipline-version.diced.sh/',
}); });
}, [data]); }, [data]);
@@ -107,7 +121,7 @@ export default function ServerSettingsFeatures({
description='Shows metrics specific to each user, for all users.' description='Shows metrics specific to each user, for all users.'
{...form.getInputProps('featuresMetricsShowUserSpecific', { type: 'checkbox' })} {...form.getInputProps('featuresMetricsShowUserSpecific', { type: 'checkbox' })}
/> />
<div />
<Switch <Switch
label='Enable Thumbnails' label='Enable Thumbnails'
description='Enables thumbnail generation for images. Requires a server restart.' description='Enables thumbnail generation for images. Requires a server restart.'
@@ -122,6 +136,30 @@ export default function ServerSettingsFeatures({
max={16} max={16}
{...form.getInputProps('featuresThumbnailsNumberThreads')} {...form.getInputProps('featuresThumbnailsNumberThreads')}
/> />
<Switch
label='Version Checking'
description='Enable version checking for the server. This will check for updates and display the status on the sidebar to all users.'
{...form.getInputProps('featuresVersionChecking', { type: 'checkbox' })}
/>
<TextInput
label='Version API URL'
description={
<>
The URL of the version checking server. The default is{' '}
<Anchor size='xs' href='zipline-version.diced.sh' target='_blank'>
https://zipline-version.diced.sh
</Anchor>
. Visit the{' '}
<Anchor size='xs' href='https://github.com/diced/zipline-version-worker' target='_blank'>
GitHub
</Anchor>{' '}
to host your own version checking server.
</>
}
placeholder='https://zipline-version.diced.sh/'
{...form.getInputProps('featuresVersionAPI')}
/>
</SimpleGrid> </SimpleGrid>
<Button type='submit' mt='md' loading={isLoading} leftSection={<IconDeviceFloppy size='1rem' />}> <Button type='submit' mt='md' loading={isLoading} leftSection={<IconDeviceFloppy size='1rem' />}>

View File

@@ -211,6 +211,9 @@ export const DATABASE_TO_PROP = {
featuresMetricsAdminOnly: 'features.metrics.adminOnly', featuresMetricsAdminOnly: 'features.metrics.adminOnly',
featuresMetricsShowUserSpecific: 'features.metrics.showUserSpecific', featuresMetricsShowUserSpecific: 'features.metrics.showUserSpecific',
featuresVersionChecking: 'features.versionChecking',
featuresVersionAPI: 'features.versionAPI',
invitesEnabled: 'invites.enabled', invitesEnabled: 'invites.enabled',
invitesLength: 'invites.length', invitesLength: 'invites.length',

View File

@@ -160,6 +160,8 @@ export const schema = z.object({
adminOnly: z.boolean().default(false), adminOnly: z.boolean().default(false),
showUserSpecific: z.boolean().default(true), showUserSpecific: z.boolean().default(true),
}), }),
versionChecking: z.boolean().default(true),
versionAPI: z.string().url().default('https://zipline-version.diced.sh/'),
}), }),
invites: z.object({ invites: z.object({
enabled: z.boolean().default(true), enabled: z.boolean().default(true),

View File

@@ -166,6 +166,9 @@ export default fastifyPlugin(
featuresMetricsAdminOnly: z.boolean(), featuresMetricsAdminOnly: z.boolean(),
featuresMetricsShowUserSpecific: z.boolean(), featuresMetricsShowUserSpecific: z.boolean(),
featuresVersionChecking: z.boolean(),
featuresVersionAPI: z.string().url(),
invitesEnabled: z.boolean(), invitesEnabled: z.boolean(),
invitesLength: z.number().min(1).max(64), invitesLength: z.number().min(1).max(64),

View File

@@ -1,6 +1,8 @@
import { config } from '@/lib/config';
import { log } from '@/lib/logger';
import { getVersion } from '@/lib/version';
import { userMiddleware } from '@/server/middleware/user'; import { userMiddleware } from '@/server/middleware/user';
import fastifyPlugin from 'fastify-plugin'; import fastifyPlugin from 'fastify-plugin';
import { getVersion } from '@/lib/version';
export type ApiVersionResponse = { export type ApiVersionResponse = {
details: ReturnType<typeof getVersion>; details: ReturnType<typeof getVersion>;
@@ -27,25 +29,37 @@ interface VersionAPI {
}; };
} }
const logger = log('api').c('version');
export const PATH = '/api/version'; export const PATH = '/api/version';
export default fastifyPlugin( export default fastifyPlugin(
(server, _, done) => { (server, _, done) => {
server.get(PATH, { preHandler: [userMiddleware] }, async (_, res) => { server.get(PATH, { preHandler: [userMiddleware] }, async (_, res) => {
if (!config.features.versionChecking) return res.notFound();
const details = getVersion(); const details = getVersion();
const params = new URLSearchParams([['details', JSON.stringify(details)]]);
const resp = await fetch(`https://zipline-version.diced.sh/?${params.toString()}`); const url = new URL(config.features.versionAPI);
url.pathname = '/';
url.searchParams.set('details', JSON.stringify(details));
if (!resp.ok) { try {
return res.internalServerError('failed to fetch version details: ' + (await resp.text())); const resp = await fetch(url);
if (!resp.ok) {
return res.internalServerError('failed to fetch version details: ' + (await resp.text()));
}
const data: VersionAPI = await resp.json();
return res.send({
data,
details,
});
} catch (e) {
logger.error('failed to fetch version details').error(e as Error);
return res.internalServerError('failed to fetch version details: ' + (e as Error).message);
} }
const data: VersionAPI = await resp.json();
return res.send({
data,
details,
});
}); });
done(); done();