Skip to content

Commit

Permalink
Add user to DB on signin
Browse files Browse the repository at this point in the history
  • Loading branch information
Josh Calder committed Jun 5, 2023
1 parent e1bdfeb commit 33f4ad6
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import NextAuth from 'next-auth';
import GithubProvider from 'next-auth/providers/github';

// WARNING: this example is for demonstration purposes only
// as with each of our examples, it has not been vetted
// or tested for any particular usage
Expand All @@ -12,8 +11,28 @@ const sessionSecret = '-- DEV COOKIE SECRET; CHANGE ME --';
export const authOptions = {
secret: sessionSecret,
callbacks: {
async session({ session, token }) {
console.log('Next Auth Session Details', { session, token });
async signIn({ user, account, profile }: any) {
// We need to require the context here to avoid a circular dependency
const sudoContext = require('../../../../context').sudo();
// console.log('Next Auth Sign In Details', { user, account, profile });
// check if the user exists in keystone
const keystoneUser = await sudoContext.query.User.findOne({
where: { subjectId: profile.id },
});
// if not, create them
if (!keystoneUser) {
await sudoContext.query.User.createOne({
data: {
subjectId: profile.id,
name: profile.name,
},
});
}
// return true to allow the sign in to complete
return true;
},
async session({ session, token }: any) {
// console.log('Next Auth Session Details', { session, token });
// add the users subjectId and email to the session object
return { ...session, email: token.email, subjectId: token.sub };
},
Expand Down
10 changes: 10 additions & 0 deletions examples/custom-session-next-auth/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { getContext } from '@keystone-6/core/context';
import config from './keystone';
// note this will probably be @prisma/client in your project
import * as PrismaModule from '.myprisma/client';
import type { Context } from '.keystone/types';

export const keystoneContext: Context =
(globalThis as any).keystoneContext || getContext(config, PrismaModule);

if (process.env.NODE_ENV !== 'production') (globalThis as any).keystoneContext = keystoneContext;
10 changes: 8 additions & 2 deletions examples/custom-session-next-auth/keystone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,14 @@ const nextAuthSession = {
const [key, value] = part.trim().split('=');
cookies[key] = decodeURIComponent(value);
}

return (await getServerSession({ headers, cookies } as any, res, authOptions)) ?? undefined;
// get the next-auth session
const nextAuthSession = await getServerSession({ headers, cookies } as any, res, authOptions);
// get the keystone user using the subjectId
const keystoneAuthor = await context.db.Author.findOne({
where: { subjectId: nextAuthSession?.subjectId },
});
if (!keystoneAuthor) return;
return { ...nextAuthSession, itemId: keystoneAuthor.id };
},

// we don't need these as next-auth handle start and end for us
Expand Down
88 changes: 88 additions & 0 deletions examples/custom-session-next-auth/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ type Post {
id: ID!
title: String
content: String
author: Author
}

input PostWhereUniqueInput {
Expand All @@ -18,6 +19,7 @@ input PostWhereInput {
id: IDFilter
title: StringFilter
content: StringFilter
author: AuthorWhereInput
}

input IDFilter {
Expand Down Expand Up @@ -73,6 +75,13 @@ enum OrderDirection {
input PostUpdateInput {
title: String
content: String
author: AuthorRelateToOneForUpdateInput
}

input AuthorRelateToOneForUpdateInput {
create: AuthorCreateInput
connect: AuthorWhereUniqueInput
disconnect: Boolean
}

input PostUpdateArgs {
Expand All @@ -83,6 +92,76 @@ input PostUpdateArgs {
input PostCreateInput {
title: String
content: String
author: AuthorRelateToOneForCreateInput
}

input AuthorRelateToOneForCreateInput {
create: AuthorCreateInput
connect: AuthorWhereUniqueInput
}

type Author {
id: ID!
subjectId: String
name: String
posts(where: PostWhereInput! = {}, orderBy: [PostOrderByInput!]! = [], take: Int, skip: Int! = 0, cursor: PostWhereUniqueInput): [Post!]
postsCount(where: PostWhereInput! = {}): Int
}

input AuthorWhereUniqueInput {
id: ID
subjectId: String
}

input AuthorWhereInput {
AND: [AuthorWhereInput!]
OR: [AuthorWhereInput!]
NOT: [AuthorWhereInput!]
id: IDFilter
subjectId: StringFilter
name: StringFilter
posts: PostManyRelationFilter
}

input PostManyRelationFilter {
every: PostWhereInput
some: PostWhereInput
none: PostWhereInput
}

input AuthorOrderByInput {
id: OrderDirection
subjectId: OrderDirection
name: OrderDirection
}

input AuthorUpdateInput {
subjectId: String
name: String
posts: PostRelateToManyForUpdateInput
}

input PostRelateToManyForUpdateInput {
disconnect: [PostWhereUniqueInput!]
set: [PostWhereUniqueInput!]
create: [PostCreateInput!]
connect: [PostWhereUniqueInput!]
}

input AuthorUpdateArgs {
where: AuthorWhereUniqueInput!
data: AuthorUpdateInput!
}

input AuthorCreateInput {
subjectId: String
name: String
posts: PostRelateToManyForCreateInput
}

input PostRelateToManyForCreateInput {
create: [PostCreateInput!]
connect: [PostWhereUniqueInput!]
}

"""
Expand All @@ -97,13 +176,22 @@ type Mutation {
updatePosts(data: [PostUpdateArgs!]!): [Post]
deletePost(where: PostWhereUniqueInput!): Post
deletePosts(where: [PostWhereUniqueInput!]!): [Post]
createAuthor(data: AuthorCreateInput!): Author
createAuthors(data: [AuthorCreateInput!]!): [Author]
updateAuthor(where: AuthorWhereUniqueInput!, data: AuthorUpdateInput!): Author
updateAuthors(data: [AuthorUpdateArgs!]!): [Author]
deleteAuthor(where: AuthorWhereUniqueInput!): Author
deleteAuthors(where: [AuthorWhereUniqueInput!]!): [Author]
endSession: Boolean!
}

type Query {
posts(where: PostWhereInput! = {}, orderBy: [PostOrderByInput!]! = [], take: Int, skip: Int! = 0, cursor: PostWhereUniqueInput): [Post!]
post(where: PostWhereUniqueInput!): Post
postsCount(where: PostWhereInput! = {}): Int
authors(where: AuthorWhereInput! = {}, orderBy: [AuthorOrderByInput!]! = [], take: Int, skip: Int! = 0, cursor: AuthorWhereUniqueInput): [Author!]
author(where: AuthorWhereUniqueInput!): Author
authorsCount(where: AuthorWhereInput! = {}): Int
keystone: KeystoneMeta!
}

Expand Down
17 changes: 14 additions & 3 deletions examples/custom-session-next-auth/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,18 @@ generator client {
}

model Post {
id String @id @default(cuid())
title String @default("")
content String @default("")
id String @id @default(cuid())
title String @default("")
content String @default("")
author Author? @relation("Post_author", fields: [authorId], references: [id])
authorId String? @map("author")
@@index([authorId])
}

model Author {
id String @id @default(cuid())
subjectId String @unique @default("")
name String @default("")
posts Post[] @relation("Post_author")
}
17 changes: 16 additions & 1 deletion examples/custom-session-next-auth/schema.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { denyAll, allOperations } from '@keystone-6/core/access';
import { list } from '@keystone-6/core';
import { text } from '@keystone-6/core/fields';
import { text, relationship } from '@keystone-6/core/fields';
import type { Session } from 'next-auth';
import type { Lists } from '.keystone/types';

Expand All @@ -23,6 +24,20 @@ export const lists: Lists<Session> = {
// the document field can be used for making rich editable content
// learn more at https://keystonejs.com/docs/guides/document-fields
content: text(),
author: relationship({ ref: 'Author.posts', many: false }),
},
}),
Author: list({
access: {
operation: {
...allOperations<Lists.Author.TypeInfo<Session>>(denyAll),
query: hasSession,
},
},
fields: {
subjectId: text({ isIndexed: 'unique' }),
name: text(),
posts: relationship({ ref: 'Post.author', many: true }),
},
}),
};

0 comments on commit 33f4ad6

Please sign in to comment.