Git Product home page Git Product logo

keystone-nextjs-auth's People

Contributors

aaronpowell avatar borisno2 avatar dcousens avatar github-actions[bot] avatar jordie23 avatar loklaan avatar renovate-bot avatar renovate[bot] avatar scottagirs avatar smarques avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

keystone-nextjs-auth's Issues

Can I get a users session information?

So I'm using this in my Keystone app and my end goal is to replace the default dashboard with a much more complete dashboard with overviews across many sources.

I need to be able to get the currently signed in user to be able to show relevant and scoped information - such as bits they can access depending on their role.

authorization in backend example

Hi, I am using your backend example, and there is something that is not clear to me... I expected it to load into session all permission assigned to the user's role.. but when I look at the session object I see only id, name, email.

I believe this is because of this line https://github.com/OpenSaasAU/keystone-nextjs-auth/blob/main/backend/keystone.ts#L25

If I change in keystone.ts :

import { permissionsList } from './schemas/permissionFields';
...
sessionData: `id name email role {${permissionsList.join(' ')}}`

then everything works!

cannot get it to work with auth0

I followed the installation instructions and generated a vanilla keystone app.

When I run yarn dev I get the following output

[next-auth][error][CLIENT_FETCH_ERROR]
https://next-auth.js.org/errors#client_fetch_error invalid json response body at http://localhost:3000/api/auth/session reason: Unexpected token < in JSON at position 0 {
  error: {
    message: 'invalid json response body at http://localhost:3000/api/auth/session reason: Unexpected token < in JSON at position 0',
    stack: 'FetchError: invalid json response body at http://localhost:3000/api/auth/session reason: Unexpected token < in JSON at position 0\n' +
      '    at /Users/user/keystone-nextjs-auth/node_modules/next/dist/compiled/node-fetch/index.js:1:49606\n' +
      '    at runMicrotasks (<anonymous>)\n' +
      '    at processTicksAndRejections (node:internal/process/task_queues:96:5)',
    name: 'FetchError'
  },
  path: 'session',
  header: {
    'x-forwarded-host': 'localhost:3000',
    'x-forwarded-proto': 'http',
    'x-forwarded-port': '3000',
    'x-forwarded-for': '::ffff:127.0.0.1',
    connection: 'close',
    host: 'localhost:3000',
    'accept-encoding': 'gzip,deflate',
    'user-agent': 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)',
    accept: '*/*'
  },
  message: 'invalid json response body at http://localhost:3000/api/auth/session reason: Unexpected token < in JSON at position 0'

This log is being printed continuously.

I also tried checking out the original source code and ran yarn dev in the backend folder (setting my auth0 creds as env vars) and I get the same problem.

E-mail login requires an adapter

It is possible to add an adapter to Keystone-next-auth? The email provider requires an adapter for the database.

[next-auth][error][EMAIL_REQUIRES_ADAPTER_ERROR] 
https://next-auth.js.org/errors#email_requires_adapter_error E-mail login requires an adapter. MissingAdapter [MissingAdapterError]: E-mail login requires an adapter.

Documentation provides the following for Prisma:

import { PrismaAdapter } from "@next-auth/prisma-adapter"
import { PrismaClient } from "@prisma/client"
export default NextAuth({
  adapter: PrismaAdapter(prisma),
  providers: [
  ...
  ],
})

Logout not working (Keystone <-> Keycloak )

Hi, I have completed a test integration with Keycloak as identity provider using your backend example. Everything works fine except for the logout function. Here's how I reproduce the problem:

  • On keystone login page click on 'Login with Keycloak'
  • You are redirected to Keycloak (correct) where you login
  • You are then redirected back to Keystone and you are logged in correctly.
  • Click on Signout
  • You are correctly signed out and taken back to the login page (correct)
  • Now if I click on 'Login with Keycloak again', I am automatically logged in with my previous user, there is no way I can login with a different account.

If I check in Keycloak I can see the user's session is still active. I think there should be a way for keystone to signal to keycloak that the user has ended their session. I know the .well-known file exposes a end_session_endpoint, I am wondering if this should be used somehow.

TIA

npm shows 4 high severity vulnerabilities

npm audit report

async <2.6.4
Severity: high
Prototype Pollution in async - GHSA-fwr7-v2mv-hh25
No fix available
node_modules/jake/node_modules/async
jake >=8.0.1
Depends on vulnerable versions of async
node_modules/jake
ejs >=3.1.2
Depends on vulnerable versions of jake
node_modules/ejs
@opensaas/keystone-nextjs-auth *
Depends on vulnerable versions of ejs
node_modules/@opensaas/keystone-nextjs-auth

4 high severity vulnerabilities

Feat Request: initFirstItem

Hey mate thanks again for putting this together ๐Ÿ‘Œ

I'm keen to have something similar to @keystone-next/auth's initFirstItem->data to populate other fields on the first User record.

Right now, using this package, that logic needs to be put in a hook. Which is actually fine right now, but the offering from Keystone raised the initial user as a priority in the design of their Authentication Config API so perhaps its a good idea to follow that here too.

Would you be up for (me) adding that here?


As an approach to add this to the Config API, I was thinking it'd be good to follow the style of initFirstItem. This would be a breaking change though:

