[…nextauth].js

Home   »   […nextauth].js

import Providers from 'next-auth/providers'
import NextAuth from 'next-auth'
const api = new RestClient()
import { RestClient } from 'lib/api'
import { differenceInDays } from 'date-fns'

const checkExpiredTime = (expired_time) => {
  const dt = new Date(expired_time)
  const now = new Date()
  if (differenceInDays(dt, now) <= 10) {
    return true
  } else {
    return false
  }
}

/**
 * Takes a token, and returns a new token with updated
 * `accessToken` and `accessTokenExpires`. If an error occurs,
 * returns the old token and an error property
 */
async function refreshAccessToken(token) {
  try {
    const res = await api.getRefreshAccessToken(token.refresh_token, token.access_token)

    if (res.kind === 'ok') {
      const isFindUser = await api.getUserInformation(res.auth.access_token)
      if (isFindUser.kind === 'ok') {
        // Any user object returned here will be saved in the JSON Web Token
        return { user: isFindUser.user, ...res.auth }
      } else {
        return {
          ...token,
          error: 'RefreshAccessTokenError',
        }
      }
    } else {
      return {
        ...token,
        error: 'RefreshAccessTokenError',
      }
    }
  } catch (error) {
    // console.log(error)
    return {
      ...token,
      error: 'RefreshAccessTokenError',
    }
  }
}

const options = {
  // Configure one or more authentication providers
  providers: [
    Providers.Credentials({
      // The name to display on the sign in form (e.g. 'Sign in with...')
      name: 'Credentials',
      // 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.

      authorize: async (credentials) => {
        // console.log('credentials', credentials)
        const user = await api.getLogin(credentials)
        // You need to provide your own logic here that takes the credentials
        // submitted and returns either a object representing a user or value
        // that is false/null if the credentials are invalid.
        // e.g. return { id: 1, name: 'J Smith', email: '[email protected]' }
        // console.log('obj user', user)
        if (user.kind === 'ok') {
          // Any user object returned here will be saved in the JSON Web Token
          return { user: user.user, token: user.token }
        } else {
          throw new Error(user.kind)
        }
      },
    }),
  ],
  callbacks: {
    // Getting the JWT token from API response
    async jwt(token, user, account, profile, isNewUser) {
      // console.log('token', token, 'user', user, 'account', account)
      if (user) {
        token = {
          // accessTokenExpires: Date.now() + account.expires_in * 1000,
          ...user.token,
          user: user.user,
        }
      }
      // Return previous token if the access token has not expired yet
      if (!checkExpiredTime(token.expiration_time)) {
        return token
      }
      // Access token has expired, try to update it
      return refreshAccessToken(token)
    },
    async session(session, token) {
      // console.log('token', token)
      const user = token.user
      session = {
        ...token,
        user,
      }
      return session
    },
  },
  pages: {
    signIn: '/login',
    error: '/login',
  },
}

export default (req, res) => NextAuth(req, res, options)

Leave a Reply

Your email address will not be published. Required fields are marked *