Skip to content

Integration with NextAuth.js

Follow this guide to set up NextAuth.js.

In your pages/api/auth/[...nextauth].js file, configure the e-Próspera provider as follows:

javascript
import NextAuth from "next-auth"
import GithubProvider from "next-auth/providers/github"

async function refreshEProsperaToken(token) {
  const response = await fetch("https://portal.eprospera.com/api/oauth/token", {
    method: "POST",
    headers: {
      "Content-Type": "application/x-www-form-urlencoded",
      Authorization:
        "Basic " +
        Buffer.from(
          `${process.env.EPROSPERA_CLIENT_ID}:${process.env.EPROSPERA_CLIENT_SECRET}`
        ).toString("base64"),
    },
    body: new URLSearchParams({
      grant_type: "refresh_token",
      refresh_token: token.refreshToken,
    }),
  })

  const refreshed = await response.json()

  if (!response.ok) throw refreshed

  return {
    ...token,
    accessToken: refreshed.access_token,
    accessTokenExpires: Date.now() + refreshed.expires_in * 1000,
    refreshToken: refreshed.refresh_token ?? token.refreshToken,
  }
}

export const authOptions = {
  // Configure one or more authentication providers
  providers: [
    {
      id: "eprospera",
      name: "eProspera",
      type: "oauth",
      wellKnown:
        "https://portal.eprospera.com/.well-known/openid-configuration",
      authorization: { params: { scope: "openid email profile offline_access" } },
      idToken: true,
      checks: ["pkce", "nonce", "state"],
      profile(profile) {
        return {
          id: profile.sub,
          name: profile.name,
          email: profile.email,
          image: profile.picture,
        };
      },
      options: {
        clientId: process.env.EPROSPERA_CLIENT_ID,
        clientSecret: process.env.EPROSPERA_CLIENT_SECRET,
      },
    },
    // ...add more providers here
  ],
  callbacks: {
    async jwt({ token, account }) {
      if (account) {
        return {
          ...token,
          accessToken: account.access_token,
          accessTokenExpires: Date.now() + account.expires_in * 1000,
          refreshToken: account.refresh_token,
        }
      }

      if (Date.now() < token.accessTokenExpires) return token

      return refreshEProsperaToken(token)
    },
  },
}

export default NextAuth(authOptions)

Request offline_access if your app needs long-lived server-side API access. Access tokens expire after 1 hour, and each refresh returns a new refresh token that should replace the old one.

To get a CLIENT_ID and a CLIENT_SECRET, reach out to gmembreno@prospera.hn.