// An example User list with an additional 'role' field.
const User = list({
  fields: {
    name: text({ isRequired: true }),
    email: text({ isRequired: true, isUnique: true }),
    subjectId: text({ isUnique: true }),
    // We may want to initialise this differently for the first User.
    role: select({ defaultValue: 'USER', options: [ { value: 'USER' }, { value: 'MODERATOR' }, { value: 'ADMIN' } ] }),
  },
});

const auth = createAuth({
  listKey: 'User',
  identityField: 'subjectId',
  sessionData: `id name email`,
  initFirstItem: {
    // 1. Moving the mappings into "initFirstItem" object makes sense, IMO! They're only ever used when creating a new User.
    // 2. Reshaping it like this *may* also be a good move, to add explicitness to the Config API.
    mapFieldsFromAuthArgs: {
      user: { subjectId: 'id', name: 'name' },
      account: {},
      profile: { email: 'email' },
    },
    data: {
      // Let's make the first user an "ADMIN" instead of the default "USER" role.
      role: 'ADMIN'
    }
  });

identityField on the provider side

Hello,
I am trying to make Google Auth work with my Keystone Project.

I got to the point where user is created on sign in, but every time I sign in an attempt is made to create the user again. It leads to an error and I don't have a session.

After some digging in the code, I found out the following is happening :

  1. In the signIn() callback in NextAuthPage, we check if the user already exist using validateNextAuth. We give it the identityField, but the identity we use to fetch the user is the value of user.id. So in the end findMatchingIdentity() makes a bad query, asking for a user whose email adress is its provider ID so it fails.
  2. After this we attempt to create a new user from user inputs, with the identityField provided by the user. This time data is well formatted so it's a duplicate : rejected.
async signIn({ user, account, profile }) {
        let identity;
        if (typeof user.id === 'string') {
          identity = user.id;
        } else if (typeof user.id === 'number') {
          identity = user.id;
        } else {
          identity = 0;
        }
        const userInput = resolver ? await resolver({ user, account, profile }) : {};

        const result = await validateNextAuth(identityField, identity, protectIdentities, list);
        // ID
        const data: any = {
          [identityField]: identity,
          ...userInput,
        };

        if (!result.success) {
          if (!autoCreate) {
            return false;
          }

          const createUser = await list
            .createOne({ data })
            .then(returned => {
              return { success: true, user: returned };
            })
            .catch(error => {
              console.error(error);
              throw new Error(error);
            });
          return createUser.success;
        }

        const updateUser = await list
          .updateOne({ where: { id: result.item.id }, data })
          .then(returned => {
            return { success: true, user: returned };
          })
          .catch(error => {
            console.error(error);
            throw new Error(error);
          });
        return updateUser.success;
      }

So I'm not sure of the actions to take on my side :

  • Do I have to add the id field from the provider user to my database ?
  • Should we add a new providerIdentityField to match with our DB identityField?
  • Is the id property of user a standard property from OAuth protocol, identical for every provider ?

In my use case using the email field from my user List as the identity field feels appropriate so I'd like to stick with it instead of storing google IDs.

Broken compatibility with new keystone next.config.js template

In @keystone-6/core 5.3.2 "./___internal-do-not-use-will-break-in-patch/admin-ui/next-config" was removed and replaced by content generated from packages/core/src/admin-ui/templates/next-config.ts.

In @opensaas/keystone-nextjs-auth/src/templates/next-config.ts is :
const keystoneConfig = require('@keystone-6/core/___internal-do-not-use-will-break-in-patch/admin-ui/next-config').config;
It takes precedence over keystone.ts config and produce following error :

- error Failed to load next.config.js, see more info here https://nextjs.org/docs/messages/next-config-error
Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './___internal-do-not-use-will-break-in-patch/admin-ui/next-config' is not defined by "exports" in /cms/node_modules/@keystone-6/core/package.json
    at new NodeError (node:internal/errors:399:5)
    at exportsNotFound (node:internal/modules/esm/resolve:361:10)
    at packageExportsResolve (node:internal/modules/esm/resolve:697:9)
    at resolveExports (node:internal/modules/cjs/loader:567:36)
    at Module._findPath (node:internal/modules/cjs/loader:636:31)
    at Module._resolveFilename (node:internal/modules/cjs/loader:1063:27)
    at /cms/node_modules/@keystone-6/core/node_modules/next/dist/server/require-hook.js:189:36
    at Module._load (node:internal/modules/cjs/loader:922:27)
    at Module.require (node:internal/modules/cjs/loader:1143:19)
    at require (node:internal/modules/cjs/helpers:110:18) {
  code: 'ERR_PACKAGE_PATH_NOT_EXPORTED'
}

Should we import the template from Keystone ?

Compatibility with Keystone Auth

First of all thank you for the effort you put in to make this package.
I was wondering what it would take to integrate this with Keystone Auth

Azure AD not logging user in

I am about 80% through getting an Azure Active Directory user to log in after working through #238 ๐Ÿ™‚

  • Navigate to http://localhost:3000
  • Redirected to http://localhost:3000/admin/api/auth/signin
  • Click on "Sign in with Azure Active Directory" button
  • Go through Microsoft account authentication process
  • New user is added to User table with all appropriate fields filled in the right place

At this point I am redirected back to http://localhost:3000/admin/api/auth/signin with the sign in button visible. I can't go anywhere without being redirected back to this page again. I can't see any errors or 404s in the browser inspector.

I am still receiving the following message in the console, though not sure if this is what is causing the issue:

[next-auth][error][CLIENT_FETCH_ERROR] 
https://next-auth.js.org/errors#client_fetch_error invalid json response body at http://localhost:3000/api/auth/session reason: Unexpected token < in JSON at position 0 {
  error: {
    message: 'invalid json response body at http://localhost:3000/api/auth/session reason: Unexpected token < in JSON at position 0',
    stack: 'FetchError: invalid json response body at http://localhost:3000/api/auth/session reason: Unexpected token < in JSON at position 0\n' +
      '    at /home/enablenz/projects/enzweb/api/node_modules/next/dist/compiled/node-fetch/index.js:1:51220\n' +
      '    at processTicksAndRejections (node:internal/process/task_queues:96:5)',
    name: 'FetchError'
  },
  url: 'http://localhost:3000/api/auth/session',
  message: 'invalid json response body at http://localhost:3000/api/auth/session reason: Unexpected token < in JSON at position 0'
}

