@opensaas/keystone-nextjs-auth 20.5.0 → 21.1.1
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +20 -0
- package/README.md +5 -3
- package/dist/declarations/src/gql/getBaseAuthSchema.d.ts +1 -3
- package/dist/declarations/src/index.d.ts +5 -5
- package/dist/declarations/src/pages/NextAuthPage.d.ts +16 -9
- package/dist/declarations/src/schema.d.ts +1 -3
- package/dist/declarations/src/templates/auth.d.ts +4 -12
- package/dist/declarations/src/types.d.ts +17 -20
- package/dist/opensaas-keystone-nextjs-auth.cjs.dev.js +77 -92
- package/dist/opensaas-keystone-nextjs-auth.cjs.prod.js +75 -92
- package/dist/opensaas-keystone-nextjs-auth.esm.js +77 -92
- package/package.json +8 -7
- package/pages/NextAuthPage/dist/opensaas-keystone-nextjs-auth-pages-NextAuthPage.cjs.dev.js +37 -32
- package/pages/NextAuthPage/dist/opensaas-keystone-nextjs-auth-pages-NextAuthPage.cjs.prod.js +37 -32
- package/pages/NextAuthPage/dist/opensaas-keystone-nextjs-auth-pages-NextAuthPage.esm.js +37 -32
- package/src/gql/getBaseAuthSchema.ts +0 -4
- package/src/index.ts +96 -94
- package/src/pages/NextAuthPage.tsx +59 -38
- package/src/schema.ts +0 -22
- package/src/templates/auth.ts +11 -28
- package/src/templates/next-config.ts +3 -0
- package/src/types.ts +20 -21
- package/src/gql/getInitFirstItemSchema.ts +0 -81
package/src/templates/auth.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import ejs from 'ejs';
|
2
|
-
import {
|
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
|
-
|
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
|
-
|
25
|
+
autoCreate,
|
25
26
|
identityField,
|
26
|
-
sessionData,
|
27
27
|
listKey,
|
28
|
-
|
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
|
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
|
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
|
-
}
|