36 lines
1.1 KiB
TypeScript
36 lines
1.1 KiB
TypeScript
import { IdentityContext } from '@app/server/identity';
|
|
import { prisma } from '@app/server/prisma/client';
|
|
import { Session } from '@generated/types';
|
|
import jwt from 'jsonwebtoken';
|
|
|
|
export async function RefreshTokenResolver(
|
|
_: any,
|
|
{ req, res, identity }: IdentityContext
|
|
): Promise<Session> {
|
|
const accessTokenSecret = process.env.ACCESS_TOKEN_SECRET;
|
|
const refreshTokenSecret = process.env.REFRESH_TOKEN_SECRET;
|
|
if (accessTokenSecret == null || refreshTokenSecret == null) throw new Error('No secrets found.');
|
|
|
|
const cookie: { jwt?: string | null } = req.cookies;
|
|
if (cookie == null || cookie.jwt == null) throw new Error('Unauthorized.');
|
|
|
|
const refreshToken = cookie.jwt;
|
|
|
|
const user = await prisma.user.findUniqueOrThrow({
|
|
where: { refreshToken },
|
|
select: { id: true }
|
|
});
|
|
|
|
const decoded = jwt.verify(refreshToken, accessTokenSecret) as {
|
|
userId: string;
|
|
iat: number;
|
|
exp: number;
|
|
};
|
|
|
|
if (user.id !== decoded.userId) throw new Error('Invalid token.');
|
|
const accessToken = jwt.sign({ userId: user.id }, accessTokenSecret, {
|
|
expiresIn: '30s'
|
|
});
|
|
|
|
return { accessToken };
|
|
}
|