mirror of
https://github.com/diced/zipline.git
synced 2026-04-28 10:43:06 -07:00
92 lines
2.4 KiB
TypeScript
92 lines
2.4 KiB
TypeScript
import { config } from '@/lib/config';
|
|
import { decryptToken } from '@/lib/crypto';
|
|
import { prisma } from '@/lib/db';
|
|
import { User, userSelect } from '@/lib/db/models/user';
|
|
import { FastifyReply } from 'fastify';
|
|
import { FastifyRequest } from 'fastify/types/request';
|
|
import { getSession } from '../session';
|
|
import * as cookie from 'cookie';
|
|
import { ApiError } from '@/lib/api/errors';
|
|
|
|
declare module 'fastify' {
|
|
export interface FastifyRequest {
|
|
user: User;
|
|
}
|
|
}
|
|
|
|
export function parseUserToken(encryptedToken: string | undefined | null): string;
|
|
export function parseUserToken(encryptedToken: string | undefined | null, noThrow: true): string | null;
|
|
export function parseUserToken(
|
|
encryptedToken: string | undefined | null,
|
|
noThrow: boolean = false,
|
|
): string | null {
|
|
if (!encryptedToken) {
|
|
if (noThrow) return null;
|
|
throw new ApiError(2001);
|
|
}
|
|
|
|
const decryptedToken = decryptToken(encryptedToken, config.core.secret);
|
|
if (!decryptedToken) {
|
|
if (noThrow) return null;
|
|
throw new ApiError(2001);
|
|
}
|
|
|
|
const [date, token] = decryptedToken;
|
|
if (isNaN(new Date(date).getTime())) {
|
|
if (noThrow) return null;
|
|
|
|
throw new ApiError(2001);
|
|
}
|
|
|
|
return token;
|
|
}
|
|
|
|
export async function userMiddleware(req: FastifyRequest, res: FastifyReply) {
|
|
const cookies = cookie.parse(req.headers.cookie ?? '');
|
|
|
|
// conditions met to allow anonymous folder uploads but later handled in the upload route
|
|
const anonFolderUpload =
|
|
req.headers['x-zipline-folder'] &&
|
|
['/api/upload', '/api/upload/partial'].includes(req.url.toLowerCase().split('?')[0]) &&
|
|
!req.headers.authorization &&
|
|
!cookies['zipline_session'];
|
|
if (anonFolderUpload) return;
|
|
|
|
const authorization = req.headers.authorization;
|
|
|
|
if (authorization) {
|
|
const token = parseUserToken(authorization);
|
|
|
|
const user = await prisma.user.findFirst({
|
|
where: {
|
|
token,
|
|
},
|
|
select: userSelect,
|
|
});
|
|
if (!user) throw new ApiError(2001);
|
|
|
|
req.user = user;
|
|
|
|
return;
|
|
}
|
|
|
|
const session = await getSession(req, res);
|
|
if (session.tokenAuth) throw new ApiError(2004);
|
|
|
|
if (!session.id || !session.sessionId) throw new ApiError(2000);
|
|
|
|
const user = await prisma.user.findFirst({
|
|
where: {
|
|
sessions: {
|
|
some: {
|
|
id: session.sessionId,
|
|
},
|
|
},
|
|
},
|
|
select: userSelect,
|
|
});
|
|
if (!user) throw new ApiError(2001);
|
|
|
|
req.user = user;
|
|
}
|