mirror of https://github.com/AlphaNecron/Void.git
132 lines
3.3 KiB
TypeScript
132 lines
3.3 KiB
TypeScript
import type { NextApiRequest, NextApiResponse } from 'next';
|
|
import type { CookieSerializeOptions } from 'cookie';
|
|
import type { File, User } from '@prisma/client';
|
|
|
|
import { serialize } from 'cookie';
|
|
import { sign64, unsign64 } from '../utils';
|
|
import config from '../config';
|
|
import prisma from '../prisma';
|
|
|
|
export interface NextApiFile {
|
|
fieldname: string;
|
|
originalname: string;
|
|
encoding: string;
|
|
mimetype: string;
|
|
buffer: string;
|
|
size: number;
|
|
}
|
|
|
|
export type NextApiReq = NextApiRequest & {
|
|
user: () => Promise<{
|
|
username: string;
|
|
token: string;
|
|
embedTitle: string;
|
|
embedColor: string;
|
|
isAdmin: boolean;
|
|
id: number;
|
|
password: string;
|
|
} | null | void>;
|
|
getCookie: (name: string) => string | null;
|
|
cleanCookie: (name: string) => void;
|
|
file?: NextApiFile;
|
|
}
|
|
|
|
export type NextApiRes = NextApiResponse & {
|
|
error: (message: string) => void;
|
|
forbid: (message: string) => void;
|
|
bad: (message: string) => void;
|
|
json: (json: any) => void;
|
|
setCookie: (name: string, value: unknown, options: CookieSerializeOptions) => void;
|
|
}
|
|
|
|
export const withAxtral = (handler: (req: NextApiRequest, res: NextApiResponse) => unknown) => (req: NextApiReq, res: NextApiRes) => {
|
|
res.error = (message: string) => {
|
|
res.setHeader('Content-Type', 'application/json');
|
|
res.json({
|
|
error: message
|
|
});
|
|
};
|
|
|
|
res.forbid = (message: string) => {
|
|
res.setHeader('Content-Type', 'application/json');
|
|
res.status(403);
|
|
res.json({
|
|
error: '403: ' + message
|
|
});
|
|
};
|
|
|
|
res.bad = (message: string) => {
|
|
res.setHeader('Content-Type', 'application/json');
|
|
res.status(401);
|
|
res.json({
|
|
error: '403: ' + message
|
|
});
|
|
};
|
|
|
|
res.json = (json: any) => {
|
|
res.setHeader('Content-Type', 'application/json');
|
|
res.end(JSON.stringify(json));
|
|
};
|
|
|
|
req.getCookie = (name: string) => {
|
|
const cookie = req.cookies[name];
|
|
if (!cookie) return null;
|
|
|
|
const unsigned = unsign64(cookie, config.core.secret);
|
|
return unsigned ? unsigned : null;
|
|
};
|
|
req.cleanCookie = (name: string) => {
|
|
res.setHeader('Set-Cookie', serialize(name, '', {
|
|
path: '/',
|
|
expires: new Date(1),
|
|
maxAge: undefined
|
|
}));
|
|
};
|
|
req.user = async () => {
|
|
try {
|
|
const userId = req.getCookie('user');
|
|
if (!userId) return null;
|
|
const user = await prisma.user.findFirst({
|
|
where: {
|
|
id: Number(userId)
|
|
},
|
|
select: {
|
|
isAdmin: true,
|
|
embedColor: true,
|
|
embedTitle: true,
|
|
id: true,
|
|
password: true,
|
|
token: true,
|
|
username: true
|
|
}
|
|
});
|
|
|
|
if (!user) return null;
|
|
return user;
|
|
} catch (e) {
|
|
if (e.code && e.code === 'ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH') {
|
|
req.cleanCookie('user');
|
|
return null;
|
|
}
|
|
}
|
|
};
|
|
|
|
res.setCookie = (name: string, value: unknown, options?: CookieSerializeOptions) => setCookie(res, name, value, options || {});
|
|
|
|
return handler(req, res);
|
|
};
|
|
|
|
export const setCookie = (
|
|
res: NextApiResponse,
|
|
name: string,
|
|
value: unknown,
|
|
options: CookieSerializeOptions = {}
|
|
) => {
|
|
|
|
if ('maxAge' in options) {
|
|
options.expires = new Date(Date.now() + options.maxAge);
|
|
options.maxAge /= 1000;
|
|
}
|
|
const signed = sign64(String(value), config.core.secret);
|
|
res.setHeader('Set-Cookie', serialize(name, signed, options));
|
|
}; |