ditto/src/app.ts

219 lines
9.2 KiB
TypeScript
Raw Normal View History

2023-10-06 00:58:47 +00:00
import { Conf } from '@/config.ts';
import '@/cron.ts';
import { type User } from '@/db/users.ts';
2023-08-17 02:53:51 +00:00
import {
type Context,
cors,
2023-12-28 02:57:20 +00:00
Debug,
2023-08-17 02:53:51 +00:00
type Handler,
Hono,
type HonoEnv,
logger,
type MiddlewareHandler,
type NostrEvent,
2023-10-06 00:58:47 +00:00
sentryMiddleware,
2023-09-11 05:19:56 +00:00
serveStatic,
2023-08-17 02:53:51 +00:00
} from '@/deps.ts';
2023-08-14 16:02:09 +00:00
import '@/firehose.ts';
import { Time } from '@/utils.ts';
2023-03-05 01:55:28 +00:00
2023-07-27 15:36:19 +00:00
import { actorController } from './controllers/activitypub/actor.ts';
2023-04-29 21:35:44 +00:00
import {
accountController,
accountLookupController,
accountSearchController,
accountStatusesController,
2024-01-01 05:35:37 +00:00
blockController,
createAccountController,
2023-09-01 18:14:27 +00:00
favouritesController,
2023-08-19 18:34:35 +00:00
followController,
followersController,
followingController,
2023-04-29 22:59:42 +00:00
relationshipsController,
2024-01-01 18:50:09 +00:00
unblockController,
unfollowController,
2023-06-11 19:41:16 +00:00
updateCredentialsController,
verifyCredentialsController,
2023-04-30 19:45:30 +00:00
} from './controllers/api/accounts.ts';
import { adminAccountsController } from './controllers/api/admin.ts';
2023-04-30 19:45:30 +00:00
import { appCredentialsController, createAppController } from './controllers/api/apps.ts';
2024-01-01 18:43:53 +00:00
import { blocksController } from './controllers/api/blocks.ts';
import { bookmarksController } from './controllers/api/bookmarks.ts';
2023-09-11 09:55:15 +00:00
import { emptyArrayController, emptyObjectController, notImplementedController } from './controllers/api/fallback.ts';
import { instanceController } from './controllers/api/instance.ts';
import { mediaController } from './controllers/api/media.ts';
import { notificationsController } from './controllers/api/notifications.ts';
2023-04-30 19:45:30 +00:00
import { createTokenController, oauthAuthorizeController, oauthController } from './controllers/api/oauth.ts';
2024-01-12 00:47:26 +00:00
import {
configController,
frontendConfigController,
pleromaAdminDeleteStatusController,
updateConfigController,
} from './controllers/api/pleroma.ts';
2023-05-13 19:27:49 +00:00
import { preferencesController } from './controllers/api/preferences.ts';
import { relayController } from './controllers/nostr/relay.ts';
import { searchController } from './controllers/api/search.ts';
2023-05-07 17:32:24 +00:00
import {
2024-01-01 19:45:07 +00:00
bookmarkController,
2023-05-07 17:32:24 +00:00
contextController,
createStatusController,
2024-03-30 18:34:18 +00:00
deleteStatusController,
2023-05-07 17:32:24 +00:00
favouriteController,
favouritedByController,
2024-01-01 22:23:08 +00:00
pinController,
rebloggedByController,
2023-05-07 17:32:24 +00:00
statusController,
2024-01-01 20:35:46 +00:00
unbookmarkController,
2024-01-01 22:23:08 +00:00
unpinController,
zapController,
2023-05-07 17:32:24 +00:00
} from './controllers/api/statuses.ts';
import { streamingController } from './controllers/api/streaming.ts';
import {
hashtagTimelineController,
homeTimelineController,
publicTimelineController,
} from './controllers/api/timelines.ts';
import { trendingTagsController } from './controllers/api/trends.ts';
2023-04-30 19:51:56 +00:00
import { indexController } from './controllers/site.ts';
2023-07-09 23:50:47 +00:00
import { hostMetaController } from './controllers/well-known/host-meta.ts';
2023-07-10 01:32:45 +00:00
import { nodeInfoController, nodeInfoSchemaController } from './controllers/well-known/nodeinfo.ts';
2023-07-09 17:55:37 +00:00
import { nostrController } from './controllers/well-known/nostr.ts';
2023-07-09 23:50:47 +00:00
import { webfingerController } from './controllers/well-known/webfinger.ts';
2023-08-28 20:38:32 +00:00
import { auth19, requirePubkey } from './middleware/auth19.ts';
import { auth98, requireProof, requireRole } from './middleware/auth98.ts';
import { cache } from './middleware/cache.ts';
2023-09-11 09:04:55 +00:00
import { csp } from './middleware/csp.ts';
2023-03-05 02:19:57 +00:00
2023-04-29 20:22:10 +00:00
interface AppEnv extends HonoEnv {
Variables: {
/** Hex pubkey for the current user. If provided, the user is considered "logged in." */
2023-04-29 20:22:10 +00:00
pubkey?: string;
/** Hex secret key for the current user. Optional, but easiest way to use legacy Mastodon apps. */
2024-02-12 17:40:17 +00:00
seckey?: Uint8Array;
2023-07-08 23:41:11 +00:00
/** NIP-98 signed event proving the pubkey is owned by the user. */
proof?: NostrEvent;
/** User associated with the pubkey, if any. */
user?: User;
2023-04-29 20:22:10 +00:00
};
}
2023-03-05 01:55:28 +00:00
2023-04-29 20:22:10 +00:00
type AppContext = Context<AppEnv>;
type AppMiddleware = MiddlewareHandler<AppEnv>;
type AppController = Handler<AppEnv>;
const app = new Hono<AppEnv>();
2023-10-06 00:58:47 +00:00
if (Conf.sentryDsn) {
// @ts-ignore Mismatched hono types.
app.use('*', sentryMiddleware({ dsn: Conf.sentryDsn }));
}
const debug = Debug('ditto:http');
2023-12-31 18:47:00 +00:00
app.use('/api/*', logger(debug));
app.use('/relay/*', logger(debug));
app.use('/.well-known/*', logger(debug));
app.use('/users/*', logger(debug));
app.use('/nodeinfo/*', logger(debug));
app.use('/oauth/*', logger(debug));
app.get('/api/v1/streaming', streamingController);
app.get('/api/v1/streaming/', streamingController);
app.get('/relay', relayController);
2023-09-11 09:04:55 +00:00
app.use('*', csp(), cors({ origin: '*', exposeHeaders: ['link'] }), auth19, auth98());
2023-03-05 04:49:08 +00:00
2023-07-09 21:08:49 +00:00
app.get('/.well-known/webfinger', webfingerController);
app.get('/.well-known/host-meta', hostMetaController);
2023-07-10 01:32:45 +00:00
app.get('/.well-known/nodeinfo', nodeInfoController);
2023-07-09 17:55:37 +00:00
app.get('/.well-known/nostr.json', nostrController);
2023-07-27 15:36:19 +00:00
app.get('/users/:username', actorController);
2023-07-10 01:32:45 +00:00
app.get('/nodeinfo/:version', nodeInfoSchemaController);
2023-03-05 02:19:57 +00:00
app.get('/api/v1/instance', instanceController);
2023-03-05 01:55:28 +00:00
app.get('/api/v1/apps/verify_credentials', appCredentialsController);
2023-03-05 02:59:39 +00:00
app.post('/api/v1/apps', createAppController);
2023-03-05 03:36:53 +00:00
app.post('/oauth/token', createTokenController);
2023-03-05 06:36:37 +00:00
app.post('/oauth/revoke', emptyObjectController);
2023-04-30 18:28:49 +00:00
app.post('/oauth/authorize', oauthAuthorizeController);
app.get('/oauth/authorize', oauthController);
2023-03-05 03:36:53 +00:00
2023-11-20 23:57:47 +00:00
app.post('/api/v1/accounts', requireProof({ pow: 20 }), createAccountController);
2023-08-28 20:38:32 +00:00
app.get('/api/v1/accounts/verify_credentials', requirePubkey, verifyCredentialsController);
app.patch('/api/v1/accounts/update_credentials', requirePubkey, updateCredentialsController);
app.get('/api/v1/accounts/search', accountSearchController);
2023-04-29 21:23:23 +00:00
app.get('/api/v1/accounts/lookup', accountLookupController);
2024-03-30 23:32:54 +00:00
app.get('/api/v1/accounts/relationships', requirePubkey, relationshipsController);
2024-01-01 18:50:09 +00:00
app.post('/api/v1/accounts/:pubkey{[0-9a-f]{64}}/block', requirePubkey, blockController);
app.post('/api/v1/accounts/:pubkey{[0-9a-f]{64}}/unblock', requirePubkey, unblockController);
app.post('/api/v1/accounts/:pubkey{[0-9a-f]{64}}/follow', requirePubkey, followController);
app.post('/api/v1/accounts/:pubkey{[0-9a-f]{64}}/unfollow', requirePubkey, unfollowController);
app.get('/api/v1/accounts/:pubkey{[0-9a-f]{64}}/followers', followersController);
app.get('/api/v1/accounts/:pubkey{[0-9a-f]{64}}/following', followingController);
app.get('/api/v1/accounts/:pubkey{[0-9a-f]{64}}/statuses', accountStatusesController);
2023-04-29 21:35:44 +00:00
app.get('/api/v1/accounts/:pubkey{[0-9a-f]{64}}', accountController);
app.get('/api/v1/statuses/:id{[0-9a-f]{64}}/favourited_by', favouritedByController);
app.get('/api/v1/statuses/:id{[0-9a-f]{64}}/reblogged_by', rebloggedByController);
2023-04-30 01:23:51 +00:00
app.get('/api/v1/statuses/:id{[0-9a-f]{64}}/context', contextController);
2023-04-29 22:26:56 +00:00
app.get('/api/v1/statuses/:id{[0-9a-f]{64}}', statusController);
2024-01-01 19:45:07 +00:00
app.post('/api/v1/statuses/:id{[0-9a-f]{64}}/favourite', requirePubkey, favouriteController);
app.post('/api/v1/statuses/:id{[0-9a-f]{64}}/bookmark', requirePubkey, bookmarkController);
2024-01-01 20:35:46 +00:00
app.post('/api/v1/statuses/:id{[0-9a-f]{64}}/unbookmark', requirePubkey, unbookmarkController);
2024-01-01 22:23:08 +00:00
app.post('/api/v1/statuses/:id{[0-9a-f]{64}}/pin', requirePubkey, pinController);
app.post('/api/v1/statuses/:id{[0-9a-f]{64}}/unpin', requirePubkey, unpinController);
app.post('/api/v1/statuses/:id{[0-9a-f]{64}}/zap', requirePubkey, zapController);
2023-08-28 20:38:32 +00:00
app.post('/api/v1/statuses', requirePubkey, createStatusController);
2024-03-30 18:34:18 +00:00
app.delete('/api/v1/statuses/:id{[0-9a-f]{64}}', requirePubkey, deleteStatusController);
2023-03-05 05:26:25 +00:00
app.post('/api/v1/media', requireRole('user', { validatePayload: false }), mediaController);
app.post('/api/v2/media', requireRole('user', { validatePayload: false }), mediaController);
app.get('/api/v1/timelines/home', requirePubkey, homeTimelineController);
app.get('/api/v1/timelines/public', publicTimelineController);
2023-08-29 00:51:21 +00:00
app.get('/api/v1/timelines/tag/:hashtag', hashtagTimelineController);
2023-03-18 19:49:44 +00:00
2023-05-13 19:27:49 +00:00
app.get('/api/v1/preferences', preferencesController);
2023-05-13 19:45:13 +00:00
app.get('/api/v1/search', searchController);
app.get('/api/v2/search', searchController);
2023-05-13 19:27:49 +00:00
app.get('/api/pleroma/frontend_configurations', frontendConfigController);
app.get('/api/v1/trends/tags', cache({ cacheName: 'web', expires: Time.minutes(15) }), trendingTagsController);
app.get('/api/v1/trends', cache({ cacheName: 'web', expires: Time.minutes(15) }), trendingTagsController);
2023-08-28 20:38:32 +00:00
app.get('/api/v1/notifications', requirePubkey, notificationsController);
2023-09-01 18:14:27 +00:00
app.get('/api/v1/favourites', requirePubkey, favouritesController);
app.get('/api/v1/bookmarks', requirePubkey, bookmarksController);
2024-01-01 18:43:53 +00:00
app.get('/api/v1/blocks', requirePubkey, blocksController);
app.get('/api/v1/admin/accounts', adminAccountsController);
app.get('/api/v1/pleroma/admin/config', requireRole('admin'), configController);
app.post('/api/v1/pleroma/admin/config', requireRole('admin'), updateConfigController);
2024-01-12 00:47:26 +00:00
app.delete('/api/v1/pleroma/admin/statuses/:id', requireRole('admin'), pleromaAdminDeleteStatusController);
2023-09-03 23:49:45 +00:00
// Not (yet) implemented.
2023-03-05 06:36:37 +00:00
app.get('/api/v1/custom_emojis', emptyArrayController);
app.get('/api/v1/filters', emptyArrayController);
app.get('/api/v1/mutes', emptyArrayController);
app.get('/api/v1/domain_blocks', emptyArrayController);
2023-04-30 02:14:00 +00:00
app.get('/api/v1/markers', emptyObjectController);
2023-05-13 19:27:49 +00:00
app.get('/api/v1/conversations', emptyArrayController);
app.get('/api/v1/lists', emptyArrayController);
2023-09-11 09:55:15 +00:00
app.use('/api/*', notImplementedController);
2023-09-11 09:14:08 +00:00
app.get('*', serveStatic({ root: './public/' }));
app.get('*', serveStatic({ root: './static/' }));
2023-09-11 05:19:56 +00:00
app.get('*', serveStatic({ path: './public/index.html' }));
2023-04-30 19:51:56 +00:00
app.get('/', indexController);
2023-03-05 01:55:28 +00:00
export default app;
2023-04-29 20:22:10 +00:00
export type { AppContext, AppController, AppMiddleware };