💾 Archived View for iich.space › src › app › index.ts captured on 2021-12-03 at 14:04:38.

View Raw

More Information

➡️ Next capture (2022-03-01)

-=-=-=-=-=-=-

import { Status } from '@/gemini';
import { Handler, Router } from '@/mission-control';

import { FEED_POST_COUNT, GEMINI, RECENT_POST_COUNT } from '~/constants';
import {
  getBoards,
  getPost,
  getPostsForSubscription,
  getRecentPosts,
  getSiteStats,
  setNameForIdentity,
} from '~/db/queries';
import withCertificate from '~/middleware/withCertificate';
import withQuery from '~/middleware/withQuery';
import {
  generateIdentityHash,
  getDisplayIdentityFromRequest,
} from '~/util/identity';
import FeedPage from '~/views/FeedPage';
import InfoPage from '~/views/InfoPage';
import LandingPage from '~/views/LandingPage';

import admin from './admin';
import board from './board';
import images from './images';
import post from './post';

const app = new Router<Handler>();

app.use('/', (req, res, { tb }) => {
  const boards = getBoards();
  const posts = getRecentPosts(RECENT_POST_COUNT);
  const stats = getSiteStats();
  const identity = getDisplayIdentityFromRequest(req);

  res.send(tb.include(LandingPage, { boards, identity, posts, stats }));
  res.end();
});

app.use('/favicon.txt', (_, res) => {
  res.sendStatus(20, 'text/plain');
  res.send(GEMINI);
  res.end();
});

app.use('/post', post);
app.use('/images', images);
app.use('/admin', admin);
app.use('/info', (_, res, { tb }) => {
  res.send(tb.include(InfoPage));
  res.end();
});

app.use('/posts/:id', (_, res, { params }) => {
  const post = getPost(parseInt(params.id, 10));

  if (post === undefined) {
    res.sendStatus(Status.NOT_FOUND);
    return res.end();
  }

  return res.redirect(post.path);
});

app.use(
  '/recent',
  withQuery('Boards to subscribe to (comma separated)'),
  (req, res) => {
    if (req.query!.match(/[^a-zA-Z, ]/g) !== null) {
      res.sendStatus(Status.BAD_REQUEST);
      return res.end();
    }
  },
  (req, res, { tb }) => {
    const names = req.query!.split(',').map((value) => value.toLowerCase());
    let boards = getBoards();

    if (names.includes('all') === false) {
      boards = boards.filter(({ name }) => names.includes(name));
    }

    const boardIds = boards.map(({ id }) => id);
    const posts = getPostsForSubscription(boardIds, FEED_POST_COUNT);

    res.send(tb.include(FeedPage, { boards, posts }));
    res.end();
  },
);

app.use('/change-name', withCertificate, withQuery('Name'), (req, res) => {
  const name = req.query!.replace(/[^-a-zA-Z0-9]/g, '');
  const hash = generateIdentityHash(req.fingerprint!);
  setNameForIdentity(req.fingerprint!, name, hash);
  res.redirect('/');
});

app.use('/:name/', board);

export default app;