Skip to content

Commit 685b03a

Browse files
author
Josh Calder
committed
Move around function
1 parent b1fb06b commit 685b03a

File tree

5 files changed

+73
-67
lines changed

5 files changed

+73
-67
lines changed

examples/custom-session-next-auth/admin/pages/api/auth/[...nextauth].ts

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import NextAuth from 'next-auth';
22
import GithubProvider from 'next-auth/providers/github';
3+
import { getNextSession, onNextSignIn } from '../../../../session';
34
// WARNING: this example is for demonstration purposes only
45
// as with each of our examples, it has not been vetted
56
// or tested for any particular usage
@@ -11,31 +12,8 @@ const sessionSecret = '-- DEV COOKIE SECRET; CHANGE ME --';
1112
export const authOptions = {
1213
secret: sessionSecret,
1314
callbacks: {
14-
async signIn({ user, account, profile }: any) {
15-
// We need to require the context here to avoid a circular dependency
16-
const sudoContext = require('../../../../context').sudo();
17-
// console.log('Next Auth Sign In Details', { user, account, profile });
18-
// check if the user exists in keystone
19-
const keystoneUser = await sudoContext.query.User.findOne({
20-
where: { subjectId: profile.id },
21-
});
22-
// if not, create them
23-
if (!keystoneUser) {
24-
await sudoContext.query.User.createOne({
25-
data: {
26-
subjectId: profile.id,
27-
name: profile.name,
28-
},
29-
});
30-
}
31-
// return true to allow the sign in to complete
32-
return true;
33-
},
34-
async session({ session, token }: any) {
35-
// console.log('Next Auth Session Details', { session, token });
36-
// add the users subjectId and email to the session object
37-
return { ...session, email: token.email, subjectId: token.sub };
38-
},
15+
signIn: onNextSignIn,
16+
session: getNextSession,
3917
},
4018
providers: [
4119
GithubProvider({

examples/custom-session-next-auth/context.ts

Lines changed: 0 additions & 10 deletions
This file was deleted.

examples/custom-session-next-auth/keystone.ts

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,14 @@
11
import { config } from '@keystone-6/core';
2-
import { getServerSession } from 'next-auth/next';
3-
import type { Session } from 'next-auth';
42
import { fixPrismaPath } from '../example-utils';
53
import { lists } from './schema';
6-
import { authOptions } from './admin/pages/api/auth/[...nextauth]';
7-
import type { Context, TypeInfo } from '.keystone/types';
4+
5+
import { Session, nextAuthSession } from './session';
6+
import type { TypeInfo } from '.keystone/types';
87

98
// WARNING: this example is for demonstration purposes only
109
// as with each of our examples, it has not been vetted
1110
// or tested for any particular usage
1211

13-
const nextAuthSession = {
14-
async get({ context }: { context: Context }): Promise<Session | undefined> {
15-
const { req, res } = context;
16-
const { headers } = req ?? {};
17-
if (!headers?.cookie || !res) return;
18-
19-
// next-auth needs a different cookies structure
20-
const cookies: Record<string, string> = {};
21-
for (const part of headers.cookie.split(';')) {
22-
const [key, value] = part.trim().split('=');
23-
cookies[key] = decodeURIComponent(value);
24-
}
25-
// get the next-auth session
26-
const nextAuthSession = await getServerSession({ headers, cookies } as any, res, authOptions);
27-
// get the keystone user using the subjectId
28-
const keystoneAuthor = await context.db.Author.findOne({
29-
where: { subjectId: nextAuthSession?.subjectId },
30-
});
31-
if (!keystoneAuthor) return;
32-
return { ...nextAuthSession, itemId: keystoneAuthor.id };
33-
},
34-
35-
// we don't need these as next-auth handle start and end for us
36-
async start() {},
37-
async end() {},
38-
};
39-
4012
export default config<TypeInfo<Session>>({
4113
db: {
4214
provider: 'sqlite',

examples/custom-session-next-auth/schema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { denyAll, allOperations } from '@keystone-6/core/access';
22
import { list } from '@keystone-6/core';
33
import { text, relationship } from '@keystone-6/core/fields';
4-
import type { Session } from 'next-auth';
4+
import type { Session } from './session';
55
import type { Lists } from '.keystone/types';
66

77
// WARNING: this example is for demonstration purposes only
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { getContext } from '@keystone-6/core/context';
2+
import { getServerSession } from 'next-auth/next';
3+
import { authOptions } from './admin/pages/api/auth/[...nextauth]';
4+
import config from './keystone';
5+
import * as PrismaModule from '.myprisma/client';
6+
import type { Context } from '.keystone/types';
7+
8+
export type Session = {
9+
id: string;
10+
};
11+
const sudoContext: Context =
12+
(globalThis as any).keystoneContext || getContext(config, PrismaModule).sudo();
13+
14+
if (process.env.NODE_ENV !== 'production') (globalThis as any).sudoContext = sudoContext;
15+
16+
export async function onNextSignIn({ user, account, profile }: any) {
17+
// console.log('Next Auth Sign In Details', { user, account, profile });
18+
// check if the user exists in keystone
19+
const keystoneUser = await sudoContext.query.Author.findOne({
20+
where: { subjectId: profile.id },
21+
});
22+
// if not, create them
23+
if (!keystoneUser) {
24+
await sudoContext.query.Author.createOne({
25+
data: {
26+
subjectId: profile.id,
27+
name: profile.name,
28+
},
29+
});
30+
}
31+
// return true to allow the sign in to complete
32+
return true;
33+
}
34+
35+
export async function getNextSession({ session, token }: any) {
36+
// console.log('Next Auth Session Details', { session, token });
37+
// add the users subjectId and email to the session object
38+
return { ...session, email: token.email, subjectId: token.sub };
39+
}
40+
41+
export const nextAuthSession = {
42+
async get({ context }: { context: Context }): Promise<Session | undefined> {
43+
const { req, res } = context;
44+
const { headers } = req ?? {};
45+
if (!headers?.cookie || !res) return;
46+
47+
// next-auth needs a different cookies structure
48+
const cookies: Record<string, string> = {};
49+
for (const part of headers.cookie.split(';')) {
50+
const [key, value] = part.trim().split('=');
51+
cookies[key] = decodeURIComponent(value);
52+
}
53+
// get the next-auth session
54+
const nextAuthSession = await getServerSession({ headers, cookies } as any, res, authOptions);
55+
// get the keystone user using the subjectId
56+
const keystoneAuthor = await context.db.Author.findOne({
57+
where: { subjectId: nextAuthSession?.subjectId },
58+
});
59+
if (!keystoneAuthor) return;
60+
return { id: keystoneAuthor.id };
61+
},
62+
63+
// we don't need these as next-auth handle start and end for us
64+
async start() {},
65+
async end() {},
66+
};

0 commit comments

Comments
 (0)