Skip to content

Commit a84d22b

Browse files
committed
Improve docs
1 parent fb47c80 commit a84d22b

File tree

3 files changed

+102
-55
lines changed

3 files changed

+102
-55
lines changed

README.md

Lines changed: 84 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# GraphQL Authentication
22

3-
**Work in progress, do not use yet**
3+
_Previously called Prisma Auth_
44

55
A very opinionated user authentication package for [GraphQL](https://graphql.org/). It uses old-school email/password authentication.
66

7-
This package does not access your data layer (e.g. an ORM); for that you need to write a _adapter_ (which is not hard to do).
7+
This package provides **a GraphQL schema and GraphQL resolvers** for everything you need related to authentication. It does not access your data layer (e.g. an ORM); for that you need to write an _adapter_ (which is not hard to do).
88
If you use Prisma, there is already an adapter for you, **[graphql-authentication-prisma](https://github.com/Volst/graphql-authentication/tree/master/packages/graphql-authentication-prisma)**.
99

1010
**Features:**
@@ -19,7 +19,7 @@ If you use Prisma, there is already an adapter for you, **[graphql-authenticatio
1919

2020
# Motivation
2121

22-
Adding user authentication seems simple; there are lots of examples on how to write a "login" and a "signup" resolver. You implement it in your own project and continue working. After a while you'll have users forgetting their password so you need to build something for that. Then you want to be able to invite users, ... you get the idea. After a while you have a lot of boilerplate code related to user authentication.
22+
Adding user authentication seems simple; there are lots of examples on how to write a "login" and a "signup" resolver. You implement it in your own project and continue working. After a while you'll have users forgetting their password so you need to build something for that. Then you want to be able to invite users, ... you get the idea. In the end you have a lot of boilerplate code related to user authentication.
2323

2424
The intention with this package is **to let you write as less user-related code as possible**, while being flexible enough to support different use cases like open sign up, invitation-only signup, extra fields on the User model etc.
2525

@@ -36,16 +36,80 @@ npm i graphql-authentication email-templates
3636

3737
# Usage
3838

39+
## Using the schema
40+
41+
In your own GraphQL schema you can import all the types this package provides:
42+
43+
```graphql
44+
# import Query.*, Mutation.* from "node_modules/graphql-authentication/schema.graphql"
45+
```
46+
47+
> This only works if you use [graphql-import](https://github.com/prismagraphql/graphql-import). If you are using graphql-yoga this will work out of the box!
48+
49+
Alternatively you can only import the types you want to expose, for example:
50+
51+
```graphql
52+
# import Query.currentUser, Mutation.signupByInvite, Mutation.inviteUser, Mutation.login from "node_modules/graphql-authentication/schema.graphql"
53+
```
54+
55+
## Configuration
56+
57+
We need to add some configuration to get this package to work. The following example uses [graphql-yoga](https://github.com/graphcool/graphql-yoga/), but it should also work with Apollo Server.
58+
3959
```js
40-
class GraphqlAuthenticationSequelizeAdapter {
41-
//
42-
}
60+
import { graphqlAuthenticationConfig } from 'graphql-authentication';
61+
import * as Email from 'email-templates';
62+
63+
const server = new GraphQLServer({
64+
typeDefs: './schema.graphql',
65+
resolvers,
66+
context: req => ({
67+
...req,
68+
graphqlAuthentication: graphqlAuthenticationConfig({
69+
// Required, see for more info the "Writing an adapter" section on this page
70+
adapter: new GraphqlAuthenticationSequelizeAdapter(),
71+
// Required, used for signing JWT tokens
72+
secret: 'wheredidthesodago',
73+
// Optional, for sending emails with email-templates (https://www.npmjs.com/package/email-templates)
74+
mailer: new Email(),
75+
// Optional, the URL to your frontend which is used in emails
76+
mailAppUrl: 'http://example.com'
77+
})
78+
})
79+
});
80+
```
81+
82+
## Adding the resolvers
4383

44-
graphqlAuthentication: GraphqlAuthenticationSequelizeAdapter({
45-
adapter: new GraphqlAuthentication()
84+
You need to expose the resolvers this package provides for you to your own GraphQL server. For example:
85+
86+
```js
87+
import { authQueries, authMutations } from 'graphql-authentication';
88+
89+
const resolvers = {
90+
Query: {
91+
...authQueries
92+
},
93+
Mutation: {
94+
...authMutations
95+
}
96+
};
97+
```
98+
99+
## Emails
100+
101+
Lastly, this project can optionally send emails for you (e.g. the password reset link). [`email-templates`](https://www.npmjs.com/package/email-templates) is used for this. Be sure to configure it in the options:
102+
103+
```js
104+
import * as Email from 'email-templates';
105+
106+
graphqlAuthentication: graphqlAuthenticationConfig({
107+
mailer: new Email()
46108
});
47109
```
48110

111+
However, this package does not provide the email templates itself for you, since these differ too much. You can [**copy the email templates**](./example/emails) from our example to get started.
112+
49113
# Documentation
50114

51115
## GraphQL endpoints
@@ -188,3 +252,15 @@ graphqlAuthentication: graphqlAuthenticationConfig({
188252
requiredConfirmedEmailForLogin: true
189253
});
190254
```
255+
256+
## Writing an adapter
257+
258+
An adapter sits between GraphQL Authentication and your own ORM/database thingy. If you are using Prisma, there is already [graphql-authentication-prisma](https://github.com/Volst/graphql-authentication/tree/master/packages/graphql-authentication-prisma) for you.
259+
260+
However, if you don't use Prisma, that's totally fine! Writing an adapter shouldn't take very long.
261+
262+
In [the tests](https://github.com/Volst/prisma-auth/blob/refactor/packages/graphql-authentication/src/__tests__/setup.ts) there is a good example of an adapter.
263+
264+
You can keep the adapter class directly in your own project, make a separate npm package for it or write a PR to add it here (please do)!
265+
266+
> TODO: this section needs to be improved

packages/graphql-authentication-prisma/README.md

Lines changed: 8 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -15,58 +15,25 @@ npm i graphql-authentication graphql-authentication-prisma email-templates
1515

1616
## Step 1
1717

18-
In your Prisma `datamodel.graphql` file, add this [User model](./example/datamodel.graphql).
18+
Read the [Usage](https://github.com/Volst/graphql-authentication/blob/master/README.md#usage) section in the full documentation first.
1919

2020
## Step 2
2121

22-
In your `schema.graphql` for your own server, add something like the following (you can also import specific endpoints only):
23-
24-
```graphql
25-
# import Query.*, Mutation.* from "node_modules/graphql-authentication/schema.graphql"
26-
```
27-
28-
## Step 3
29-
30-
In your server we now need to map these types to resolvers and pass in some options. The following example uses [graphql-yoga](https://github.com/graphcool/graphql-yoga/), but it should also work with Apollo Server.
22+
After configuring the basics, you can now add this package as an adapter. Pseudo-code example:
3123

3224
```js
33-
import { authQueries, authMutations, graphqlAuthenticationConfig } from 'graphql-authentication';
3425
import { GraphqlAuthenticationPrismaAdapter } from 'graphql-authentication-prisma';
35-
import * as Email from 'email-templates';
36-
37-
const resolvers = {
38-
Query: {
39-
...authQueries
40-
},
41-
Mutation: {
42-
...authMutations
43-
}
44-
};
4526

46-
const server = new GraphQLServer({
47-
typeDefs: './schema.graphql',
48-
resolvers,
49-
context: req => ({
50-
...req,
51-
db: new Prisma({...}),
52-
graphqlAuthentication: graphqlAuthenticationConfig({
53-
adapter: new GraphqlAuthenticationPrismaAdapter({
54-
// Optional, defaults to 'db'
55-
prismaContextName: 'db'
56-
}),
57-
// Required, used for signing JWT tokens
58-
secret: 'wheredidthesodago',
59-
// Optional, for sending emails with email-templates (https://www.npmjs.com/package/email-templates)
60-
mailer: new Email(),
61-
// Optional, the URL to your frontend which is used in emails
62-
mailAppUrl: 'http://example.com',
63-
})
27+
graphqlAuthentication: graphqlAuthenticationConfig({
28+
adapter: new GraphqlAuthenticationPrismaAdapter({
29+
// Optional, defaults to 'db'
30+
prismaContextName: 'db'
6431
})
6532
});
6633
```
6734

68-
## Step 4
35+
## Step 3
6936

70-
Lastly, if you want to send emails, you should copy the email templates to your own project. Checkout [the example email templates](./example/emails).
37+
In your Prisma `datamodel.graphql` file, add this [User model](./example/datamodel.graphql). Run `prisma deploy` to run the migrations.
7138

7239
### [Full Documentation](https://github.com/Volst/graphql-authentication/blob/master/README.md#documentation)

packages/graphql-authentication/src/__tests__/setup.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import { GraphQLServer } from 'graphql-yoga';
22
import { GraphQLClient } from 'graphql-request';
3-
import { graphqlAuthenticationConfig, authQueries, authMutations } from '..';
4-
import { GraphqlAuthenticationAdapter, User, ID } from '..';
3+
import {
4+
graphqlAuthenticationConfig,
5+
authQueries,
6+
authMutations,
7+
GraphqlAuthenticationAdapter,
8+
User,
9+
ID
10+
} from '..';
511

612
export class FakeAdapter implements GraphqlAuthenticationAdapter {
713
users: User[] = [
@@ -35,16 +41,14 @@ export class FakeAdapter implements GraphqlAuthenticationAdapter {
3541
return Promise.resolve(this.users.some(user => user.email === email));
3642
}
3743
createUserBySignup(ctx: any, data: any) {
38-
const lastUser = this.users[this.users.length - 1];
3944
const user = { id: this._generateId(), ...data };
4045
this.users.push(user);
41-
return user;
46+
return Promise.resolve(user);
4247
}
4348
createUserByInvite(ctx: any, data: any) {
44-
const lastUser = this.users[this.users.length - 1];
4549
const user = { id: this._generateId(), ...data };
4650
this.users.push(user);
47-
return user;
51+
return Promise.resolve(user);
4852
}
4953
async updateUserLastLogin(ctx: any, userId: string, data: any) {
5054
const user = await this.findUserById(ctx, userId);

0 commit comments

Comments
 (0)