Advertisement
Guest User

Untitled

a guest
Jun 1st, 2025
32
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
TypeScript 3.76 KB | Cybersecurity | 0 0
  1. import { loginUser } from "@/lib/auth";
  2. import NextAuth, { CredentialsSignin, User } from "next-auth"
  3. import { type JWT } from "next-auth/jwt";
  4. import Credentials from "next-auth/providers/credentials"
  5.  
  6. // Access time is shorter than backend to prompt a refresh
  7. export const BACKEND_ACCESS_TOKEN_LIFETIME = 45 * 60;              // 45 minutes
  8. export const BACKEND_REFRESH_TOKEN_LIFETIME = 6 * 24 * 60 * 60;    // 6 days
  9.  
  10. export const getCurrentEpochTime = () => {
  11.     return Math.floor(Date.now() / 1000);
  12. };
  13.  
  14. export function shouldUpdateToken(token: JWT): boolean {
  15.     return token.accessExp <= getCurrentEpochTime()
  16. }
  17.  
  18. export class InvalidLoginError extends CredentialsSignin {
  19.     constructor(message: string) {
  20.         super(message);
  21.         this.code = message;
  22.     }
  23. }
  24.  
  25. export const { handlers, signIn, signOut, auth } = NextAuth({
  26.     session: {
  27.         strategy: "jwt",
  28.         maxAge: BACKEND_REFRESH_TOKEN_LIFETIME,
  29.     },
  30.     providers: [
  31.         Credentials({
  32.             name: "credentials",
  33.             credentials: {
  34.                 username: { label: "Username", type: "text" },
  35.                 password: { label: "Password", type: "password" }
  36.             },
  37.             authorize: async (credentials) => {
  38.                 if (!credentials || !credentials.password || !credentials.username) {
  39.                     throw new Error("Missing credentials: " + credentials);
  40.                 }
  41.  
  42.                 try {
  43.                     const loginResponse = await loginUser({
  44.                         username: credentials.username as string,
  45.                         password: credentials.password as string,
  46.                     });
  47.  
  48.                     return {
  49.                         id: loginResponse.user.pk.toString(),
  50.                         username: loginResponse.user.username,
  51.                         email: loginResponse.user.email,
  52.                         firstName: loginResponse.user.first_name,
  53.                         lastName: loginResponse.user.last_name,
  54.                         accessToken: loginResponse.access,
  55.                         accessExp: getCurrentEpochTime() + BACKEND_ACCESS_TOKEN_LIFETIME,
  56.                         refreshToken: loginResponse.refresh,
  57.                         emailVerified: loginResponse.user.is_verified,
  58.                     } as User;
  59.                 } catch (error) {
  60.                     if (typeof (error) === "object") {
  61.                         throw new InvalidLoginError(JSON.stringify(error));
  62.                     }
  63.                     throw new InvalidLoginError("InvalidCredentials");
  64.                 }
  65.             },
  66.         }),
  67.     ],
  68.     callbacks: {
  69.         async jwt({ token, user, account }) {
  70.             // If `user` and `account` are set, that means it's a login event
  71.             if (user && account) {
  72.                 // we only support credentials login
  73.                 if (account?.type !== "credentials") {
  74.                     throw new Error("Invalid Login Type: " + account?.type);
  75.                 }
  76.                 return {
  77.                     ...token,
  78.                     user: user,
  79.                     accessToken: user.accessToken,
  80.                     refreshToken: user.refreshToken,
  81.                     accessExp: user.accessExp,
  82.                 }
  83.             }
  84.             return token;
  85.         },
  86.         async session({ token, session }) {
  87.             return {
  88.                 ...session,
  89.                 user: token.user,
  90.                 accessToken: token.accessToken,
  91.             }
  92.         },
  93.         authorized: async ({ auth }) => {
  94.             // Logged in users are authenticated, otherwise redirect to login page
  95.             return !!auth
  96.         },
  97.     },
  98.     pages: {
  99.         signIn: "/login",
  100.         // TODO: signOut: "/logout",
  101.     },
  102. })
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement