{"id":13452585,"url":"https://github.com/Volst/graphql-authentication","last_synced_at":"2025-03-23T19:34:39.626Z","repository":{"id":32144856,"uuid":"131498800","full_name":"Volst/graphql-authentication","owner":"Volst","description":"🔑 Makes it easy to do boring authentication stuff with GraphQL (login, password reset, ...)","archived":false,"fork":false,"pushed_at":"2022-12-22T08:51:50.000Z","size":1538,"stargazers_count":234,"open_issues_count":93,"forks_count":15,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-10-01T07:29:49.622Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://graphql-authentication-demo.now.sh/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Volst.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-04-29T13:56:38.000Z","updated_at":"2024-07-19T08:56:01.000Z","dependencies_parsed_at":"2023-01-14T20:45:26.934Z","dependency_job_id":null,"html_url":"https://github.com/Volst/graphql-authentication","commit_stats":null,"previous_names":["volst/prisma-auth"],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Volst%2Fgraphql-authentication","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Volst%2Fgraphql-authentication/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Volst%2Fgraphql-authentication/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Volst%2Fgraphql-authentication/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Volst","download_url":"https://codeload.github.com/Volst/graphql-authentication/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221901015,"owners_count":16899001,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T07:01:28.227Z","updated_at":"2024-10-28T18:31:36.139Z","avatar_url":"https://github.com/Volst.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# GraphQL Authentication\n\n**Disclaimer: This repository is not actively maintained!**\n\n_Previously called Prisma Auth_\n\nA very opinionated user authentication package for [GraphQL](https://graphql.org/). It uses old-school email/password authentication.\n\nThis 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).\nIf 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)**. You can also checkout the [`examples/`](https://github.com/Volst/graphql-authentication/tree/master/examples) folder with examples on how to write an adapter for Sequelize and TypeORM!\n\n[**👉 Try out the live demo**](https://graphql-authentication-demo.now.sh/)\n\n**Features:**\n\n- Signup with good ol' email/password and confirmation email\n- Login\n- Invite another user (sends email)\n- Password reset\n- Change password of current user\n- Update current user info\n- Support for [graphql-shield](https://github.com/maticzav/graphql-shield) to deal with permissions\n\n# Motivation\n\nAdding 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.\n\nThe 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.\n\n\u003e If this package is too opinionated for you, you could still copy/paste parts of it in your application!\n\n# Install\n\nNode v8+ should be used. Install with Yarn or npm:\n\n```\nyarn add graphql-authentication email-templates\nnpm i graphql-authentication email-templates\n```\n\n# Usage\n\n## Using the schema\n\nIn your own GraphQL schema you can import all the types this package provides:\n\n```graphql\n# import Query.*, Mutation.* from \"node_modules/graphql-authentication/schema.graphql\"\n```\n\n\u003e 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!\n\nAlternatively you can only import the types you want to expose, for example:\n\n```graphql\n# import Query.currentUser, Mutation.signupByInvite, Mutation.inviteUser, Mutation.login from \"node_modules/graphql-authentication/schema.graphql\"\n```\n\n## Configuration\n\nWe 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.\n\n```js\nimport { graphqlAuthenticationConfig } from 'graphql-authentication';\nimport * as Email from 'email-templates';\n\nconst server = new GraphQLServer({\n  typeDefs: './schema.graphql',\n  resolvers,\n  context: req =\u003e ({\n    ...req,\n    graphqlAuthentication: graphqlAuthenticationConfig({\n      // Required, see for more info the \"Writing an adapter\" section on this page\n      adapter: new GraphqlAuthenticationSequelizeAdapter(),\n      // Required, used for signing JWT tokens\n      secret: 'wheredidthesodago',\n      // Optional, for sending emails with email-templates (https://www.npmjs.com/package/email-templates)\n      mailer: new Email(),\n      // Optional, the URL to your frontend which is used in emails\n      mailAppUrl: 'http://example.com'\n    })\n  })\n});\n```\n\n## Adding the resolvers\n\nYou need to expose the resolvers this package provides for you to your own GraphQL server. For example:\n\n```js\nimport { authQueries, authMutations } from 'graphql-authentication';\n\nconst resolvers = {\n  Query: {\n    ...authQueries\n  },\n  Mutation: {\n    ...authMutations\n  }\n};\n```\n\n## Emails\n\nLastly, 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:\n\n```js\nimport * as Email from 'email-templates';\n\ngraphqlAuthentication: graphqlAuthenticationConfig({\n  mailer: new Email()\n});\n```\n\nHowever, this package does not provide the email templates itself for you, since these differ too much. You can [**copy the email templates**](https://github.com/Volst/graphql-authentication/tree/master/examples/with-prisma/emails) from our example to get started.\n\n# Documentation\n\n## GraphQL endpoints\n\nMutations:\n\n- `signUpByInvite`\n- `signup`\n- `confirmEmail`\n- `inviteUser`\n- `login`\n- `changePassword`\n- `updateCurrentUser`\n- `trigerPasswordReset`\n- `passwordReset`\n\nQueries:\n\n- `currentUser`\n\nFor more details take a look at [schema.graphql](./packages/graphql-authentication/schema.graphql).\n\n## Authentication on endpoints\n\nOn some of your endpoints you might want to require that the user is logged in, or only allow the user to see the data if they have a specific role. A very powerful package exists for this, [graphql-shield](https://github.com/maticzav/graphql-shield):\n\n```js\nimport { shield, rule } from 'graphql-shield';\nimport { isAuthResolver } from 'graphql-authentication';\n\nconst isAuth = rule()(isAuthResolver);\n\nconst permissions = shield({\n  Mutation: {\n    publish: isAuth\n  }\n});\n\nconst server = new GraphQLServer({\n  typeDefs: './schema.graphql',\n  resolvers,\n  middlewares: [permissions]\n});\n```\n\nTake a look at the [graphql-shield README](https://github.com/maticzav/graphql-shield/blob/master/README.md) to find out more.\n\n## Helper utilities\n\nGet the current user in a resolver (performs a request to your data layer):\n\n```js\nimport { getUser } from 'graphql-authentication';\n\nconst Mutation = {\n  async publish(parent, data, ctx) {\n    const user = await getUser(ctx);\n    console.log('User', user.email);\n  }\n};\n```\n\nGet only the current user ID in a resolver (without request to your data layer):\n\n```js\nimport { getUserId } from 'graphql-authentication';\n\nconst Mutation = {\n  async publish(parent, data, ctx) {\n    const userId = await getUserId(ctx);\n    console.log('User', userId);\n  }\n};\n```\n\n## Login and session handling\n\n[JWT tokens](https://jwt.io/) are used to handle sessions. In the frontend you can perform a login like this:\n\n```graphql\nmutation login($email: String!, $password: String!) {\n  login(email: $email, password: $password) {\n    token\n    user {\n      # optional\n      name\n    }\n  }\n}\n```\n\nAnd then save the token to `localStorage`. Now you need to send the token with every request. If you are using Apollo, [the documentation](https://www.apollographql.com/docs/react/recipes/authentication.html#Header) has a great example on how to do this.\n\n## Adding custom fields to the User type\n\nIf you wish to expose some fields on the User type that are not exposed in our [schema.graphql](./packages/graphql-authentication/schema.graphql), you can provide your own User. In your own `schema.graphql`, do something like the following:\n\n```graphql\n# import Mutation.* from \"node_modules/graphql-authentication/schema.graphql\"\n\ntype Query {\n  currentUser: User\n}\n\ntype User {\n  id: ID!\n  email: String!\n  name: String!\n  inviteAccepted: Boolean!\n  emailConfirmed: Boolean!\n  deletedAt: DateTime\n  lastLogin: DateTime\n  joinedAt: DateTime!\n  isSuper: Boolean!\n  # And finally, our custom field:\n  isWillingToDance: Boolean!\n}\n```\n\nIf for example you do not want the `joinedAt` field to be exposed, you can simply remove it from your schema.\n\n\u003e `extend type User` would save some copy/pasta here, but unfortunately that doesn't work yet in `graphql-js`. [More info](https://github.com/graphcool/graphql-import/issues/42#issuecomment-357693183).\n\n## Signup only by invite\n\nBy default everyone can signup for your project. But what if you want to only allow invite by signup? In this case you need to leave out the `Mutation.signup` import. Example:\n\n```graphql\n# import Mutation.signupByInvite, Mutation.inviteUser, Mutation.login, Mutation.changePassword, Mutation.updateCurrentUser, Mutation.triggerPasswordReset, Mutation.passwordReset, from \"node_modules/graphql-authentication/schema.graphql\"\n```\n\n## Making email confirmation required before login\n\nAfter a user signups via the `signup` endpoint, they will get an email with a link in it to confirm their email. Meanwhile they can still login in the app. This is done to not disturb the users flow too much (e.g. services like Twitter do this too). It is left open to the project to block the user after a while. With the fields `emailConfirmed` and `joinedAt` on the User you can perhaps display a warning in your frontend or disallow certain features.\n\nHowever, you might want to block the user from logging in at all when their email is not yet confirmed. In this case you need to pass this option:\n\n```js\ngraphqlAuthentication: graphqlAuthenticationConfig({\n  requiredConfirmedEmailForLogin: true\n});\n```\n\n## Custom password validation\n\nThe users password is validated with `password.length \u003e= 8` by default. Maybe you want stricter or less stricter validation on this. You will need to pass this option to change it:\n\n```js\ngraphqlAuthentication: graphqlAuthenticationConfig({\n  validatePassword: value =\u003e value.length \u003e= 10\n});\n```\n\n## Writing an adapter\n\nAn 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.\n\nHowever, if you don't use Prisma, that's totally fine! Writing an adapter shouldn't take very long.\n\nIn [the tests](https://github.com/Volst/graphql-authentication/blob/refactor/packages/graphql-authentication/src/__tests__/setup.ts) there is a good example of an adapter. Also, the [`examples/`](https://github.com/Volst/graphql-authentication/tree/master/examples) folder contains more some custom adapters, like one for Sequelize.\n\nYou 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)!\n\n\u003e TODO: this section needs to be improved\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FVolst%2Fgraphql-authentication","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FVolst%2Fgraphql-authentication","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FVolst%2Fgraphql-authentication/lists"}