Skip to content
This repository has been archived by the owner on Oct 8, 2023. It is now read-only.

Commit

Permalink
Fix Session types on Frontend (#256)
Browse files Browse the repository at this point in the history
  • Loading branch information
borisno2 committed Nov 10, 2022
1 parent 7ee2b64 commit 9643191
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 48 deletions.
5 changes: 5 additions & 0 deletions .changeset/lazy-mangos-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@opensaas/keystone-nextjs-auth': minor
---

Upgrade next-auth and fix types
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ jobs:
- name: Checkout Repo
uses: actions/checkout@v3

- name: Setup Node.js LTS
- name: Setup Node.js 16.x
uses: actions/setup-node@main
with:
node-version: lts/*
node-version: 16.x

- name: Install Dependencies
run: yarn
Expand Down
29 changes: 15 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[![Open in Visual Studio Code](https://open.vscode.dev/badges/open-in-vscode.svg)](https://open.vscode.dev/OpenSaasAU/keystone-nextjs-auth)
[![Release](https://github.com/OpenSaasAU/keystone-nextjs-auth/actions/workflows/release.yml/badge.svg)](https://github.com/OpenSaasAU/keystone-nextjs-auth/actions/workflows/release.yml)


# Keystone next auth

This package enables the addition of social auth to keystone-6.

## Contents
Expand All @@ -13,6 +13,7 @@ This package enables the addition of social auth to keystone-6.
- [Contributing](#contributing)

## About

This uses NextAuth.js (https://next-auth.js.org/) project to add social auth to Keystone-6 (https://keystonejs.com/). Primary testing has been done with Auth0, happy for others to test other providers/give feedback or send through a PR.

## Adding to your project
Expand All @@ -24,7 +25,6 @@ Add import...
```javascript
import { createAuth } from '@opensaas/keystone-nextjs-auth';
import Auth0 from '@opensaas/keystone-nextjs-auth/providers/auth0';

```

Add you Auth configuration including providers
Expand Down Expand Up @@ -64,7 +64,8 @@ const auth = createAuth({
]
});
```
Wrap your keystone config in `auth.withAuth`. Note that `generateNodeAPI` is required.

Wrap your keystone config in `auth.withAuth`.

```javascript
export default auth.withAuth(
Expand All @@ -73,32 +74,32 @@ export default auth.withAuth(
db: {},
ui: {},
lists,
experimental: {
generateNodeAPI: true,
},
...
});
```
## Configuration
Provider configuration see https://next-auth.js.org/configuration/providers.
For Keystone-6 Configuration see https://keystonejs.com/
for example see the example [backend](./backend)
- listKey - the list for authentication (generally `'User'`). Make sure any required fields are set using the `*Map` fields, see note below.
- identityField - The field that stores the identity/subjectId in keystone (generally `'subjectId'`). You will need to add this field to your list schema specified by `listKey`. An example can be found [here](./backend/schemas/User.ts).
- sessionData - Data to be stored in the session ( something like `'id name email'`),
- autoCreate - boolean to autocreate a user when they log in
- userMap: `key:value` pairs that define what is copied from the User object returned from NextAuth in the SignIn callback (https://next-auth.js.org/configuration/callbacks#sign-in-callback) Left side is Keystone side, right is what comes from NextAuth eg: `{ subjectId: 'id', name: 'name' }`
- accountMap - As Above but for the Account object
- profileMap - As Above but for the Profile object
- keystonePath - the path you want to access keystone from your frontend app (if required).
- listKey - the list for authentication (generally `'User'`). Make sure any required fields are set using the `*Map` fields, see note below.
- identityField - The field that stores the identity/subjectId in keystone (generally `'subjectId'`). You will need to add this field to your list schema specified by `listKey`. An example can be found [here](./backend/schemas/User.ts).
- sessionData - Data to be stored in the session ( something like `'id name email'`),
- autoCreate - boolean to autocreate a user when they log in
- userMap: `key:value` pairs that define what is copied from the User object returned from NextAuth in the SignIn callback (https://next-auth.js.org/configuration/callbacks#sign-in-callback) Left side is Keystone side, right is what comes from NextAuth eg: `{ subjectId: 'id', name: 'name' }`
- accountMap - As Above but for the Account object
- profileMap - As Above but for the Profile object
- keystonePath - the path you want to access keystone from your frontend app (if required).
Note: The Keystone `create-keystone-app` CLI app (generally run with `yarn create keystone-app`/`npm init keystone-app`) will set a required `password` field on the `User` list. If you've used this to set up your project you will need to modify your list schema to set the field as not required, or remove it entirely if you don't plan to use the default Keystone auth system at all.
## Contributing
If you want to run this package locally
After cloning run `yarn install` and either:
- `yarn dev` to run both the frontend and backend or
- `yarn dev:backend` for just the backend
Expand Down
2 changes: 1 addition & 1 deletion apps/ks-frontend-demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
"lodash": "^4.17.21",
"lodash.debounce": "^4.0.8",
"next": "^12.2.5",
"next-auth": "^4.14.0",
"next-auth": "^4.16.4",
"next-transpile-modules": "^9.1.0",
"nprogress": "^0.2.0",
"prop-types": "^15.8.1",
Expand Down
17 changes: 17 additions & 0 deletions apps/ks-frontend-demo/types/next-auth.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import NextAuth from 'next-auth';

declare module 'next-auth' {
/**
* Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context
*/
interface Session {
itemId: string;
listKey?: string;
subject?: string | number | null | undefined;
data: {
name: string;
email: string;
id: string;
};
}
}
28 changes: 15 additions & 13 deletions packages/keystone-nextjs-auth/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Keystone next auth

