@opensaas/keystone-nextjs-auth 21.1.0 → 22.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,14 +1,9 @@
1
- import NextAuth, {
2
- CookiesOptions,
3
- EventCallbacks,
4
- PagesOptions,
5
- } from 'next-auth';
1
+ import NextAuth, { CookiesOptions, EventCallbacks, PagesOptions } from 'next-auth';
6
2
  import type { KeystoneListsAPI } from '@keystone-6/core/types';
7
3
  import { Provider } from 'next-auth/providers';
8
4
  import { JWTOptions } from 'next-auth/jwt';
9
5
  import { validateNextAuth } from '../lib/validateNextAuth';
10
6
 
11
- // TODO: See if possible to merge with `type AuthConfig`
12
7
  type CoreNextAuthPageProps = {
13
8
  autoCreate: boolean;
14
9
  cookies?: Partial<CookiesOptions>;
@@ -18,7 +13,9 @@ type CoreNextAuthPageProps = {
18
13
  listKey: string;
19
14
  pages?: Partial<PagesOptions>;
20
15
  providers?: Provider[];
21
- resolver?: Function | undefined;
16
+ resolver?: (args: { user: any; profile: any; account: any }) => {
17
+ [key: string]: boolean | string | number;
18
+ };
22
19
  sessionData: string | undefined;
23
20
  sessionSecret: string;
24
21
  };
@@ -45,8 +42,6 @@ export default function NextAuthPage(props: NextAuthPageProps) {
45
42
  sessionData,
46
43
  sessionSecret,
47
44
  } = props;
48
- // TODO: (v1.1). https://github.com/ijsto/keystone-6-oauth/projects/1#card-78602004
49
- console.log('NextAuthPages... ', pages);
50
45
 
51
46
  if (!query) {
52
47
  console.error('NextAuthPage got no query.');
@@ -79,16 +74,9 @@ export default function NextAuthPage(props: NextAuthPageProps) {
79
74
  } else {
80
75
  identity = 0;
81
76
  }
82
- const userInput = resolver
83
- ? await resolver({ user, account, profile })
84
- : {};
85
-
86
- const result = await validateNextAuth(
87
- identityField,
88
- identity,
89
- protectIdentities,
90
- queryAPI
91
- );
77
+ const userInput = resolver ? await resolver({ user, account, profile }) : {};
78
+
79
+ const result = await validateNextAuth(identityField, identity, protectIdentities, queryAPI);
92
80
  // ID
93
81
  const data: any = {
94
82
  [identityField]: identity,
@@ -97,66 +85,72 @@ export default function NextAuthPage(props: NextAuthPageProps) {
97
85
 
98
86
  if (!result.success) {
99
87
  if (!autoCreate) {
100
- console.log(
101
- '`autoCreate` if set to `false`, skipping user auto-creation'
102
- );
88
+ console.log('`autoCreate` is set to `false`, skipping user auto-creation');
103
89
  return false;
104
90
  }
105
- console.log(
106
- '`autoCreate` if set to `true`, auto-creating a new user'
107
- );
91
+ console.log('`autoCreate` is set to `true`, auto-creating a new user');
108
92
 
109
93
  const createUser = await list
110
94
  .createOne({ data })
111
- .then((returned) => {
112
- console.log('User Created', JSON.stringify(returned));
113
- return true;
95
+ .then(returned => {
96
+ return { success: true, user: returned };
114
97
  })
115
- .catch((error) => {
98
+ .catch(error => {
116
99
  console.log(error);
117
100
  throw new Error(error);
118
101
  });
119
102
  console.log('Created User', createUser);
120
- return createUser;
103
+ return createUser.success;
121
104
  }
122
- // await list.updateOne({where: {id: result.item.id}, data});
123
- return result.success;
105
+ console.log('Data', data);
106
+
107
+ const updateUser = await list
108
+ .updateOne({ where: { id: result.item.id }, data })
109
+ .then(returned => {
110
+ return { success: true, user: returned };
111
+ })
112
+ .catch(error => {
113
+ console.log(error);
114
+ throw new Error(error);
115
+ });
116
+ return updateUser.success;
124
117
  },
125
118
  async redirect({ url }) {
126
119
  return url;
127
120
  },
128
121
  async session({ session, token }) {
129
- const returnSession = {
130
- ...session,
131
- data: token.data,
132
- subject: token.sub,
133
- listKey: token.listKey,
134
- itemId: token.itemId,
135
- };
122
+ let returnSession = session;
123
+ if (!token.itemId) {
124
+ return { expires: '0' };
125
+ } else {
126
+ returnSession = {
127
+ ...session,
128
+ data: token.data,
129
+ subject: token.sub,
130
+ listKey: token.listKey as string,
131
+ itemId: token.itemId as string,
132
+ };
133
+ }
134
+ console.log('Session', returnSession);
135
+
136
136
  return returnSession;
137
137
  },
138
138
  async jwt({ token }) {
139
139
  const identity = token.sub as number | string;
140
- if (!token.itemId) {
141
- const result = await validateNextAuth(
142
- identityField,
143
- identity,
144
- protectIdentities,
145
- queryAPI
146
- );
147
-
148
- if (!result.success) {
149
- return token;
150
- }
140
+ const result = await validateNextAuth(identityField, identity, protectIdentities, queryAPI);
141
+
142
+ if (!result.success) {
143
+ token.itemId = null;
144
+ } else {
151
145
  token.itemId = result.item.id;
146
+ const data = await query[listKey].findOne({
147
+ where: { id: token.itemId },
148
+ query: sessionData || 'id',
149
+ });
150
+ token.data = data;
152
151
  }
153
- const data = await query[listKey].findOne({
154
- where: { id: token.itemId },
155
- query: sessionData || 'id',
156
- });
157
152
  const returnToken = {
158
153
  ...token,
159
- data,
160
154
  subject: token.sub,
161
155
  listKey,
162
156
  };
@@ -167,5 +161,4 @@ export default function NextAuthPage(props: NextAuthPageProps) {
167
161
  });
168
162
  }
169
163
 
170
- export const getNextAuthPage = (props: NextAuthPageProps) => () =>
171
- NextAuthPage({ ...props });
164
+ export const getNextAuthPage = (props: NextAuthPageProps) => () => NextAuthPage({ ...props });
package/src/schema.ts CHANGED
@@ -9,13 +9,11 @@ export const getSchemaExtension = ({
9
9
  identityField: string;
10
10
  listKey: string;
11
11
  }): ExtendGraphqlSchema =>
12
- graphql.extend((base) => {
12
+ graphql.extend(base => {
13
13
  const baseSchema = getBaseAuthSchema({
14
14
  listKey,
15
15
  base,
16
16
  });
17
17
 
18
- return [baseSchema.extension].filter(
19
- (x): x is Exclude<typeof x, undefined> => x !== undefined
20
- );
18
+ return [baseSchema.extension].filter((x): x is Exclude<typeof x, undefined> => x !== undefined);
21
19
  });
@@ -56,11 +56,7 @@ module.exports = withPreconstruct({
56
56
  <% } %>
57
57
  });
58
58
  `;
59
- export const nextConfigTemplate = ({
60
- keystonePath,
61
- }: {
62
- keystonePath: string;
63
- }) => {
59
+ export const nextConfigTemplate = ({ keystonePath }: { keystonePath: string }) => {
64
60
  const nextConfigOut = ejs.render(template, { keystonePath });
65
61
 
66
62
  return nextConfigOut;
@@ -1,8 +1,27 @@
1
- import { BaseListTypeInfo, KeystoneConfig } from '@keystone-6/core/types';
2
- import { CookiesOptions, PagesOptions } from 'next-auth';
1
+ import type { ServerResponse, IncomingMessage } from 'http';
2
+ import type { NextRequest } from 'next/server';
3
3
  import { Provider } from 'next-auth/providers';
4
+ import { CookiesOptions, PagesOptions } from 'next-auth';
5
+ import { BaseListTypeInfo, KeystoneConfig, CreateContext } from '@keystone-6/core/types';
4
6
 
5
- export type NextAuthSession = { listKey: string; itemId: string; data: any };
7
+ type NextAuthResponse = IncomingMessage & NextRequest;
8
+
9
+ export declare type AuthSessionStrategy<StoredSessionData> = {
10
+ start: (args: {
11
+ res: ServerResponse;
12
+ data: any;
13
+ createContext: CreateContext;
14
+ }) => Promise<string>;
15
+ end: (args: {
16
+ req: IncomingMessage;
17
+ res: ServerResponse;
18
+ createContext: CreateContext;
19
+ }) => Promise<void>;
20
+ get: (args: {
21
+ req: NextAuthResponse;
22
+ createContext: CreateContext;
23
+ }) => Promise<StoredSessionData | undefined>;
24
+ };
6
25
 
7
26
  export type NextAuthProviders = Provider[];
8
27
 
@@ -15,9 +34,7 @@ type NextAuthOptions = {
15
34
  resolver: any;
16
35
  };
17
36
 
18
- export type KeystoneOAuthConfig = KeystoneConfig &
19
- KeytoneOAuthOptions &
20
- NextAuthOptions;
37
+ export type KeystoneOAuthConfig = KeystoneConfig & KeytoneOAuthOptions & NextAuthOptions;
21
38
 
22
39
  export type AuthConfig<GeneratedListTypes extends BaseListTypeInfo> = {
23
40
  /** Auth Create users in Keystone DB from Auth Provider */
@@ -31,20 +48,20 @@ export type AuthConfig<GeneratedListTypes extends BaseListTypeInfo> = {
31
48
  /** Path for Keystone interface */
32
49
  keystonePath?: string;
33
50
  // Custom pages for different NextAuth events
34
- pages?: any; // TODO: Fix types
51
+ pages?: Partial<PagesOptions>;
35
52
  /** Providers for Next Auth */
36
53
  providers: NextAuthProviders;
37
54
  /** Resolver for user to define their profile */
38
- resolver?: Function | undefined;
55
+ resolver?: (args: { user: any; profile: any; account: any }) => Promise<{
56
+ [key: string]: boolean | string | number;
57
+ }>;
39
58
  /** Session data population */
40
59
  sessionData?: string | undefined;
41
60
  /** Next-Auth Session Secret */
42
61
  sessionSecret: string;
43
62
  };
44
63
 
45
- export type AuthTokenRequestErrorCode =
46
- | 'IDENTITY_NOT_FOUND'
47
- | 'MULTIPLE_IDENTITY_MATCHES';
64
+ export type AuthTokenRequestErrorCode = 'IDENTITY_NOT_FOUND' | 'MULTIPLE_IDENTITY_MATCHES';
48
65
 
49
66
  export type PasswordAuthErrorCode =
50
67
  | AuthTokenRequestErrorCode
@@ -0,0 +1,19 @@
1
+ import NextAuth from 'next-auth';
2
+ import { JWT } from 'next-auth/jwt';
3
+
4
+ declare module 'next-auth' {
5
+ interface JWT {
6
+ data?: any | undefined;
7
+ subject?: string | undefined;
8
+ listKey?: string;
9
+ itemId?: string | undefined;
10
+ name?: string | null | undefined;
11
+ email?: string | null | undefined;
12
+ picture?: string | null | undefined;
13
+ sub?: string | null | undefined;
14
+ expires?: string | null | undefined;
15
+ }
16
+ interface Session extends JWT {
17
+ user?: any;
18
+ }
19
+ }