Files
football-next/lib/mobileTokens.ts
2026-05-11 16:06:47 +03:30

65 lines
1.6 KiB
TypeScript

import crypto from "crypto";
import { db } from "@/lib/db";
export const ACCESS_TOKEN_EXPIRES_IN = 15 * 60;
export const REFRESH_TOKEN_EXPIRES_IN = 30 * 24 * 60 * 60;
function addSeconds(seconds: number) {
return new Date(Date.now() + seconds * 1000);
}
export function hashToken(token: string) {
return crypto.createHash("sha256").update(token).digest("hex");
}
export function generateToken() {
return crypto.randomBytes(48).toString("base64url");
}
export async function createMobileTokenPair(userId: string, refreshFamilyId?: string) {
const accessToken = generateToken();
const refreshToken = generateToken();
const accessTokenExpiresAt = addSeconds(ACCESS_TOKEN_EXPIRES_IN);
const refreshTokenExpiresAt = addSeconds(REFRESH_TOKEN_EXPIRES_IN);
const session = await db.session.create({
data: {
sessionToken: accessToken,
userId,
expires: accessTokenExpiresAt,
},
});
const refreshSession = await db.refreshToken.create({
data: {
tokenHash: hashToken(refreshToken),
userId,
familyId: refreshFamilyId ?? crypto.randomUUID(),
expiresAt: refreshTokenExpiresAt,
},
});
return {
accessToken,
accessTokenExpiresAt,
refreshToken,
refreshTokenExpiresAt,
refreshTokenId: refreshSession.id,
refreshFamilyId: refreshSession.familyId,
sessionId: session.id,
};
}
export async function revokeRefreshTokenFamily(userId: string, familyId: string) {
await db.refreshToken.updateMany({
where: {
userId,
familyId,
revokedAt: null,
},
data: {
revokedAt: new Date(),
},
});
}