These are my files.

keystone.ts

import * as dotenv from 'dotenv';
dotenv.config();

import { config } from '@keystone-6/core';
import { KeystoneContext } from '@keystone-6/core/types';
import { lists } from './schema';
import { withAuth, session } from './auth';

export default withAuth(
  config({
    db: {
      provider: 'mysql',
      url: process.env.DATABASE_URL,
      useMigrations: true,
      idField: { kind: 'uuid' },
      enableLogging: true,
    },
    ui: {
      isAccessAllowed: (context: KeystoneContext) => !!context.session,
    },
    lists,
    session,
  })
);

auth.ts


import { randomBytes } from 'crypto';
import { createAuth } from '@opensaas/keystone-nextjs-auth';
import AzureADProvider from "@opensaas/keystone-nextjs-auth/providers/azure-ad";
import { statelessSessions } from '@keystone-6/core/session';

let sessionSecret = process.env.SESSION_SECRET;
if (!sessionSecret && process.env.NODE_ENV !== 'production') {
  sessionSecret = randomBytes(32).toString('hex');
}

const { withAuth } = createAuth({
  listKey: 'User',
  identityField: 'subjectId',
  sessionData: `id name email`,
  sessionSecret: sessionSecret,
  autoCreate: true,
  resolver: async ({user, profile, account}) => {
    console.log(user);
    console.log(profile);
    console.log(account);
    const name = user.name as string;
    const email = user.email as string;
    return { email, name };
  },
  keystonePath: '/admin',
  providers: [
    AzureADProvider({
      clientId: process.env.AZURE_AD_CLIENT_ID,
      clientSecret: process.env.AZURE_AD_CLIENT_SECRET,
      tenantId: process.env.AZURE_AD_TENANT_ID,
    }),    
  ]
});

const sessionMaxAge = 60 * 60 * 24 * 30;

// you can find out more at https://keystonejs.com/docs/apis/session#session-api
const session = statelessSessions({
  maxAge: sessionMaxAge,
  secret: sessionSecret!,
});

export { withAuth, session };

This is how the user table is set up in schema.ts:

  User: list({
    access: allowAll,
    fields: {
      name: text({ validation: { isRequired: true } }),
      email: text({
        validation: { isRequired: true },
        isIndexed: 'unique',
      }),
      subjectId: text({ isIndexed: 'unique' }),
      createdAt: timestamp({
        defaultValue: { kind: 'now' },
      }),
    },
  }),

And finally, these are the env vars I have set:

AZURE_AD_CLIENT_ID=<secret squirrel>
AZURE_AD_CLIENT_SECRET=<secret squirrel>
AZURE_AD_TENANT_ID=<secret squirrel>
DATABASE_URL=<secret squirrel>
NEXTAUTH_URL=http://localhost:3000/admin/api/auth
NODE_ENV=development
SESSION_SECRET=<secret squirrel>

Is there anything I am missing? Thanks for your patience ๐Ÿ‘

Feature Request - Adapter Implementation

Hi Guys,

Amazing work you've done here this project of yours has really helped me,

I'm currently implementing Auth via the google identity platform, and I'm sure I could probably implement something directly with firebase but would love to keep using this module, the only thing really stopping me is adapters aren't implemented,

https://next-auth.js.org/adapters/overview
https://next-auth.js.org/adapters/firebase

Probably just need to add the property definition "adaptor" to the AuthConfig type def, although not sure how the other dependencies might work

Keystone.ts would then look something like this

