@opensaas/keystone-nextjs-auth 20.5.0 → 21.1.1

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,5 +1,5 @@
1
1
  import ejs from 'ejs';
2
- import { AuthGqlNames } from '../types';
2
+ import { NextAuthPageProps } from '../pages/NextAuthPage';
3
3
 
4
4
  const template = `
5
5
  import getNextAuthPage from '@opensaas/keystone-nextjs-auth/pages/NextAuthPage';
@@ -7,49 +7,32 @@ import { query } from '.keystone/api';
7
7
  import keystoneConfig from '../../../../../keystone';
8
8
 
9
9
  export default getNextAuthPage({
10
+ autoCreate: <%= autoCreate %>,
10
11
  identityField: '<%= identityField %>',
11
- sessionData: '<%= sessionData %>',
12
12
  listKey: '<%= listKey %>',
13
- userMap: <%- JSON.stringify(userMap) %>,
14
- accountMap: <%- JSON.stringify(accountMap) %>,
15
- profileMap: <%- JSON.stringify(profileMap) %>,
16
- autoCreate: <%= autoCreate %>,
17
- sessionSecret: '<%= sessionSecret %>',
13
+ pages: keystoneConfig.pages,
18
14
  providers: keystoneConfig.providers,
19
15
  query,
16
+ resolver: keystoneConfig.resolver,
17
+ sessionData: '<%= sessionData %>',
18
+ sessionSecret: '<%= sessionSecret %>',
20
19
  });
21
20
  `;
22
21
 