This package enables the addition of social auth to keystone-6.

## Contents
Expand All @@ -9,6 +10,7 @@ This package enables the addition of social auth to keystone-6.
- [Contributing](#contributing)

## About

This uses NextAuth.js (https://next-auth.js.org/) project to add social auth to Keystone-6 (https://keystonejs.com/). Primary testing has been done with Auth0, happy for others to test other providers/give feedback or send through a PR.

## Adding to your project
Expand All @@ -20,7 +22,6 @@ Add import...
```javascript
import { createAuth } from '@opensaas/keystone-nextjs-auth';
import Auth0 from '@opensaas/keystone-nextjs-auth/providers/auth0';

```

Add you Auth configuration including providers
Expand Down Expand Up @@ -60,7 +61,8 @@ const auth = createAuth({
]
});
```
Wrap your keystone config in `auth.withAuth`. Note that `generateNodeAPI` is required.

Wrap your keystone config in `auth.withAuth`.

```javascript
export default auth.withAuth(
Expand All @@ -69,32 +71,32 @@ export default auth.withAuth(
db: {},
ui: {},
lists,
experimental: {
generateNodeAPI: true,
},
...
});
```
## Configuration
Provider configuration see https://next-auth.js.org/configuration/providers.
For Keystone-6 Configuration see https://keystonejs.com/
for example see the example [backend](./backend)
- listKey - the list for authentication (generally `'User'`). Make sure any required fields are set using the `*Map` fields, see note below.
- identityField - The field that stores the identity/subjectId in keystone (generally `'subjectId'`). You will need to add this field to your list schema specified by `listKey`. An example can be found [here](./backend/schemas/User.ts).
- sessionData - Data to be stored in the session ( something like `'id name email'`),
- autoCreate - boolean to autocreate a user when they log in
- userMap: `key:value` pairs that define what is copied from the User object returned from NextAuth in the SignIn callback (https://next-auth.js.org/configuration/callbacks#sign-in-callback) Left side is Keystone side, right is what comes from NextAuth eg: `{ subjectId: 'id', name: 'name' }`
- accountMap - As Above but for the Account object
- profileMap - As Above but for the Profile object
- keystonePath - the path you want to access keystone from your frontend app (if required).
- listKey - the list for authentication (generally `'User'`). Make sure any required fields are set using the `*Map` fields, see note below.
- identityField - The field that stores the identity/subjectId in keystone (generally `'subjectId'`). You will need to add this field to your list schema specified by `listKey`. An example can be found [here](./backend/schemas/User.ts).
- sessionData - Data to be stored in the session ( something like `'id name email'`),
- autoCreate - boolean to autocreate a user when they log in
- userMap: `key:value` pairs that define what is copied from the User object returned from NextAuth in the SignIn callback (https://next-auth.js.org/configuration/callbacks#sign-in-callback) Left side is Keystone side, right is what comes from NextAuth eg: `{ subjectId: 'id', name: 'name' }`
- accountMap - As Above but for the Account object
- profileMap - As Above but for the Profile object
- keystonePath - the path you want to access keystone from your frontend app (if required).
Note: The Keystone `create-keystone-app` CLI app (generally run with `yarn create keystone-app`/`npm init keystone-app`) will set a required `password` field on the `User` list. If you've used this to set up your project you will need to modify your list schema to set the field as not required, or remove it entirely if you don't plan to use the default Keystone auth system at all.
## Contributing
If you want to run this package locally
After cloning run `yarn install` and either:
- `yarn dev` to run both the frontend and backend or
- `yarn dev:backend` for just the backend
Expand Down
2 changes: 1 addition & 1 deletion packages/keystone-nextjs-auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"cross-fetch": "^3.1.5",
"ejs": "^3.1.8",
"fast-deep-equal": "^3.1.3",
"next-auth": "^4.14.0"
"next-auth": "^4.16.4"
},
"devDependencies": {
"@keystone-6/core": "3.0.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/keystone-nextjs-auth/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import { getToken } from 'next-auth/jwt';
import { Provider } from 'next-auth/providers';

import * as cookie from 'cookie';

import { JWT, Session } from 'next-auth';
import { JWT } from 'next-auth/jwt';
import { Session } from 'next-auth';
import { nextConfigTemplate } from './templates/next-config';
// import * as Path from 'path';

Expand Down
13 changes: 8 additions & 5 deletions packages/keystone-nextjs-auth/src/pages/NextAuthPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,25 +116,28 @@ export default function NextAuthPage(props: NextAuthPageProps) {
async session({ session, token }) {
let returnSession = session;
if (!token.itemId) {
return { expires: '0' };
return session;
} else {
returnSession = {
...session,
data: token.data,
subject: token.sub,
listKey: token.listKey as string,
itemId: token.itemId as string,
listKey: token.listKey,
itemId: token.itemId,
};
}

return returnSession;
},
async jwt({ token }) {
const identity = token.sub as number | string;
const identity = token.sub;
if (!identity) {
return token;
}
const result = await validateNextAuth(identityField, identity, protectIdentities, list);

if (!result.success) {
token.itemId = null;
token.itemId = undefined;
} else {
token.itemId = result.item.id;
const data = await query[listKey].findOne({
Expand Down
19 changes: 13 additions & 6 deletions packages/keystone-nextjs-auth/src/types/next-auth.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,25 @@ import NextAuth from 'next-auth';
import { JWT } from 'next-auth/jwt';

declare module 'next-auth' {
interface Session extends JWT {
user?: any;
listKey?: string;
itemId?: string;
subject?: string | number | null | undefined;
expires?: string;
}
}

declare module 'next-auth/jwt' {
interface JWT {
data?: any | undefined;
subject?: string | undefined;
subject?: string | number | null | undefined;
listKey?: string;
itemId?: string | undefined;
itemId?: string;
name?: string | null | undefined;
email?: string | null | undefined;
picture?: string | null | undefined;
sub?: string | null | undefined;
sub?: string | number | null | undefined;
expires?: string | null | undefined;
}
interface Session extends JWT {
user?: any;
}
}
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10803,10 +10803,10 @@ [email protected]:
resolved "https://registry.yarnpkg.com/new-github-issue-url/-/new-github-issue-url-0.2.1.tgz#e17be1f665a92de465926603e44b9f8685630c1d"
integrity sha512-md4cGoxuT4T4d/HDOXbrUHkTKrp/vp+m3aOA7XXVYwNsUNMK49g3SQicTSeV5GIz/5QVGAeYRAOlyp9OvlgsYA==

next-auth@^4.14.0:
version "4.14.0"
resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.14.0.tgz#d2c6d4ebeac5e7e9ba1519fb778c65f6efe00079"
integrity sha512-pD5sin6kq/uIx3Cod2/0JFnViEnngBTTNy4CdfRaYc2QzV2zwpWAbQny2Ezlg0GjEozDhKC53JJxRRE4AmNKEw==
next-auth@^4.16.4:
version "4.16.4"
resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.16.4.tgz#3ab796a0979ac05a6ebc1fbf343983ef5bc965c9"
integrity sha512-KXW578+ER1u5RcWLwCHMdb/RIBIO6JM8r6xlf9RIPSKzkvDcX9FHiZfJS2vOq/SurHXPJZc4J3OS4IDJpF74Dw==
dependencies:
"@babel/runtime" "^7.16.3"
"@panva/hkdf" "^1.0.1"
Expand Down

0 comments on commit 9643191

Please sign in to comment.