const auth = createAuth({
  listKey: 'User',
  identityField: 'subjectId',
  sessionData: `id name email`,
  autoCreate: true,
  resolver: async ({user, profile, account}) => {
    const username = user.name as string;
    const email = user.email as string;
    return { email, username };
  },

  keystonePath: '/admin',
  sessionSecret,
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_ID || "Google Cloud Client ID",
      clientSecret: process.env.GOOGLE_SECRET || "Google Cloud Client Secret",
    }),
  ],
  
  adapter: FirestoreAdapter({
  apiKey: process.env.FIREBASE_API_KEY,
  appId: process.env.FIREBASE_APP_ID,
  authDomain: process.env.FIREBASE_AUTH_DOMAIN,
  databaseURL: process.env.FIREBASE_DATABASE_URL,
  projectId: process.env.FIREBASE_PROJECT_ID,
  storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
  // Optional emulator config (see below for options)
  emulator: {},

}),
});

Much love
Juan H

Invalid Json Response for /api/auth/session

Both in my own application and in the example application, im getting this error. When I run yarn keystone dev it just goes into an infinite loop of compiling and erroring out.

For all I know im doing something wrong, but I follow the documentation here and I also checked next-auth's documentation and I have googled this issue and found somewhat related issues, but I think its a pretty general error since its just the fetch api not being able to read an expected json output.

Since the unexpected character is < I assumed the response it was getting was html and when I tried to go, to the page it was trying to get to, it seemed like it was returning an html page saying that I didn't have access to this page. But adding the path to the public pages config did nothing.

Here is my main file, its basically the example project but I changed the database to sqlite because it was easier to run locally that way.

import 'dotenv/config';
import * as Path from 'path';
import { config } from '@keystone-6/core';
import { statelessSessions } from '@keystone-6/core/session';
import Auth0 from '@opensaas/keystone-nextjs-auth/providers/auth0';
import { createAuth } from '@opensaas/keystone-nextjs-auth';
import { KeystoneContext } from '@keystone-6/core/types';
import { lists } from './schemas';

let sessionSecret = process.env.SESSION_SECRET;

if (!sessionSecret) {
  if (process.env.NODE_ENV === 'production') {
    throw new Error('The SESSION_SECRET environment variable must be set in production');
  } else {
    sessionSecret = '-- DEV COOKIE SECRET; CHANGE ME --';
  }
}

const sessionMaxAge = 60 * 60 * 24 * 30; // 30 days

const auth = createAuth({
  listKey: 'User',
  identityField: 'subjectId',
  sessionData: `id name email`,
  autoCreate: true,
  resolver: async ({ user, profile }: { user: any; profile: any }) => {
    const name = user.name as string;
    const email = profile.email as string;
    return { email, name };
  },
  pages: {
    signIn: '/admin/auth/signin',
  },
  keystonePath: '/admin',
  sessionSecret,
  providers: [
    Auth0({
      clientId: process.env.AUTH0_CLIENT_ID || 'Auth0ClientID',
      clientSecret: process.env.AUTH0_CLIENT_SECRET || 'Auth0ClientSecret',
      issuer: process.env.AUTH0_ISSUER_BASE_URL || 'https://opensaas.au.auth0.com',
    }),
  ],
});

export default auth.withAuth(
  config({
    server: {
      cors: {
        origin: [process.env.FRONTEND || 'http://localhost:7777'],
        credentials: true,
      },
    },
    db: {
      provider: 'sqlite',
      url: 'file:./keystone.db',
    },
    ui: {
      isAccessAllowed: (context: KeystoneContext) => !!context.session?.data,
      publicPages: ['/admin/auth/signin', '/admin/auth/error'],
      getAdditionalFiles: [
        async () => [
          {
            mode: 'copy',
            inputPath: Path.resolve('./customPages/signin.js'),
            outputPath: 'pages/auth/signin.js',
          },
          {
            mode: 'copy',
            inputPath: Path.resolve('./customPages/error.js'),
            outputPath: 'pages/auth/error.js',
          },
        ],
      ],
    },
    lists,
    session: statelessSessions({
      maxAge: sessionMaxAge,
      secret: sessionSecret,
    }),
    experimental: {
      generateNodeAPI: true,
    },
  })
);

Here is what the whole error log looks like

