simpkey/src/router.ts

274 lines
7.2 KiB
TypeScript
Raw Normal View History

2020-07-23 18:53:00 +02:00
import { Context, DefaultState } from 'koa';
import Router from 'koa-router';
2020-07-24 06:44:09 +02:00
import { signIn, api, i, notesShow, usersShowByName } from './misskey';
2020-07-23 18:53:00 +02:00
import { Note } from './models/Note';
import { die } from './die';
export const router = new Router<DefaultState, Context>();
const staticRouting = [
2022-11-17 21:25:19 +01:00
[ 'about', 'About Simpkey' ],
[ 'terms', 'Terms of Use' ],
[ 'privacy-policy', 'Privacy Policy' ],
[ 'settings', 'Settings' ],
[ 'help', 'Help' ],
2020-07-23 18:53:00 +02:00
];
for (const [ name, title ] of staticRouting) {
router.get('/' + name, async ctx => {
await ctx.render(name, { title });
});
}
async function timeline(ctx: Context, host: string, endpoint: string, timelineName: string, token: string) {
const user = await i(host, token);
2020-07-24 06:44:09 +02:00
const notes = await api<Note[]>(host, endpoint, { i: token });
2020-07-23 18:53:00 +02:00
2020-07-24 06:58:36 +02:00
const myself = await i(host, token);
2020-07-23 18:53:00 +02:00
await ctx.render('timeline', {
title: timelineName + ' - Simpkey',
2020-07-24 06:58:36 +02:00
user,
notes,
timelineName,
canRenote: (note: Note) => note.userId === myself.id || note.visibility === 'public' || note.visibility === 'home',
canReact: (note: Note) => note.userId !== myself.id,
2020-07-23 18:53:00 +02:00
});
}
router.get('/', async ctx => {
const token = ctx.cookies.get('i');
const host = ctx.cookies.get('host');
if (!token || !host) {
console.log('no session so show top page');
await ctx.render('index', {
title: 'Simpkey'
});
return;
}
2022-11-17 21:25:19 +01:00
await timeline(ctx, host, 'notes/timeline', 'Home Timeline', token);
2020-07-23 18:53:00 +02:00
});
router.get('/ltl', async ctx => {
const token = ctx.cookies.get('i');
const host = ctx.cookies.get('host');
if (!token || !host) {
2022-11-17 21:25:19 +01:00
await die(ctx, 'Please login');
2020-07-23 18:53:00 +02:00
return;
}
const meta = await api<any>(host, 'meta', { i: token });
if (meta.disableLocalTimeline) {
2022-11-17 21:25:19 +01:00
await die(ctx, 'Local timeline has been disabled');
2020-07-23 18:53:00 +02:00
} else {
2022-11-17 21:25:19 +01:00
await timeline(ctx, host, 'notes/local-timeline', 'Local Timeline', token);
2020-07-23 18:53:00 +02:00
}
});
router.get('/stl', async ctx => {
const token = ctx.cookies.get('i');
const host = ctx.cookies.get('host');
if (!token || !host) {
2022-11-17 21:25:19 +01:00
await die(ctx, 'Please login');
2020-07-23 18:53:00 +02:00
return;
}
const meta = await api<any>(host, 'meta', { i: token });
if (meta.disableLocalTimeline) {
2022-11-17 21:25:19 +01:00
await die(ctx, 'Social timeline has been disabled');
2020-07-23 18:53:00 +02:00
} else {
2022-11-17 21:25:19 +01:00
await timeline(ctx, host, 'notes/hybrid-timeline', 'Social Timeline', token);
2020-07-23 18:53:00 +02:00
}
});
2020-07-23 20:53:44 +02:00
2020-07-23 18:53:00 +02:00
router.get('/gtl', async ctx => {
const token = ctx.cookies.get('i');
const host = ctx.cookies.get('host');
if (!token || !host) {
2022-11-17 21:25:19 +01:00
await die(ctx, 'Please login');
2020-07-23 18:53:00 +02:00
return;
}
const meta = await api<any>(host, 'meta', { i: token });
if (meta.disableGlobalTimeline) {
2022-11-17 21:25:19 +01:00
await die(ctx, 'Global timeline has been disabled');
2020-07-23 18:53:00 +02:00
} else {
2022-11-17 21:25:19 +01:00
await timeline(ctx, host, 'notes/global-timeline', 'Global Timeline', token);
2020-07-23 18:53:00 +02:00
}
});
router.get('/notifications', async ctx => {
const token = ctx.cookies.get('i');
const host = ctx.cookies.get('host');
if (!token || !host) {
2022-11-17 21:25:19 +01:00
await die(ctx, 'Please login');
return;
}
2020-07-24 06:58:36 +02:00
const myself = await i(host, token);
const notifications = await api<any>(host, 'i/notifications', { i: token });
2020-07-24 06:58:36 +02:00
await ctx.render('notifications', {
notifications,
canRenote: (note: Note) => note.userId === myself.id || note.visibility === 'public' || note.visibility === 'home',
canReact: (note: Note) => note.userId !== myself.id,
});
});
2020-07-24 06:44:09 +02:00
router.get('/renote/:noteId', async ctx => {
2020-07-23 20:53:44 +02:00
const token = ctx.cookies.get('i');
const host = ctx.cookies.get('host');
if (!token || !host) {
2022-11-17 21:25:19 +01:00
await die(ctx, 'Please login');
2020-07-23 20:53:44 +02:00
return;
}
try {
2020-07-24 06:58:36 +02:00
const myself = await i(host, token);
2020-07-24 06:44:09 +02:00
const note = await notesShow(host, ctx.params.noteId);
2020-07-24 06:58:36 +02:00
await ctx.render('renote', {
note,
canRenote: note.userId === myself.id || note.visibility === 'public' || note.visibility === 'home'
});
2020-07-23 20:53:44 +02:00
} catch(e) {
await die(ctx, e.message);
}
});
2020-07-24 06:44:09 +02:00
router.get('/reply/:noteId', async ctx => {
2020-07-23 20:53:44 +02:00
const token = ctx.cookies.get('i');
const host = ctx.cookies.get('host');
if (!token || !host) {
2022-11-17 21:25:19 +01:00
await die(ctx, 'Please login');
2020-07-23 20:53:44 +02:00
return;
}
try {
2020-07-24 06:44:09 +02:00
const note = await notesShow(host, ctx.params.noteId);
2020-07-23 20:53:44 +02:00
await ctx.render('reply', { note });
} catch(e) {
await die(ctx, e.message);
}
});
2020-07-24 06:44:09 +02:00
router.get('/react/:noteId', async ctx => {
2020-07-23 20:53:44 +02:00
const token = ctx.cookies.get('i');
const host = ctx.cookies.get('host');
if (!token || !host) {
2022-11-17 21:25:19 +01:00
await die(ctx, 'Please login');
2020-07-23 20:53:44 +02:00
return;
}
try {
2020-07-24 06:44:09 +02:00
const note = await notesShow(host, ctx.params.noteId);
2020-07-23 20:53:44 +02:00
const myself = await i(host, token);
2020-07-24 06:58:36 +02:00
await ctx.render('react', {
note,
reactions: myself.clientData?.reactions,
canReact: note.userId !== myself.id && !note.myReaction
});
2020-07-23 20:53:44 +02:00
} catch(e) {
await die(ctx, e.message);
}
});
2020-07-24 06:44:09 +02:00
router.get('/@:acct', async ctx => {
2020-07-24 06:58:36 +02:00
const token = ctx.cookies.get('i');
2020-07-24 06:44:09 +02:00
const host = ctx.cookies.get('host');
2020-07-24 06:58:36 +02:00
if (!token || !host) {
2022-11-17 21:25:19 +01:00
await die(ctx, 'Please login');
2020-07-24 06:44:09 +02:00
return;
}
const acct = ctx.params.acct.split('@');
const username = acct[0];
const remoteHost = acct[1];
2020-07-24 06:58:36 +02:00
const myself = await i(host, token);
2020-07-24 06:44:09 +02:00
const user = await usersShowByName(host, username, remoteHost);
2020-07-24 06:58:36 +02:00
const notes = await api<Note[]>(host, 'users/notes', { i: token, userId: user.id });
await ctx.render('user', {
user,
notes,
canRenote: (note: Note) => note.userId === myself.id || note.visibility === 'public' || note.visibility === 'home',
canReact: (note: Note) => note.userId !== myself.id,
});
2020-07-24 06:44:09 +02:00
});
2020-07-23 18:53:00 +02:00
router.post('/', async ctx => {
const {
host,
username,
password,
token
} = ctx.request.body;
if (!host || !username || !password) {
2022-11-17 21:25:19 +01:00
await die(ctx, 'Some parameters are missing. Please retry.');
2020-07-23 18:53:00 +02:00
return;
}
try {
const { id, i } = await signIn(host, username, password, token);
ctx.cookies.set('id', id);
ctx.cookies.set('host', host);
ctx.cookies.set('i', i);
console.log('login as ' + username);
ctx.redirect('/');
} catch (err) {
await die(ctx, err.message);
console.error(err);
}
});
router.post('/action/:action', async ctx => {
const i = ctx.cookies.get('i');
const host = ctx.cookies.get('host');
if (!i || !host) {
2022-11-17 21:25:19 +01:00
await die(ctx, 'Please login');
2020-07-23 18:53:00 +02:00
return;
}
const action = ctx.params.action as string;
2020-07-23 20:53:44 +02:00
try {
switch (action) {
case 'create-note': {
2020-07-24 15:43:39 +02:00
const { text, renoteId, replyId, useCw, cw, visibility } = ctx.request.body;
2020-07-23 20:53:44 +02:00
const opts = { i } as Record<string, string>;
if (text) opts.text = text;
if (renoteId) opts.renoteId = renoteId;
if (replyId) opts.replyId = replyId;
2020-07-24 07:18:17 +02:00
if (useCw) opts.cw = cw || '';
2020-07-24 15:43:39 +02:00
if (visibility) opts.visibility = visibility;
2020-07-23 20:53:44 +02:00
await api(host, 'notes/create', opts);
break;
}
case 'react': {
const { noteId, reaction, customReaction } = ctx.request.body;
if (!noteId) throw new Error('noteId required');
2022-11-17 21:25:19 +01:00
if (!reaction) throw new Error('No emoji was specified');
2020-07-23 20:53:44 +02:00
await api(host, 'notes/reactions/create', { i, noteId, reaction: reaction === 'custom' ? customReaction : reaction });
break;
}
case 'unreact': {
const { noteId } = ctx.request.body;
if (!noteId) throw new Error('noteId required');
await api(host, 'notes/reactions/delete', { i, noteId });
break;
}
}
} catch (e) {
await die(ctx, e.message);
return;
2020-07-23 18:53:00 +02:00
}
2020-07-23 20:53:44 +02:00
ctx.redirect('/');
2020-07-23 18:53:00 +02:00
});
router.post('/logout', ctx => {
ctx.cookies.set('id');
ctx.cookies.set('host');
ctx.cookies.set('i');
ctx.redirect('/');
});
// Return 404 for other pages
router.all('(.*)', async ctx => {
ctx.status = 404;
2022-11-17 21:25:19 +01:00
await die(ctx, 'Resource not found');
2020-07-23 18:53:00 +02:00
});