Vizzuality/landgriffon

View on GitHub
client/src/pages/api/auth/[...nextauth].ts

Summary

Maintainability
A
0 mins
Test Coverage
import NextAuth, { getServerSession } from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';
import { GetServerSidePropsContext, NextApiRequest, NextApiResponse } from 'next';

import { authService } from 'services/authentication';
import getUserFullName from 'utils/user-full-name';
import { User } from '@/types';

import type { NextAuthOptions } from 'next-auth';

export const options: NextAuthOptions = {
  /**
   * Defining custom pages
   * By default Next-Auth provides /api/auth/signin
   */
  pages: {
    error: '/auth/signin',
    signIn: '/auth/signin',
  },

  session: {
    strategy: 'jwt',
    maxAge: 12 * 60 * 60, // 12 hours
  },
  // Configure one or more authentication providers
  providers: [
    CredentialsProvider({
      // The name to display on the sign in form (e.g. 'Sign in with...')
      name: 'Landgriffon',
      // The credentials is used to generate a suitable form on the sign in page.
      // You can specify whatever fields you are expecting to be submitted.
      // e.g. domain, username, password, 2FA token, etc.
      credentials: {
        username: { label: 'Email', type: 'email', placeholder: 'username@domain.com' },
        password: { label: 'Password', type: 'password' },
      },
      async authorize(credentials) {
        const { username, password } = credentials;

        // Request to sign in
        const signInRequest = await authService.request<{
          user: User;
          accessToken: string;
        }>({
          url: '/sign-in',
          method: 'POST',
          data: { username, password },
          headers: { 'Content-Type': 'application/json' },
        });

        const { data, status } = signInRequest;

        if (data && status === 201) {
          return {
            ...data.user,
            name: getUserFullName(data.user),
            image: data.user.avatarDataUrl,
            accessToken: data.accessToken,
          };
        }

        return null;
      },
    }),
  ],

  callbacks: {
    // Assigning encoded token from API to token created in the session
    jwt({ token, user }) {
      const newToken = { ...token };

      if (user) {
        const { accessToken, ...rest } = user;
        newToken.accessToken = accessToken;
        newToken.user = rest;

        // If it's not expired, return the token,
        // if (Date.now() / 1000 + TIME_TO_REFRESH_TOKEN < (newToken?.exp as number)) {
        //   return newToken;
        // }

        // otherwise, refresh token
        // const refreshTokenRequest = await authService.request({
        //   url: '/refresh-token',
        //   method: 'POST',
        //   data: {},
        //   headers: {
        //     'Content-Type': 'application/json',
        //     Authorization: `Bearer ${newToken.accessToken}`,
        //   },
        // });

        // newToken.accessToken = refreshTokenRequest.data.accessToken;
      }

      return newToken;
    },

    // Extending session object
    session({ session, token }) {
      session.accessToken = token.accessToken;
      session.user = token.user;
      return session;
    },
  },
};

export function auth(
  ...args:
    | [GetServerSidePropsContext['req'], GetServerSidePropsContext['res']]
    | [NextApiRequest, NextApiResponse]
    | []
) {
  return getServerSession(...args, options);
}

export default NextAuth(options);