โžœ yarn keystone dev
yarn run v1.22.19
$ /Users/eric/Development/web/keystonejs-auth-test/node_modules/.bin/keystone dev
โœจ Starting Keystone
โญ๏ธ Dev Server Starting on http://localhost:3000
โญ๏ธ GraphQL API Starting on http://localhost:3000/api/graphql
โœจ Generating GraphQL and Prisma schemas
โœจ The database is already in sync with the Prisma schema.
โœจ Connecting to the database
โœจ Creating server
โœ… GraphQL API ready
โœจ Generating Admin UI code
โœจ Preparing Admin UI app
event - compiled client and server successfully in 7.4s (1263 modules)
โœ… Admin UI ready
wait  - compiling /no-access (client and server)...
event - compiled client and server successfully in 492 ms (1268 modules)
[next-auth][error][CLIENT_FETCH_ERROR]
https://next-auth.js.org/errors#client_fetch_error invalid json response body at http://localhost:3000/api/auth/session reason: Unexpected token < in JSON at position 0 {
  error: {
    message: 'invalid json response body at http://localhost:3000/api/auth/session reason: Unexpected token < in JSON at position 0',
    stack: 'FetchError: invalid json response body at http://localhost:3000/api/auth/session reason: Unexpected token < in JSON at position 0\n' +
      '    at /Users/eric/Development/web/keystonejs-auth-test/node_modules/next/dist/compiled/node-fetch/index.js:1:51220\n' +
      '    at processTicksAndRejections (node:internal/process/task_queues:96:5)',
    name: 'FetchError'
  },
  url: 'http://localhost:3000/api/auth/session',
  message: 'invalid json response body at http://localhost:3000/api/auth/session reason: Unexpected token < in JSON at position 0'
}
wait  - compiling /api/__keystone_api_build (client and server)...
event - compiled successfully in 129 ms (159 modules)
wait  - compiling...
event - compiled client and server successfully in 174 ms (1290 modules)
[next-auth][error][CLIENT_FETCH_ERROR]
https://next-auth.js.org/errors#client_fetch_error invalid json response body at http://localhost:3000/api/auth/session reason: Unexpected token < in JSON at position 0 {
  error: {
    message: 'invalid json response body at http://localhost:3000/api/auth/session reason: Unexpected token < in JSON at position 0',
    stack: 'FetchError: invalid json response body at http://localhost:3000/api/auth/session reason: Unexpected token < in JSON at position 0\n' +
      '    at /Users/eric/Development/web/keystonejs-auth-test/node_modules/next/dist/compiled/node-fetch/index.js:1:51220\n' +
      '    at runMicrotasks (<anonymous>)\n' +
      '    at processTicksAndRejections (node:internal/process/task_queues:96:5)',
    name: 'FetchError'
  },
  url: 'http://localhost:3000/api/auth/session',
  message: 'invalid json response body at http://localhost:3000/api/auth/session reason: Unexpected token < in JSON at position 0'
}

inputPath of customPages must be absolute

I'm having an issue running the keystone-nextjs-auth backend locally with an error on inputPaths for custom pages.
I don't see much information on the keystone js docs for getAdditionalFiles ui property, but that seems to be the issue.

After running yarn dev:backend, i'm left with this error:

๐Ÿšจ There was an error loading your Keystone config
Error: An inputPath of "../../customPages/signin.js" was provided to copy but inputPaths must be absolute
    at writeAdminFile (/Users/salo/Code/examples/keystone-nextjs-auth/node_modules/@keystone-6/core/dist/initConfig-c6b5cfcb.cjs.dev.js:557:13)
    at /Users/salo/Code/examples/keystone-nextjs-auth/node_modules/@keystone-6/core/dist/initConfig-c6b5cfcb.cjs.dev.js:604:69
    at Array.map (<anonymous>)
    at Object.generateAdminUI (/Users/salo/Code/examples/keystone-nextjs-auth/node_modules/@keystone-6/core/dist/initConfig-c6b5cfcb.cjs.dev.js:604:57)
    at initKeystone (/Users/salo/Code/examples/keystone-nextjs-auth/node_modules/@keystone-6/core/scripts/dist/keystone-6-core-scripts.cjs.dev.js:265:11)
[next-auth][error][CLIENT_FETCH_ERROR] 
https://next-auth.js.org/errors#client_fetch_error invalid json response body at http://localhost:3000/api/auth/session reason: Unexpected token < in JSON at position 0 {
  error: {
    message: 'invalid json response body at http://localhost:3000/api/auth/session reason: Unexpected token < in JSON at position 0',
    stack: 'FetchError: invalid json response body at http://localhost:3000/api/auth/session reason: Unexpected token < in JSON at position 0\n' +
      '    at /Users/salo/Code/examples/keystone-nextjs-auth/node_modules/next/dist/compiled/node-fetch/index.js:1:49606\n' +
      '    at runMicrotasks (<anonymous>)\n' +
      '    at processTicksAndRejections (node:internal/process/task_queues:96:5)',
    name: 'FetchError'
  },
  url: 'http://localhost:3000/api/auth/session',
  message: 'invalid json response body at http://localhost:3000/api/auth/session reason: Unexpected token < in JSON at position 0'
}

it seems to complain about the relative path on inputPath in keystone.ts:

ui: {
      isAccessAllowed: (context: KeystoneContext) => !!context.session?.data,
      publicPages: ['/admin/auth/signin', '/admin/auth/error'],
      getAdditionalFiles: [
        async () => [
          {
            mode: 'copy',
            inputPath: Path.join(__dirname, './customPages/signin.js'),
            outputPath: 'pages/auth/signin.js',
          },
          {
            mode: 'copy',
            inputPath: Path.join(__dirname, './customPages/error.js'),
            outputPath: 'pages/auth/error.js',
          },
        ],
      ],
    },

I tried several changes to that path (and tried using write instead of copy with putting the src directly in keystone.ts), but still not getting it to run.
Any ideas on how to fix that?

Thanks!

Signout does not work

When clicking signout in the admin UI it does not clear the next-authjs session cookie.

Is there a sample for Credentials?

Hi, I tried to use CredentialsProvider but keep getting access denied when logging in. I then realised that /api/auth/callback/credentials is not supported (I get this error when i visit the url Error: Callback for provider type credentials not supported). Thanks

Edit: I tried with google provider and it still doesn't work. It seems to be an issue with the isAccessAllowed function internally in this package. The context.session is undefined even if i am logged in

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Other Branches

These updates are pending. To force PRs open, click the checkbox below.

  • Lock file maintenance

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

