diff --git a/apps/infoalloggi/src/forms/FormLogin.tsx b/apps/infoalloggi/src/forms/FormLogin.tsx index a64f8de..ed66dad 100644 --- a/apps/infoalloggi/src/forms/FormLogin.tsx +++ b/apps/infoalloggi/src/forms/FormLogin.tsx @@ -53,8 +53,8 @@ export const FormLogin = () => { await utils.auth.getSession.invalidate(); setAlreadyRequested(true); toast.success(t.auth.login.success); - //await router.push(redirect ? (redirect as string) : "/"); - window.location.replace(redirect ? (redirect as string) : "/"); + await router.push(redirect ? (redirect as string) : "/"); + //window.location.replace(redirect ? (redirect as string) : "/"); }, }); const [altreadyRequested, setAlreadyRequested] = useState(false); diff --git a/apps/infoalloggi/src/middlewares/auth_middleware.ts b/apps/infoalloggi/src/middlewares/auth_middleware.ts index 2384746..d3f6903 100644 --- a/apps/infoalloggi/src/middlewares/auth_middleware.ts +++ b/apps/infoalloggi/src/middlewares/auth_middleware.ts @@ -1,20 +1,19 @@ import { add } from "date-fns"; import { type NextRequest, NextResponse } from "next/server"; -import { env } from "~/env.mjs"; +import { TOKEN_CONFIG } from "~/server/auth/configs"; -import { - ACCESS_TOKEN_COOKIE_NAME, - REFRESH_TOKEN_COOKIE_NAME, - signToken, - verifyToken, -} from "~/server/auth/jwt"; +import { signToken, verifyToken } from "~/server/auth/jwt"; export const authMiddleware = async (req: NextRequest) => { const path = req.nextUrl.pathname; - const refreshToken = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)?.value; + const refreshToken = req.cookies.get( + TOKEN_CONFIG.REFRESH_TOKEN_COOKIE_NAME, + )?.value; - const accessToken = req.cookies.get(ACCESS_TOKEN_COOKIE_NAME)?.value; + const accessToken = req.cookies.get( + TOKEN_CONFIG.ACCESS_TOKEN_COOKIE_NAME, + )?.value; const isProtectedRoute = (path.startsWith("/area-riservata") || path.startsWith("/servizio")) && @@ -27,8 +26,8 @@ export const authMiddleware = async (req: NextRequest) => { const destination = new URL("/login", req.nextUrl); destination.searchParams.set("redirect", path); const response = NextResponse.redirect(destination); - response.cookies.delete(ACCESS_TOKEN_COOKIE_NAME); - response.cookies.delete(REFRESH_TOKEN_COOKIE_NAME); + response.cookies.delete(TOKEN_CONFIG.ACCESS_TOKEN_COOKIE_NAME); + response.cookies.delete(TOKEN_CONFIG.REFRESH_TOKEN_COOKIE_NAME); return response; } // if refresh token is present, handle refresh token logic @@ -42,7 +41,7 @@ export const authMiddleware = async (req: NextRequest) => { const destination = new URL("/login", req.nextUrl); destination.searchParams.set("redirect", path); const response = NextResponse.redirect(destination); - response.cookies.delete(ACCESS_TOKEN_COOKIE_NAME); + response.cookies.delete(TOKEN_CONFIG.ACCESS_TOKEN_COOKIE_NAME); return response; } @@ -61,8 +60,8 @@ export const authMiddleware = async (req: NextRequest) => { return await refreshAuthToken(req, refreshToken, true); } const response = NextResponse.next(); - response.cookies.delete(ACCESS_TOKEN_COOKIE_NAME); - response.cookies.delete(REFRESH_TOKEN_COOKIE_NAME); + response.cookies.delete(TOKEN_CONFIG.ACCESS_TOKEN_COOKIE_NAME); + response.cookies.delete(TOKEN_CONFIG.REFRESH_TOKEN_COOKIE_NAME); return response; } @@ -88,7 +87,7 @@ export const authMiddleware = async (req: NextRequest) => { const destination = new URL("/login", req.nextUrl); destination.searchParams.set("redirect", path); const response = NextResponse.redirect(destination); - response.cookies.delete(ACCESS_TOKEN_COOKIE_NAME); + response.cookies.delete(TOKEN_CONFIG.ACCESS_TOKEN_COOKIE_NAME); return response; } if (path.startsWith("/auth/new-password-reset")) { @@ -121,7 +120,7 @@ const refreshAuthToken = async ( const destination = new URL("/login", req.nextUrl); destination.searchParams.set("redirect", req.nextUrl.pathname); const response = NextResponse.redirect(destination); - response.cookies.delete(REFRESH_TOKEN_COOKIE_NAME); + response.cookies.delete(TOKEN_CONFIG.REFRESH_TOKEN_COOKIE_NAME); return response; } // If refresh token is valid, sign a new access token @@ -133,14 +132,14 @@ const refreshAuthToken = async ( const newAccessToken = await signToken( refreshTokenPayload, - "5m", + TOKEN_CONFIG.ACCESS_TOKEN_EXPIRY, "accessToken", ); - response.cookies.set(ACCESS_TOKEN_COOKIE_NAME, newAccessToken, { - expires: add(new Date(), { minutes: 1 }), - httpOnly: true, - path: "/", - sameSite: "lax", + response.cookies.set(TOKEN_CONFIG.ACCESS_TOKEN_COOKIE_NAME, newAccessToken, { + expires: add(new Date(), { + minutes: TOKEN_CONFIG.ACCESS_TOKEN_COOKIE_EXPIRY, + }), + ...TOKEN_CONFIG.COOKIE_OPTIONS, //secure: env.NODE_ENV === "production", }); return response; diff --git a/apps/infoalloggi/src/server/auth/configs.ts b/apps/infoalloggi/src/server/auth/configs.ts new file mode 100644 index 0000000..a2173e3 --- /dev/null +++ b/apps/infoalloggi/src/server/auth/configs.ts @@ -0,0 +1,13 @@ +export const TOKEN_CONFIG = { + ACCESS_TOKEN_COOKIE_NAME: "access_token", + REFRESH_TOKEN_COOKIE_NAME: "refresh_token", + ACCESS_TOKEN_EXPIRY: "5m", + REFRESH_TOKEN_EXPIRY: "7d", + ACCESS_TOKEN_COOKIE_EXPIRY: 5, + REFRESH_TOKEN_COOKIE_EXPIRY: 7, + COOKIE_OPTIONS: { + httpOnly: true, + path: "/", + sameSite: "lax", + }, +} as const; diff --git a/apps/infoalloggi/src/server/auth/jwt.ts b/apps/infoalloggi/src/server/auth/jwt.ts index 4175600..52425e5 100644 --- a/apps/infoalloggi/src/server/auth/jwt.ts +++ b/apps/infoalloggi/src/server/auth/jwt.ts @@ -3,9 +3,6 @@ import { jwtVerify, SignJWT } from "jose"; import { env } from "~/env.mjs"; import { type Session, sessionSchema } from "~/server/api/trpc"; -export const ACCESS_TOKEN_COOKIE_NAME = "access_token"; -export const REFRESH_TOKEN_COOKIE_NAME = "refresh_token"; - const secret = new TextEncoder().encode(env.JWT_SECRET); export async function signToken( diff --git a/apps/infoalloggi/src/server/controllers/auth.controller.ts b/apps/infoalloggi/src/server/controllers/auth.controller.ts index 527d4b8..a5fe2ca 100644 --- a/apps/infoalloggi/src/server/controllers/auth.controller.ts +++ b/apps/infoalloggi/src/server/controllers/auth.controller.ts @@ -1,13 +1,9 @@ import { TRPCError } from "@trpc/server"; -import { deleteCookie, type OptionsType, setCookie } from "cookies-next"; +import { deleteCookie, setCookie } from "cookies-next"; import { add } from "date-fns"; import type { UsersId } from "~/schemas/public/Users"; import type { Context } from "~/server/api/trpc"; -import { - ACCESS_TOKEN_COOKIE_NAME, - REFRESH_TOKEN_COOKIE_NAME, - signToken, -} from "~/server/auth/jwt"; +import { signToken } from "~/server/auth/jwt"; import { db } from "~/server/db"; import { isBanned } from "~/server/services/banlist.service"; import { @@ -22,27 +18,7 @@ import { findUser_byId_MINI, } from "~/server/services/user.service"; import { checkCtx } from "~/server/utils/ctxChecker"; - -// [...] Cookie options -const cookieOptions: OptionsType = { - httpOnly: true, - path: "/", - sameSite: "lax", - //secure: env.NODE_ENV === "production", -}; - -const accessTokenExpiry = "1m"; -export const refreshTokenExpiry = "5m"; - -const accessTokenCookieOptions: OptionsType = { - ...cookieOptions, - expires: add(new Date(), { minutes: 1 }), -}; - -const refreshTokenCookieOptions: OptionsType = { - ...cookieOptions, - expires: add(new Date(), { minutes: 5 }), -}; +import { TOKEN_CONFIG } from "../auth/configs"; export const createUserAdmin = async ({ email, @@ -153,24 +129,30 @@ export const logIn = async ({ const accessToken = await signToken( payload, - accessTokenExpiry, + TOKEN_CONFIG.ACCESS_TOKEN_EXPIRY, "accessToken", ); const refreshToken = await signToken( payload, - refreshTokenExpiry, + TOKEN_CONFIG.REFRESH_TOKEN_EXPIRY, "refreshToken", ); console.log("Generated tokens for user:", user.email); try { - await setCookie(ACCESS_TOKEN_COOKIE_NAME, accessToken, { - ...accessTokenCookieOptions, + await setCookie(TOKEN_CONFIG.ACCESS_TOKEN_COOKIE_NAME, accessToken, { + ...TOKEN_CONFIG.COOKIE_OPTIONS, + expires: add(new Date(), { + minutes: TOKEN_CONFIG.ACCESS_TOKEN_COOKIE_EXPIRY, + }), req, res, }); - await setCookie(REFRESH_TOKEN_COOKIE_NAME, refreshToken, { - ...refreshTokenCookieOptions, + await setCookie(TOKEN_CONFIG.REFRESH_TOKEN_COOKIE_NAME, refreshToken, { + ...TOKEN_CONFIG.COOKIE_OPTIONS, + expires: add(new Date(), { + minutes: TOKEN_CONFIG.REFRESH_TOKEN_COOKIE_EXPIRY, + }), req, res, }); @@ -209,21 +191,31 @@ export const swapAuth = async ({ }); } - const accessToken = await signToken(user, accessTokenExpiry, "accessToken"); + const accessToken = await signToken( + user, + TOKEN_CONFIG.ACCESS_TOKEN_EXPIRY, + "accessToken", + ); const refreshToken = await signToken( user, - refreshTokenExpiry, + TOKEN_CONFIG.REFRESH_TOKEN_EXPIRY, "refreshToken", ); // Send Access Token in Cookie - await setCookie(ACCESS_TOKEN_COOKIE_NAME, accessToken, { - ...accessTokenCookieOptions, + await setCookie(TOKEN_CONFIG.ACCESS_TOKEN_COOKIE_NAME, accessToken, { + ...TOKEN_CONFIG.COOKIE_OPTIONS, + expires: add(new Date(), { + minutes: TOKEN_CONFIG.ACCESS_TOKEN_COOKIE_EXPIRY, + }), req, res, }); - await setCookie(REFRESH_TOKEN_COOKIE_NAME, refreshToken, { - ...refreshTokenCookieOptions, + await setCookie(TOKEN_CONFIG.REFRESH_TOKEN_COOKIE_NAME, refreshToken, { + ...TOKEN_CONFIG.COOKIE_OPTIONS, + expires: add(new Date(), { + minutes: TOKEN_CONFIG.REFRESH_TOKEN_COOKIE_EXPIRY, + }), req, res, }); @@ -238,8 +230,8 @@ export const swapAuth = async ({ export const logOut = async ({ ctx: { req, res } }: { ctx: Context }) => { checkCtx({ req, res }); try { - await deleteCookie(ACCESS_TOKEN_COOKIE_NAME, { req, res }); - await deleteCookie(REFRESH_TOKEN_COOKIE_NAME, { req, res }); + await deleteCookie(TOKEN_CONFIG.ACCESS_TOKEN_COOKIE_NAME, { req, res }); + await deleteCookie(TOKEN_CONFIG.REFRESH_TOKEN_COOKIE_NAME, { req, res }); return { status: "success" }; } catch (err: unknown) { console.error(err);