22
+ type AuthTemplateOptions = NextAuthPageProps;
23
+
23
24
  export const authTemplate = ({
24
- gqlNames,
25
+ autoCreate,
25
26
  identityField,
26
- sessionData,
27
27
  listKey,
28
- autoCreate,
29
- userMap,
30
- accountMap,
31
- profileMap,
28
+ sessionData,
32
29
  sessionSecret,
33
- }: {
34
- gqlNames: AuthGqlNames;
35
- identityField: string;
36
- sessionData: any;
37
- listKey: string;
38
- autoCreate: boolean;
39
- userMap: any;
40
- accountMap: any;
41
- profileMap: any;
42
- sessionSecret: string;
43
- }) => {
30
+ }: AuthTemplateOptions) => {
44
31
  const authOut = ejs.render(template, {
45
- gqlNames,
46
32
  identityField,
47
33
  sessionData,
48
34
  listKey,
49
35
  autoCreate,
50
- userMap,
51
- accountMap,
52
- profileMap,
53
36
  sessionSecret,
54
37
  });
55
38
  return authOut;
@@ -9,6 +9,9 @@ module.exports = withPreconstruct({
9
9
  typescript: {
10
10
  ignoreBuildErrors: true,
11
11
  },
12
+ env: {
13
+ NEXTAUTH_URL: process.env.NEXTAUTH_URL || 'http://localhost:<%= process.env.PORT || 3000 %><%= keystonePath || '' %>/api/auth',
14
+ },
12
15
  eslint: {
13
16
  ignoreDuringBuilds: true,
14
17
  },
package/src/types.ts CHANGED
@@ -1,44 +1,43 @@
1
1
  import { BaseListTypeInfo, KeystoneConfig } from '@keystone-6/core/types';
2
+ import { CookiesOptions, PagesOptions } from 'next-auth';
2
3
  import { Provider } from 'next-auth/providers';
3
4
 
4
- export type AuthGqlNames = {
5
- CreateInitialInput: string;
6
- createInitialItem: string;
7
- authenticateItemWithPassword: string;
8
- ItemAuthenticationWithPasswordResult: string;
9
- ItemAuthenticationWithPasswordSuccess: string;
10
- ItemAuthenticationWithPasswordFailure: string;
11
- };
12
-
13
5
  export type NextAuthSession = { listKey: string; itemId: string; data: any };
14
6
 
15
7
  export type NextAuthProviders = Provider[];
16
8
 
17
- type KeytoneAuthProviders = {
9
+ type KeytoneOAuthOptions = {
18
10
  providers: NextAuthProviders;
11
+ pages?: Partial<PagesOptions>;
12
+ };
13
+ type NextAuthOptions = {
14
+ cookies?: Partial<CookiesOptions>;
15
+ resolver: any;
19
16
  };
20
17
 
21
- export type KeystoneAuthConfig = KeystoneConfig & KeytoneAuthProviders;
18
+ export type KeystoneOAuthConfig = KeystoneConfig &
19
+ KeytoneOAuthOptions &
20
+ NextAuthOptions;
22
21
 
23
22
  export type AuthConfig<GeneratedListTypes extends BaseListTypeInfo> = {
23
+ /** Auth Create users in Keystone DB from Auth Provider */
24
+ autoCreate: boolean;
25
+ /** Adds ability to customize cookie options, for example, to facilitate cross-subdomain functionality */
26
+ cookies?: Partial<CookiesOptions>;
24
27
  /** The key of the list to authenticate users with */
25
28
  listKey: GeneratedListTypes['key'];
26
29
  /** The path of the field the identity is stored in; must be text-ish */
27
30
  identityField: GeneratedListTypes['fields'];
28
- /** Session data population */
29
- sessionData?: string;
30
- /** Auth Create users in Keystone DB from Auth Provider */
31
- autoCreate: boolean;
32
- /** Map User in next-auth to item */
33
- userMap: any;
34
- /** Map Account in next-auth to item */
35
- accountMap: any;
36
- /** Map Profile in next-auth to item */
37
- profileMap: any;
38
31
  /** Path for Keystone interface */
39
32
  keystonePath?: string;
33
+ // Custom pages for different NextAuth events
34
+ pages?: any; // TODO: Fix types
40
35
  /** Providers for Next Auth */
41
36
  providers: NextAuthProviders;
37
+ /** Resolver for user to define their profile */
38
+ resolver?: Function | undefined;
39
+ /** Session data population */
40
+ sessionData?: string | undefined;
42
41
  /** Next-Auth Session Secret */
43
42
  sessionSecret: string;
44
43
  };
@@ -1,81 +0,0 @@
1
- import type {
2
- GraphQLSchemaExtension,
3
- KeystoneContext,
4
- } from '@keystone-6/core/types';
5
- import {
6
- assertInputObjectType,
7
- GraphQLInputObjectType,
8
- GraphQLSchema,
9
- printType,
10
- } from 'graphql';
11
-
12
- import { AuthGqlNames, InitFirstItemConfig } from '../types';
13
-
14
- export function getInitFirstItemSchema({
15
- listKey,
16
- fields,
17
- itemData,
18
- gqlNames,
19
- graphQLSchema,
20
- }: {
21
- listKey: string;
22
- fields: InitFirstItemConfig<any>['fields'];
23
- itemData: InitFirstItemConfig<any>['itemData'];
24
- gqlNames: AuthGqlNames;
25
- graphQLSchema: GraphQLSchema;
26
- }): GraphQLSchemaExtension {
27
- const createInputConfig = assertInputObjectType(
28
- graphQLSchema.getType(`${listKey}CreateInput`)
29
- ).toConfig();
30
- const fieldsSet = new Set<any>(fields);
31
- const initialCreateInput = printType(
32
- new GraphQLInputObjectType({
33
- ...createInputConfig,
34
- fields: Object.fromEntries(
35
- Object.entries(createInputConfig.fields).filter(([fieldKey]) =>
36
- fieldsSet.has(fieldKey)
37
- )
38
- ),
39
- name: gqlNames.CreateInitialInput,
40
- })
41
- );
42
- return {
43
- typeDefs: `
44
- ${initialCreateInput}
45
- type Mutation {
46
- ${gqlNames.createInitialItem}(data: ${gqlNames.CreateInitialInput}!): ${gqlNames.ItemAuthenticationWithPasswordSuccess}!
47
- }
48
- `,
49
- resolvers: {
50
- Mutation: {
51
- async [gqlNames.createInitialItem](
52
- root: any,
53
- { data }: { data: Record<string, any> },
54
- context: KeystoneContext
55
- ) {
56
- if (!context.startSession) {
57
- throw new Error('No session implementation available on context');
58
- }
59
-
60
- const dbItemAPI = context.sudo().db[listKey];
61
- const count = await dbItemAPI.count({});
62
- if (count !== 0) {
63
- throw new Error(
64
- 'Initial items can only be created when no items exist in that list'
65
- );
66
- }
67
-
68
- // Update system state
69
- const item = await dbItemAPI.createOne({
70
- data: { ...data, ...itemData },
71
- });
72
- const sessionToken = await context.startSession({
73
- listKey,
74
- itemId: item.id,
75
- });
76
- return { item, sessionToken };
77
- },
78
- },
79
- },
80
- };
81
- }