docker-compose
.devcontainer/docker-compose.yml
docker-compose.yml
dockerfile
.devcontainer/Dockerfile
  • mcr.microsoft.com/vscode/devcontainers/typescript-node 18
apps/Dockerfile
  • node 20-buster-slim
backend/Dockerfile
  • node 20
github-actions
.github/workflows/release.yml
  • changesets/action v1
.github/workflows/tests.yml
  • actions/checkout v3
npm
apps/ks-frontend-demo/package.json
  • @apollo/client ^3.7.12
  • @babel/core ^7.21.4
  • @babel/plugin-proposal-class-properties ^7.18.6
  • @babel/plugin-proposal-object-rest-spread ^7.20.7
  • @babel/plugin-syntax-dynamic-import ^7.8.3
  • @babel/plugin-transform-runtime ^7.21.4
  • @babel/preset-env ^7.21.5
  • @babel/preset-react ^7.18.6
  • @babel/preset-typescript ^7.21.4
  • @babel/runtime ^7.21.0
  • @babel/runtime-corejs3 ^7.21.0
  • @next/bundle-analyzer ^13.4.2
  • @preconstruct/next ^4.0.0
  • core-js ^3.23.5
  • date-fns ^2.30.0
  • deepmerge ^4.3.1
  • downshift ^6.1.12
  • eslint-config-next ^13.4.2
  • graphql ^16.6.0
  • graphql-tag ^2.12.6
  • graphql-upload ^12.0.0
  • lodash ^4.17.21
  • lodash.debounce ^4.0.8
  • next ^13.4.2
  • next-auth ^4.22.1
  • nprogress ^0.2.0
  • prop-types ^15.8.1
  • react ^18.2.0
  • react-bootstrap ^2.7.3
  • react-dom ^18.2.0
  • react-transition-group ^4.4.5
  • styled-components ^5.3.9
  • typescript ^5.0.4
  • waait ^1.0.5
  • @apollo/react-testing ^4.0.0
  • @next/eslint-plugin-next ^13.4.2
  • @testing-library/jest-dom ^5.16.5
  • @testing-library/react ^11.2.7
  • @testing-library/user-event ^12.8.3
  • @types/nprogress ^0.2.0
  • @types/styled-components ^5.1.26
  • babel-eslint ^10.1.0
  • babel-jest ^28.1.3
  • babel-plugin-styled-components ^1.13.3
  • casual ^1.6.2
  • eslint ^8.40.0
  • eslint-config-airbnb ^19.0.4
  • eslint-config-prettier ^6.15.0
  • eslint-config-wesbos ^3.2.3
  • eslint-plugin-html ^6.2.0
  • eslint-plugin-jsx-a11y ^6.7.1
  • eslint-plugin-prettier ^4.2.1
  • eslint-plugin-react ^7.32.2
  • eslint-plugin-react-hooks ^4.6.0
  • jest ^28.1.3
  • prettier ^2.8.7
  • react-test-renderer ^18.2.0
backend/package.json
  • @keystone-6/core ^5.2.0
  • @keystone-6/fields-document ^8.0.0
  • @keystone-ui/button ^7.0.2
  • @keystone-ui/core ^5.0.2
  • @types/ejs ^3.1.2
  • dotenv ^16.0.3
  • ejs ^3.1.9
  • react ^18.2.0
  • typescript ^5.0.4
package.json
  • @babel/core ^7.21.4
  • @babel/eslint-parser ^7.21.8
  • @babel/plugin-proposal-class-properties ^7.18.6
  • @babel/plugin-proposal-object-rest-spread ^7.20.7
  • @babel/plugin-syntax-dynamic-import ^7.8.3
  • @babel/plugin-transform-runtime ^7.21.4
  • @babel/plugin-transform-typescript ^7.21.3
  • @babel/preset-env ^7.21.5
  • @babel/preset-flow ^7.21.4
  • @babel/preset-react ^7.18.6
  • @babel/preset-typescript ^7.21.4
  • @changesets/changelog-github ^0.4.8
  • @changesets/cli ^2.26.1
  • @manypkg/cli ^0.20.0
  • @preconstruct/cli 2.6.2
  • @preconstruct/eslint-plugin-format-js-tag ^0.2.0
  • @types/node ^18.16.6
  • @types/react ^18.2.6
  • @typescript-eslint/eslint-plugin ^5.53.0
  • @typescript-eslint/parser ^5.53.0
  • babel-loader ^8.3.0
  • babel-plugin-styled-components ^1.13.3
  • chalk-cli ^5.0.1
  • concurrently ^8.0.1
  • cross-env ^7.0.3
  • eslint ^8.40.0
  • eslint-plugin-cypress ^2.12.1
  • eslint-plugin-import ^2.27.5
  • eslint-plugin-jest ^27.2.1
  • eslint-plugin-react ^7.32.2
  • eslint-plugin-react-hooks ^4.6.0
  • is-ci ^3.0.1
  • prettier ^2.8.7
  • rimraf ^3.0.2
  • terminal-link-cli ^3.0.0
  • typescript ^5.0.4
  • node ^14.15.0 || ^16.13.0 || ^18.0.0
  • yarn 1.22.19
