From 4285763c9dac0c35197091b070f0403938c009ad Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Wed, 12 Jun 2024 19:47:26 -0500 Subject: [PATCH] Add instance v2 controller --- src/app.ts | 12 +++-- src/controllers/api/instance.ts | 90 +++++++++++++++++++++++++++++++-- 2 files changed, 95 insertions(+), 7 deletions(-) diff --git a/src/app.ts b/src/app.ts index 15d4fc5..5ab31d8 100644 --- a/src/app.ts +++ b/src/app.ts @@ -6,7 +6,6 @@ import { cors, logger, serveStatic } from 'hono/middleware'; import { Conf } from '@/config.ts'; import { cron } from '@/cron.ts'; import { startFirehose } from '@/firehose.ts'; -import { Time } from '@/utils.ts'; import { accountController, @@ -42,7 +41,11 @@ import { nameRequestsController, } from '@/controllers/api/ditto.ts'; import { emptyArrayController, emptyObjectController, notImplementedController } from '@/controllers/api/fallback.ts'; -import { instanceController } from '@/controllers/api/instance.ts'; +import { + instanceDescriptionController, + instanceV1Controller, + instanceV2Controller, +} from '@/controllers/api/instance.ts'; import { markersController, updateMarkersController } from '@/controllers/api/markers.ts'; import { mediaController } from '@/controllers/api/media.ts'; import { mutesController } from '@/controllers/api/mutes.ts'; @@ -103,7 +106,6 @@ import { indexController } from '@/controllers/site.ts'; import { nodeInfoController, nodeInfoSchemaController } from '@/controllers/well-known/nodeinfo.ts'; import { nostrController } from '@/controllers/well-known/nostr.ts'; import { auth98Middleware, requireProof, requireRole } from '@/middleware/auth98Middleware.ts'; -import { cacheMiddleware } from '@/middleware/cacheMiddleware.ts'; import { cspMiddleware } from '@/middleware/cspMiddleware.ts'; import { requireSigner } from '@/middleware/requireSigner.ts'; import { signerMiddleware } from '@/middleware/signerMiddleware.ts'; @@ -164,7 +166,9 @@ app.get('/.well-known/nostr.json', nostrController); app.get('/nodeinfo/:version', nodeInfoSchemaController); -app.get('/api/v1/instance', cacheMiddleware({ cacheName: 'web', expires: Time.minutes(5) }), instanceController); +app.get('/api/v1/instance', instanceV1Controller); +app.get('/api/v2/instance', instanceV2Controller); +app.get('/api/v1/instance/extended_description', instanceDescriptionController); app.get('/api/v1/apps/verify_credentials', appCredentialsController); app.post('/api/v1/apps', createAppController); diff --git a/src/controllers/api/instance.ts b/src/controllers/api/instance.ts index 6287325..4c3e981 100644 --- a/src/controllers/api/instance.ts +++ b/src/controllers/api/instance.ts @@ -3,7 +3,9 @@ import { Conf } from '@/config.ts'; import { Storages } from '@/storages.ts'; import { getInstanceMetadata } from '@/utils/instance.ts'; -const instanceController: AppController = async (c) => { +const version = '0.0.0 (compatible; Ditto 0.0.1)'; + +const instanceV1Controller: AppController = async (c) => { const { host, protocol } = Conf.url; const meta = await getInstanceMetadata(await Storages.db(), c.req.raw.signal); @@ -54,7 +56,7 @@ const instanceController: AppController = async (c) => { urls: { streaming_api: `${wsProtocol}//${host}`, }, - version: '0.0.0 (compatible; Ditto 0.0.1)', + version, email: meta.email, nostr: { pubkey: Conf.pubkey, @@ -67,4 +69,86 @@ const instanceController: AppController = async (c) => { }); }; -export { instanceController }; +const instanceV2Controller: AppController = async (c) => { + const { host, protocol } = Conf.url; + const meta = await getInstanceMetadata(await Storages.db(), c.req.raw.signal); + + /** Protocol to use for WebSocket URLs, depending on the protocol of the `LOCAL_DOMAIN`. */ + const wsProtocol = protocol === 'http:' ? 'ws:' : 'wss:'; + + return c.json({ + domain: host, + title: meta.name, + version, + source_url: 'https://gitlab.com/soapbox-pub/ditto', + description: meta.about, + usage: { + users: { + active_month: 0, + }, + }, + thumbnail: { + url: meta.picture, + blurhash: '', + versions: { + '@1x': meta.picture, + '@2x': meta.picture, + }, + }, + languages: [ + 'en', + ], + configuration: { + urls: { + streaming: `${wsProtocol}//${host}`, + }, + vapid: { + public_key: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=', + }, + accounts: { + max_featured_tags: 10, + max_pinned_statuses: 5, + }, + statuses: { + max_characters: Conf.postCharLimit, + max_media_attachments: 4, + characters_reserved_per_url: 23, + }, + media_attachments: { + supported_mime_types: [], + image_size_limit: 16777216, + image_matrix_limit: 33177600, + video_size_limit: 103809024, + video_frame_rate_limit: 120, + video_matrix_limit: 8294400, + }, + polls: { + max_options: 4, + max_characters_per_option: 50, + min_expiration: 300, + max_expiration: 2629746, + }, + translation: { + enabled: false, + }, + }, + registrations: { + enabled: false, + approval_required: false, + message: null, + url: null, + }, + rules: [], + }); +}; + +const instanceDescriptionController: AppController = async (c) => { + const meta = await getInstanceMetadata(await Storages.db(), c.req.raw.signal); + + return c.json({ + content: meta.about, + updated_at: new Date((meta.event?.created_at ?? 0) * 1000).toISOString(), + }); +}; + +export { instanceDescriptionController, instanceV1Controller, instanceV2Controller };