Search code examples
next.jsjwtkeycloakprismanext-auth

next-auth error between Prisma Adapter and Keycloak (error_linkaccount, not-before-policy)


I use next-auth and I have a prisma adapter to PostgreSQL.

When I connected to keycloak(openid), it occoured errors.

prisma, postgresql, keycloak, nextauth

my all error logs below:

[next-auth][error][adapter_error_linkAccount] 
https://next-auth.js.org/errors#adapter_error_linkaccount      
Invalid `p.account.create()` invocation in

   
→ 19 linkAccount: (data) => p.account.create({
       data: {
         provider: 'keycloak',
         type: 'oauth',
         providerAccountId: '1368b98d-d517-4530-8706-b5ec54aaf18c',
         access_token: 1gRDY-
         expires_at: 1662888014,
         refresh_expires_in: 1800,
         ~~~~~~~~~~~~~~~~~~

         'not-before-policy': 0,
         session_state: '1580ca55-c649-4cba-aa37-f2c335c8217a',
         scope: 'openid profile email',
         userId: 'cl7x4jxfk0004fkgasu1cfd6n'
       }
     })

Unknown arg `not-before-policy` in data.not-before-policy for type 
    
→ 19 linkAccount: (data) => p.account.create({
       data: {
         provider: 'keycloak',
         type: 'oauth',
         providerAccountId: '1368b98d-d517-4530-8706-b5ec54aaf18c',
         access_token:
    
  name: 'LinkAccountError',  code: undefined
}

Solution

  • A workaround is to delete the not-before-policy property just before it will be added to the DB.

    // src/lib/prisma.ts
    
    // https://github.com/prisma/prisma/discussions/10037
    import { PrismaClient } from "@prisma/client"
    
    let prisma: PrismaClient
    
    if (process.env.NODE_ENV === "production") {
      prisma = new PrismaClient()
    } else {
      let globalWithPrisma = global as typeof globalThis & {
        prisma: PrismaClient
      }
      if (!globalWithPrisma.prisma) {
        globalWithPrisma.prisma = new PrismaClient(/*{ log: ['info', 'query'] }*/)
      }
      prisma = globalWithPrisma.prisma
    }
    
    prisma.$use(async (params, next) => {
      if (params.action == "create" && params.model == "Account") {
        delete params.args.data["not-before-policy"]
      }
    
      const result = await next(params)
      // See results here
      return result
    })
    
    export default prisma
    
    // src/pages/api/[...nextauth].ts
    
    import NextAuth from "next-auth"
    import KeycloakProvider from "next-auth/providers/keycloak"
    import { PrismaAdapter } from "@next-auth/prisma-adapter"
    import prisma from "src/lib/prisma"
    
    
    // For more information on each option (and a full list of options) go to
    // https://next-auth.js.org/configuration/options
    export default NextAuth({
      adapter: PrismaAdapter(prisma),
    
    // ....