packages/keystone-nextjs-auth/package.json
  • @babel/runtime ^7.21.0
  • @babel/runtime-corejs3 ^7.21.0
  • @types/ejs ^3.1.2
  • cookie ^0.5.0
  • cross-fetch ^3.1.5
  • ejs ^3.1.9
  • fast-deep-equal ^3.1.3
  • next-auth ^4.22.1
  • @keystone-6/core ^5.2.0
  • react ^18.2.0
  • @keystone-6/core ^5.2.0
  • react ^18.2.0

  • Check this box to trigger a request for Renovate to run again on this repository

Can we add `autoUpdate` option?

NextAuthPage.tsx

In this file line 96 I see a piece of code that is commented out. As I've understood this is planned for autoUpdate option ;)
That would be really great to have this option, I can also contribute if needed.

Can this be used for authentication for a React Native app?

Hi there and thank you for creating and maintaining this bodacious library!
We have been building out an API using KS and so far have been very happy and impressed with it. Whilst we are using the admin UI we also have a mobile app that we are building using React Native to call KS's GraphQL API. So far so good because we have everything public, but we want to start implementing authentication/authorisation via social login providers. This library appears to offer what we need but I am unsure at this stage whether we can use it to implement social authentication via our React Native app? Are you able to indicate whether this is possible or if we need to be taking a different approach?
Thank you :-)
Ollie.

Sign in does not work with any provider

I am using latest version of keystone and keystone-nextjs-auth package and when I click on sign in button the page refreshes and nothing else happens:

Here are more details
Screenshot 2023-04-24 at 5 46 03 PM

Keystone Package versions

"@graphql-tools/schema": "^9.0.17",
"@keystone-6/auth": "^7.0.0",
"@keystone-6/core": "^5.1.0",
"@keystone-6/fields-document": "^7.0.0",
"@keystone-ui/core": "^5.0.2",

This is what I get in terminal

[next-auth][error][CLIENT_FETCH_ERROR] 
https://next-auth.js.org/errors#client_fetch_error undefined {
  error: {},
  url: 'http://localhost:3000/admin/api/auth/session',
  message: undefined
}

here is my .env content

NEXTAUTH_URL=http://localhost:3000/admin/api/auth
SESSION_SECRET="H0Rvwx5gy5elNS2VhUuQfo5+5sL9WWJQ8dbIR/YsMs0="
DATABASE_URL=postgres://test:test@localhost:5432/test

Any ideas? any help is appreciated.

Errors when building front end app

Hi, I tried to build the example front end app using its docker file, but I got the following errors:

  1. linting error
    `> [6/6] RUN yarn build:
    #10 0.649 yarn run v1.22.19
    #10 0.707 $ next build
    #10 1.517 Attention: Next.js now collects completely anonymous telemetry regarding usage.
    #10 1.518 This information is used to shape Next.js' roadmap and prioritize features.
    #10 1.518 You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:
    #10 1.519 https://nextjs.org/telemetry
    #10 1.520
    #10 1.719 info - Linting and checking validity of types...
    #10 2.747
    #10 2.747 Failed to compile.
    #10 2.747
    #10 2.747 ./pages/_app.tsx
    #10 2.747 1:1 Error: Parsing error: The keyword 'import' is reserved
    #10 2.747
    #10 2.747 ./pages/_document.tsx
    #10 2.747 1:1 Error: Parsing error: The keyword 'import' is reserved
    #10 2.747
    #10 2.747 ./pages/index.tsx
    #10 2.747 2:1 Error: Parsing error: The keyword 'import' is reserved
    #10 2.747
    #10 2.747 ./components/Footer.tsx
    #10 2.747 1:1 Error: Parsing error: The keyword 'import' is reserved
    #10 2.747
    #10 2.747 ./components/Header.tsx
    #10 2.747 1:1 Error: Parsing error: The keyword 'import' is reserved
    #10 2.747
    #10 2.747 ./components/Page.tsx
    #10 2.747 1:1 Error: Parsing error: The keyword 'import' is reserved
    #10 2.747
    #10 2.747 ./lib/apolloClient.ts
    #10 2.747 1:1 Error: Parsing error: The keyword 'import' is reserved
    #10 2.747
    #10 2.747 ./lib/useForm.tsx
    #10 2.747 1:1 Error: Parsing error: The keyword 'import' is reserved
    #10 2.747
    #10 2.747 ./lib/useUser.tsx
    #10 2.747 1:1 Error: Parsing error: The keyword 'import' is reserved
    #10 2.747
    #10 2.747 info - Need to disable some ESLint rules? Learn more here: https://nextjs.org/docs/basic-features/eslint#disabling-rules
    #10 2.798 error Command failed with exit code 1.
    #10 2.798 info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

executor failed running [/bin/sh -c yarn build]: exit code: 1
ERROR: Service 'ks-frontend-demo' failed to build : Build failed`

