fauth-template
Version:
Generate auth templates for your projects
103 lines (88 loc) • 2.3 kB
text/typescript
import { jwtConfig } from "@/configs/envs";
import { jwtVerify, SignJWT } from "jose";
import { TextEncoder } from "util";
export type Payload = {
username: string;
id: string;
};
const config = {
accessTokenSecret: jwtConfig.accessSecret,
refreshTokenSecret: jwtConfig.jwtSecret,
accessTokenExpiry: "15m",
refreshTokenExpiry: "7d",
};
export interface TokenPair {
accessToken: string;
refreshToken: string;
expiresIn: number;
}
export interface User {
userId: string;
email: string;
}
export async function generateTokens(user: Payload): Promise<TokenPair> {
const accessToken = await encryptJWT(
user,
config.accessTokenSecret,
config.accessTokenExpiry
);
const refreshToken = await encryptJWT(
user,
config.refreshTokenSecret,
config.refreshTokenExpiry
);
return {
accessToken,
refreshToken,
expiresIn: 15 * 60,
};
}
export function encryptJWT(
payload: Payload,
secret: string,
expiresIn: string
) {
const encodedKey = new TextEncoder().encode(secret);
return new SignJWT(payload)
.setExpirationTime(expiresIn)
.setProtectedHeader({
alg: "HS256",
})
.setIssuedAt(Date.now())
.sign(encodedKey);
}
export async function verifyJWT(jwt: string, secret: string) {
const encodedKey = new TextEncoder().encode(secret);
const { payload } = await jwtVerify(jwt, encodedKey, {
algorithms: ["HS256"],
});
return payload as Payload;
}
export async function verifyAccessToken(token: string) {
try {
const decoded = await verifyJWT(token, config.accessTokenSecret);
return decoded;
} catch (error) {
return null;
}
}
// Check if refresh token is valid
export async function verifyRefreshToken(token: string) {
try {
const decoded = await verifyJWT(token, config.refreshTokenSecret);
return decoded;
} catch (error) {
return null;
}
}
// Create new access token using refresh token
export async function refreshAccessToken(refreshToken: string) {
const user = await verifyRefreshToken(refreshToken);
if (!user) {
return null;
}
return (await generateTokens({
username: user.username,
id: user.id,
})) as TokenPair;
}