So i edited apps/ks-frontend-demo/next.config.js to disable linting during builds, and the error went away.

  1. missing lodash types
    Type error: Could not find a declaration file for module 'lodash/isEqual'. '/usr/app/node_modules/lodash/isEqual.js' implicitly has an 'any' type.
    #10 19.99 Try npm i --save-dev @types/lodash if it exists or add a new declaration (.d.ts) file containing declare module 'lodash/isEqual';
    #10 19.99
    #10 19.99 3 | import { concatPagination } from '@apollo/client/utilities';
    #10 19.99 4 | import merge from 'deepmerge';
    #10 19.99 > 5 | import isEqual from 'lodash/isEqual';
    #10 19.99 | ^
    #10 19.99 6 | import getConfig from 'next/config';
    #10 19.99 7 |
    #10 19.99 8 | export const APOLLO_STATE_PROP_NAME = 'APOLLO_STATE';
    #10 20.08
    #10 20.08 > Build error occurred

So I added a RUN yarn add -D @types/lodash before yarn install in the docker file, and it worked.
But now..

  1.  ./pages/index.tsx:42:14
     Type error: Property 'itemId' does not exist on type 'Session'.
     
       40 |       )}
       41 |       {!user && <p>No User</p>}
     > 42 |       {data?.itemId ? (
          |              ^
       43 |         <>
       44 |           <p>Your email stored in your NextAuthjs Session as: &quot;{data?.user?.email}&quot;</p>
       45 |           <Button
     
     > Build error occurred
    

Am I doing something wrong?
Thanks in advance

Can't get Google Auth working

For some reason I just can't get the Google provider to work. I was able to debug some (as per the two PRs I sent) but I'm kinda stumped now, I think I just don't have enough knowledge of nextjs-auth or keystone to debug it properly.

Basically I can get it to pop up the google auth screen, I can choose my google account but when it lands on the callback page /api/auth/callback/google?state=.... I'm redirected to an error page /api/auth/error?error=AccessDenied.

I installed keystone-next at version 22 and couldn't get it working. I tried updating latest keystone (23.0.2 as of writing) and am getting a typescript error now when using withAuth by the way.

I used the setup where keystone generates a User list and a Post list, and installed using a normal email/password setup. I tried to add this package afterward. That setup did not have a subjectId field, so I have since added that, but hasn't seemed to help.

This is my keystone.ts file, maybe I'm doing something wrong with my config?

import { config } from '@keystone-next/keystone/schema'
import { statelessSessions } from '@keystone-next/keystone/session'
// original keystone auth
// import { createAuth } from '@keystone-next/auth'
import { lists } from './schema'
import {
  createAuth,
  nextAuthProviders as Providers,
} from '@opensaas/keystone-nextjs-auth'

let sessionSecret = process.env.SESSION_SECRET

if (!sessionSecret) {
  if (process.env.NODE_ENV === 'production') {
    throw new Error(
      'The SESSION_SECRET environment variable must be set in production'
    )
  } else {
    sessionSecret =
      '-- DEV SECRET - The bodies are buried under the binary tree --'
  }
}

let sessionMaxAge = 60 * 60 * 24 * 30 // 30 days

export const providers = [
  Providers.Google({
    clientId: process.env.GOOGLE_CLIENT_ID,
    clientSecret: process.env.GOOGLE_CLIENT_SECRET
  }),
]

const auth = createAuth({
  listKey: 'User',
  identityField: 'subjectId',
  sessionData: `id name email`,
  autoCreate: false,
  userMap: { subjectId: 'id', name: 'name' },
  accountMap: {},
  profileMap: { email: 'email' },
})

// Original keystone auth config
// const { withAuth } = createAuth({
//   listKey: 'User',
//   identityField: 'email',
//   secretField: 'password',
//   sessionData: 'name',
//   initFirstItem: {
//     fields: ['name', 'email', 'password'],
//   },
// })

const session = statelessSessions({
  maxAge: sessionMaxAge,
  secret: sessionSecret,
})

const getDbUrl = () => {
  if (
    process.env.DATABASE_URL &&
    typeof process.env.DATABASE_URL === 'string' &&
    process.env.DATABASE_URL !== 'undefined' // for some reason this can end up as a string of 'undefined'
  ) {
    return process.env.DATABASE_URL
  }

  if (
    process.env.DB_NAME &&
    process.env.DB_PASS &&
    process.env.DB_USER &&
    process.env.DB_HOST
  ) {
    return `postgres://${process.env.DB_USER}:${process.env.DB_PASS}@${process.env.DB_HOST}/${process.env.DB_NAME}`
  }

  // local dev default
  return 'postgres://postgres:[email protected]/example'
}

export default auth.withAuth(
  config({
    experimental: {
      generateNodeAPI: true,
    },
    db: {
      adapter: 'prisma_postgresql',
      url: getDbUrl(),
    },
    lists,
    session,
  })
)

Any ideas on where I should be looking to start debugging?

String cannot represent a non string value

Hi, I've just begun to use your package and added a github authentication provider but, whenever I complete the authentication flow I get this error.

http://localhost:3000/admin/api/auth/error?error=Variable%20%22%24where%22%20got%20invalid%20value%2032213671%20at%20%22where.subjectId.equals%22%3B%20String%20cannot%20represent%20a%20non%20string%20value%3A%2032213671

I'm running the latest version of this package (14.1.1) and version 26.1.0 of @keystone-next/keystone

Link to Github user API reference:
https://docs.github.com/en/rest/reference/users

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.