graphql_devise 0.11.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -1
  3. data/.rspec +1 -0
  4. data/.travis.yml +36 -18
  5. data/CHANGELOG.md +56 -0
  6. data/README.md +274 -35
  7. data/app/controllers/graphql_devise/application_controller.rb +4 -1
  8. data/app/controllers/graphql_devise/concerns/set_user_by_token.rb +23 -0
  9. data/app/controllers/graphql_devise/graphql_controller.rb +2 -0
  10. data/app/helpers/graphql_devise/mailer_helper.rb +2 -2
  11. data/config/routes.rb +18 -0
  12. data/graphql_devise.gemspec +3 -3
  13. data/lib/generators/graphql_devise/install_generator.rb +63 -30
  14. data/lib/graphql_devise.rb +32 -0
  15. data/lib/graphql_devise/concerns/controller_methods.rb +23 -0
  16. data/lib/graphql_devise/mount_method/operation_preparer.rb +2 -2
  17. data/lib/graphql_devise/mount_method/operation_preparers/resource_name_setter.rb +1 -1
  18. data/lib/graphql_devise/mutations/login.rb +4 -1
  19. data/lib/graphql_devise/mutations/resend_confirmation.rb +4 -1
  20. data/lib/graphql_devise/mutations/send_password_reset.rb +3 -2
  21. data/lib/graphql_devise/mutations/sign_up.rb +1 -9
  22. data/lib/graphql_devise/rails/routes.rb +5 -76
  23. data/lib/graphql_devise/resource_loader.rb +87 -0
  24. data/{app/graphql → lib}/graphql_devise/schema.rb +0 -1
  25. data/lib/graphql_devise/schema_plugin.rb +87 -0
  26. data/lib/graphql_devise/version.rb +1 -1
  27. data/spec/dummy/app/controllers/api/v1/graphql_controller.rb +11 -2
  28. data/spec/dummy/app/controllers/application_controller.rb +1 -0
  29. data/spec/dummy/app/graphql/dummy_schema.rb +9 -0
  30. data/spec/dummy/app/graphql/interpreter_schema.rb +9 -0
  31. data/spec/dummy/app/graphql/types/mutation_type.rb +1 -1
  32. data/spec/dummy/app/graphql/types/query_type.rb +10 -0
  33. data/spec/dummy/config/environments/test.rb +1 -1
  34. data/spec/dummy/config/routes.rb +1 -0
  35. data/spec/generators/graphql_devise/install_generator_spec.rb +62 -30
  36. data/spec/rails_helper.rb +4 -1
  37. data/spec/requests/graphql_controller_spec.rb +80 -0
  38. data/spec/requests/mutations/login_spec.rb +14 -2
  39. data/spec/requests/mutations/resend_confirmation_spec.rb +24 -9
  40. data/spec/requests/mutations/send_password_reset_spec.rb +9 -1
  41. data/spec/requests/mutations/sign_up_spec.rb +10 -0
  42. data/spec/requests/user_controller_spec.rb +180 -24
  43. data/spec/services/mount_method/operation_preparer_spec.rb +2 -2
  44. data/spec/services/mount_method/operation_preparers/custom_operation_preparer_spec.rb +1 -1
  45. data/spec/services/mount_method/operation_preparers/default_operation_preparer_spec.rb +1 -1
  46. data/spec/services/mount_method/operation_preparers/resource_name_setter_spec.rb +1 -1
  47. data/spec/services/resource_loader_spec.rb +82 -0
  48. data/spec/services/schema_plugin_spec.rb +26 -0
  49. data/spec/spec_helper.rb +1 -1
  50. metadata +33 -8
  51. data/spec/support/generators/file_helpers.rb +0 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2b4803d3f6df2467fd64e37ae4e91e9be33f422600b9fc0a920827313c24c843
4
- data.tar.gz: 152da5a17af638e55375f0e5af21246b26e49c107300d556dca7ba8992456666
3
+ metadata.gz: 6929ccf18a8a9f8e7cd9b3f4f5e8388cf2b6d19617ed163f8b1c769820c14e57
4
+ data.tar.gz: fb23c4d077deb50757905b0d28ed92764e8442b696273035d8a925c917e69fb4
5
5
  SHA512:
6
- metadata.gz: 33831323626b88ecdcf4805fdc1b097bd66f18af3bebf5319d16dc27a8122672d0666d0d96c638fa4e30f85f1bc24503f2481287eed594bcfa307bce9693eb69
7
- data.tar.gz: 50d5b6f84ac02367304dc81ad0609b3c5e013eb5c7eff41d5ac3feb4fa415c205810b27872e856a9b672ed621a66f361b2d61106246bf968134d08eee8524dc1
6
+ metadata.gz: 7f76369100a4ad9f5e1814a759e5a358dd9a38548a105ee685baf38cd5b5a42f18c58f28f320fe2d607e1061c2cc12ed64bd82085b616179004e93720b4e3baa
7
+ data.tar.gz: cce3f1d55751b40d6089e3a0f0b77563dbecf0298004eec3a9d40df2890ebf80b28fc8e8c95aeefb46878e7c71296c1444bff8145885f1aec014ba030253b1da
data/.gitignore CHANGED
@@ -7,13 +7,16 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
 
10
+ README.md.*
11
+
10
12
  # rspec failure tracking
11
13
  .rspec_status
12
14
  /spec/dummy/log/
13
15
  /spec/dummy/tmp/
14
16
  /Gemfile.lock
15
17
  *.gemfile.lock
16
- /*.sqlite3
18
+ *.sqlite3
19
+ *.sqlite3-journal
17
20
  /spec/dummy/db/development.sqlite3
18
21
  /spec/dummy/db/test.sqlite3
19
22
  /*.gem
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
1
  --format documentation
2
2
  --color
3
+ --order random
@@ -5,12 +5,15 @@ cache: bundler
5
5
  before_install: gem install bundler -v 1.17
6
6
  before_script: RAILS_ENV=test bundle exec rake db:create db:schema:load
7
7
 
8
+ env: EAGER_LOAD=true
9
+
8
10
  rvm:
9
11
  - 2.2.10
10
12
  - 2.3.8
11
- - 2.4.9
12
- - 2.5.7
13
- - 2.6.5
13
+ - 2.4.10
14
+ - 2.5.8
15
+ - 2.6.6
16
+ - 2.7.1
14
17
 
15
18
  gemfile:
16
19
  - gemfiles/rails4.2_graphql1.8.gemfile
@@ -25,30 +28,45 @@ gemfile:
25
28
  jobs:
26
29
  include:
27
30
  - gemfile: gemfiles/rails6.0_graphql1.8.gemfile
28
- rvm: 2.5.7
31
+ rvm: 2.5.8
32
+ - gemfile: gemfiles/rails6.0_graphql1.8.gemfile
33
+ rvm: 2.6.6
29
34
  - gemfile: gemfiles/rails6.0_graphql1.8.gemfile
30
- rvm: 2.6.5
35
+ rvm: 2.7.1
31
36
  - gemfile: gemfiles/rails6.0_graphql1.9.gemfile
32
- rvm: 2.5.7
37
+ rvm: 2.5.8
33
38
  - gemfile: gemfiles/rails6.0_graphql1.9.gemfile
34
- rvm: 2.6.5
39
+ rvm: 2.6.6
40
+ - gemfile: gemfiles/rails6.0_graphql1.9.gemfile
41
+ rvm: 2.7.1
42
+ - gemfile: gemfiles/rails6.0_graphql1.10.gemfile
43
+ rvm: 2.5.8
35
44
  - gemfile: gemfiles/rails6.0_graphql1.10.gemfile
36
- rvm: 2.5.7
45
+ rvm: 2.6.6
37
46
  - gemfile: gemfiles/rails6.0_graphql1.10.gemfile
38
- rvm: 2.6.5
47
+ rvm: 2.7.1
39
48
  - gemfile: gemfiles/rails6.0_graphql_edge.gemfile
40
- rvm: 2.5.7
41
- env: SKIP_COVERALLS=true
49
+ rvm: 2.6.6
50
+ env:
51
+ - SKIP_COVERALLS=true
52
+ - EAGER_LOAD=true
42
53
  - gemfile: gemfiles/rails6.0_graphql_edge.gemfile
43
- rvm: 2.6.5
44
- env: SKIP_COVERALLS=true
54
+ rvm: 2.7.1
55
+ env:
56
+ - SKIP_COVERALLS=true
57
+ - EAGER_LOAD=true
45
58
  - gemfile: gemfiles/rails_edge_graphql_edge.gemfile
46
- rvm: 2.6.5
47
- env: SKIP_COVERALLS=true
59
+ rvm: 2.7.1
60
+ env:
61
+ - SKIP_COVERALLS=true
62
+ - EAGER_LOAD=true
63
+ exclude:
64
+ - gemfile: gemfiles/rails4.2_graphql1.8.gemfile
65
+ rvm: 2.7.1
48
66
  allow_failures:
49
- - rvm: 2.5.7
67
+ - rvm: 2.6.6
50
68
  gemfile: gemfiles/rails6.0_graphql_edge.gemfile
51
- - rvm: 2.6.5
69
+ - rvm: 2.7.1
52
70
  gemfile: gemfiles/rails6.0_graphql_edge.gemfile
53
- - rvm: 2.6.5
71
+ - rvm: 2.7.1
54
72
  gemfile: gemfiles/rails_edge_graphql_edge.gemfile
@@ -1,5 +1,61 @@
1
1
  # Changelog
2
2
 
3
+ ## [v0.12.0](https://github.com/graphql-devise/graphql_devise/tree/v0.12.0) (2020-06-11)
4
+
5
+ [Full Changelog](https://github.com/graphql-devise/graphql_devise/compare/v0.11.4...v0.12.0)
6
+
7
+ **Implemented enhancements:**
8
+
9
+ - Mount auth operations in main GQL schema [\#96](https://github.com/graphql-devise/graphql_devise/pull/96) ([mcelicalderon](https://github.com/mcelicalderon))
10
+
11
+ ## [v0.11.4](https://github.com/graphql-devise/graphql_devise/tree/v0.11.4) (2020-05-23)
12
+
13
+ [Full Changelog](https://github.com/graphql-devise/graphql_devise/compare/v0.11.3...v0.11.4)
14
+
15
+ **Implemented enhancements:**
16
+
17
+ - Do nothing if forgery protection enabled in ApplicationController [\#93](https://github.com/graphql-devise/graphql_devise/pull/93) ([mcelicalderon](https://github.com/mcelicalderon))
18
+
19
+ ## [v0.11.3](https://github.com/graphql-devise/graphql_devise/tree/v0.11.3) (2020-05-23)
20
+
21
+ [Full Changelog](https://github.com/graphql-devise/graphql_devise/compare/v0.11.2...v0.11.3)
22
+
23
+ **Implemented enhancements:**
24
+
25
+ - Default `change\_headers\_on\_each\_request` to false [\#76](https://github.com/graphql-devise/graphql_devise/issues/76)
26
+ - Replace the auth model concern on generator execution [\#53](https://github.com/graphql-devise/graphql_devise/issues/53)
27
+ - Generator. Use our modules, change defaults [\#91](https://github.com/graphql-devise/graphql_devise/pull/91) ([mcelicalderon](https://github.com/mcelicalderon))
28
+
29
+ ## [v0.11.2](https://github.com/graphql-devise/graphql_devise/tree/v0.11.2) (2020-05-07)
30
+
31
+ [Full Changelog](https://github.com/graphql-devise/graphql_devise/compare/v0.11.1...v0.11.2)
32
+
33
+ **Fixed bugs:**
34
+
35
+ - Avoid multiple schema and type load \(Devise behavior\) [\#88](https://github.com/graphql-devise/graphql_devise/pull/88) ([mcelicalderon](https://github.com/mcelicalderon))
36
+
37
+ ## [v0.11.1](https://github.com/graphql-devise/graphql_devise/tree/v0.11.1) (2020-05-05)
38
+
39
+ [Full Changelog](https://github.com/graphql-devise/graphql_devise/compare/v0.11.0...v0.11.1)
40
+
41
+ **Implemented enhancements:**
42
+
43
+ - Honor Devise's case insensitive fields [\#81](https://github.com/graphql-devise/graphql_devise/pull/81) ([mcelicalderon](https://github.com/mcelicalderon))
44
+
45
+ **Fixed bugs:**
46
+
47
+ - Add query and mutation type only once after app routes [\#87](https://github.com/graphql-devise/graphql_devise/pull/87) ([mcelicalderon](https://github.com/mcelicalderon))
48
+
49
+ **Closed issues:**
50
+
51
+ - Get the Mutations going [\#83](https://github.com/graphql-devise/graphql_devise/issues/83)
52
+ - Improve docs. Better reference to Devise and DTA. [\#75](https://github.com/graphql-devise/graphql_devise/issues/75)
53
+ - Add case insensitive fields to sign\_up and login [\#66](https://github.com/graphql-devise/graphql_devise/issues/66)
54
+
55
+ **Merged pull requests:**
56
+
57
+ - Improve readme file [\#84](https://github.com/graphql-devise/graphql_devise/pull/84) ([mcelicalderon](https://github.com/mcelicalderon))
58
+
3
59
  ## [v0.11.0](https://github.com/graphql-devise/graphql_devise/tree/v0.11.0) (2020-04-11)
4
60
 
5
61
  [Full Changelog](https://github.com/graphql-devise/graphql_devise/compare/v0.10.1...v0.11.0)
data/README.md CHANGED
@@ -5,6 +5,55 @@
5
5
 
6
6
  GraphQL interface on top of the [Devise Token Auth](https://github.com/lynndylanhurley/devise_token_auth) (DTA) gem.
7
7
 
8
+ ## Table of Contents
9
+
10
+ <!--ts-->
11
+ * [GraphqlDevise](#graphqldevise)
12
+ * [Table of Contents](#table-of-contents)
13
+ * [Introduction](#introduction)
14
+ * [Installation](#installation)
15
+ * [Running the Generator](#running-the-generator)
16
+ * [Mounting the Schema in a Separate Route](#mounting-the-schema-in-a-separate-route)
17
+ * [Mounting Operations in Your Own Schema](#mounting-operations-in-your-own-schema)
18
+ * [Important](#important)
19
+ * [Usage](#usage)
20
+ * [Mounting Auth Schema on a Separate Route](#mounting-auth-schema-on-a-separate-route)
21
+ * [Mounting Operations Into Your Own Schema](#mounting-operations-into-your-own-schema)
22
+ * [Available Mount Options](#available-mount-options)
23
+ * [Available Operations](#available-operations)
24
+ * [Configuring Model](#configuring-model)
25
+ * [Customizing Email Templates](#customizing-email-templates)
26
+ * [I18n](#i18n)
27
+ * [Authenticating Controller Actions](#authenticating-controller-actions)
28
+ * [Authenticate Before Reaching Your GQL Schema](#authenticate-before-reaching-your-gql-schema)
29
+ * [Authenticate in Your GQL Schema](#authenticate-in-your-gql-schema)
30
+ * [Making Requests](#making-requests)
31
+ * [Mutations](#mutations)
32
+ * [Queries](#queries)
33
+ * [More Configuration Options](#more-configuration-options)
34
+ * [Devise Token Auth Initializer](#devise-token-auth-initializer)
35
+ * [Devise Initializer](#devise-initializer)
36
+ * [GraphQL Interpreter](#graphql-interpreter)
37
+ * [Using Alongside Standard Devise](#using-alongside-standard-devise)
38
+ * [Future Work](#future-work)
39
+ * [Contributing](#contributing)
40
+ * [License](#license)
41
+
42
+ <!-- Added by: mcelicalderon, at: Wed Jun 10 22:10:26 -05 2020 -->
43
+
44
+ <!--te-->
45
+
46
+ ## Introduction
47
+ This gem heavily relies on two gems, [Devise Token Auth](https://github.com/lynndylanhurley/devise_token_auth) (DTA)
48
+ and [Devise](https://github.com/heartcombo/devise) which is a dependency of DTA.
49
+ It provides a GraphQL interface on top of DTA which is designed to work with REST APIs. That's why
50
+ things like token management, token expiration and everything up until using the actual GraphQL schema is
51
+ still controlled by DTA. For that reason you will find that our generator runs these two gems generator and two
52
+ initializer files are included. We'll provide more configuration details in the
53
+ [configuration section](#more-configuration-options),
54
+ but **we recommend you get familiar with [DTA and their docs](https://github.com/lynndylanhurley/devise_token_auth)
55
+ in order to use this gem to its full potential**.
56
+
8
57
  ## Installation
9
58
 
10
59
  Add this line to your application's Gemfile:
@@ -14,17 +63,11 @@ gem 'graphql_devise'
14
63
  ```
15
64
 
16
65
  And then execute:
66
+ ```bash
67
+ $ bundle
68
+ ```
17
69
 
18
- $ bundle
19
-
20
- Or install it yourself as:
21
-
22
- $ gem install graphql_devise
23
-
24
- Next, you need to run the generator:
25
-
26
- $ rails generate graphql_devise:install
27
-
70
+ ### Running the Generator
28
71
  Graphql Devise generator will execute `Devise` and `Devise Token Auth`
29
72
  generators for you. These will make the required changes for the gems to
30
73
  work correctly. All configurations for [Devise](https://github.com/plataformatec/devise) and
@@ -32,11 +75,16 @@ work correctly. All configurations for [Devise](https://github.com/plataformatec
32
75
  so you can read the docs there to customize your options.
33
76
  Configurations are done via initializer files as usual, one per gem.
34
77
 
78
+ #### Mounting the Schema in a Separate Route
79
+ ```bash
80
+ $ bundle exec rails generate graphql_devise:install
81
+ ```
82
+
35
83
  The generator accepts 2 params: `user_class` and `mount_path`. The params
36
84
  will be used to mount the route in `config/routes.rb`. For instance the executing:
37
85
 
38
86
  ```bash
39
- $ rails g graphql_devise:install Admin api/auth
87
+ $ bundle exec rails g graphql_devise:install Admin api/auth
40
88
  ```
41
89
 
42
90
  Will do the following:
@@ -51,9 +99,33 @@ Will do the following:
51
99
  `Admin` could be any model name you are going to be using for authentication,
52
100
  and `api/auth` could be any mount path you would like to use for auth.
53
101
 
54
- ### Mounting Routes manually
55
- Routes can be added using the initializer or manually.
56
- You can add a route like this:
102
+ #### Mounting Operations in Your Own Schema
103
+ Now you can provide to the generator an option specifying
104
+ the name of your GQL schema. Doing this will skip the insertion of the mount method in the
105
+ routes file and will also add our `SchemaPlugin` to the specified schema. `user_class` param is still optional (`Admin`) in the following example.
106
+
107
+ ```bash
108
+ $ bundle exec rails g graphql_devise:install Admin --mount MySchema
109
+ ```
110
+
111
+ ### Important
112
+ Remember that by default this gem mounts a completely separate GraphQL schema on a separate controller in the route
113
+ provided by the `at` option in the `mount_graphql_devise_for` method in the `config/routes.rb` file. If no `at`
114
+ option is provided, the route will be `/graphql_auth`.
115
+
116
+ **Starting with `v0.12.0`** you can opt-in to load this gem's queries and mutations into your
117
+ own application's schema. You can actually mount a resource's auth schema in a separate route
118
+ and in your app's schema at the same time, but that's probably not a common scenario. More on
119
+ this in the next section.
120
+
121
+ ## Usage
122
+ ### Mounting Auth Schema on a Separate Route
123
+ The generator can do this step for you by default. Remember now you can mount this gem's
124
+ auth operations into your own schema as described in [this section](#mounting-operations-into-your-own-schema).
125
+
126
+
127
+ Routes can be added using the generator or manually.
128
+ You can mount this gem's GraphQL auth schema in your routes file like this:
57
129
 
58
130
  ```ruby
59
131
  # config/routes.rb
@@ -78,11 +150,83 @@ Rails.application.routes.draw do
78
150
  )
79
151
  end
80
152
  ```
153
+ The second argument of the `mount_graphql_devise` method is a hash of options where you can
154
+ customize how the queries and mutations are mounted into the schema. For a list of available
155
+ options go [here](#available-mount-options)
156
+
157
+ ### Mounting Operations Into Your Own Schema
158
+ Starting with `v0.12.0` you can now mount the GQL operations provided by this gem into your
159
+ app's main schema.
160
+
161
+ ```ruby
162
+ # app/graphql/dummy_schema.rb
163
+
164
+ class DummySchema < GraphQL::Schema
165
+ # It's important that this line goes before setting the query and mutation type on your
166
+ # schema in graphql versions < 1.10.0
167
+ use GraphqlDevise::SchemaPlugin.new(
168
+ query: Types::QueryType,
169
+ mutation: Types::MutationType,
170
+ resource_loaders: [
171
+ GraphqlDevise::ResourceLoader.new('User', only: [:login, :confirm_account])
172
+ ]
173
+ )
174
+
175
+ mutation(Types::MutationType)
176
+ query(Types::QueryType)
177
+ end
178
+ ```
179
+ The example above describes just one of the possible scenarios you might need.
180
+ The second argument of the `GraphqlDevise::ResourceLoader` initializer is a hash of
181
+ options where you can customize how the queries and mutations are mounted into the schema.
182
+ For a list of available options go [here](#available-mount-options).
183
+
184
+ It's important to use the plugin in your schema before assigning the mutation and query type to
185
+ it in graphql versions `< 1.10.0`. Otherwise the auth operations won't be available.
186
+
187
+ You can provide as many resource loaders as you need to the `resource_loaders` option, and each
188
+ of those will be loaded into your schema. These are the options you can initialize the
189
+ `SchemaPlugin` with:
190
+
191
+ 1. `query`: This param is mandatory unless you skip all queries via the resource loader
192
+ options. This should be the same `QueryType` you provide to the `query` method
193
+ in your schema.
194
+ 1. `mutation`: This param mandatory unless you skip all mutations via the resource loader
195
+ options. This should be the same `MutationType` you provide to the `mutation` method
196
+ in your schema.
197
+ 1. `resource_loaders`: This is an optional array of `GraphqlDevise::ResourceLoader` instances.
198
+ Here is where you specify the operations that you want to load into your app's schema.
199
+ If no loader is provided, no operations will be added to your schema, but you will still be
200
+ able to authenticate queries and mutations selectively. More on this in the controller
201
+ authentication [section](#authenticating-controller-actions).
202
+ 1. `authenticate_default`: This is a boolean value which is `true` by default. This value
203
+ defines what is the default behavior for authentication in your schema fields. `true` means
204
+ every root level field requires authentication unless specified otherwise using the
205
+ `authenticate: false` option on the field. `false` means your root level fields won't require
206
+ authentication unless specified otherwise using the `authenticate: true` option on the field.
207
+ 1. `unauthenticated_proc`: This param is optional. Here you can provide a proc that receives
208
+ one argument (field name) and is called whenever a field that requires authentication
209
+ is called without an authenticated resource. By default a `GraphQL::ExecutionError` will be
210
+ raised if authentication fails. This will provide a GQL like error message on the response.
211
+
212
+ ### Available Mount Options
213
+ Both the `mount_graphql_devise_for` method and the `GraphqlDevise::ResourceLoader` class
214
+ take the same options. So, wether you decide to mount this gem in a separate route
215
+ from your main application's schema or you use our `GraphqlDevise::SchemaPlugin` to load
216
+ this gem's auth operation into your schema, these are the options you can provide as a hash.
217
+
218
+ ```ruby
219
+ # Using the mount method in your config/routes.rb file
220
+ mount_graphql_devise_for('User', {})
81
221
 
82
- Here are the options for the mount method:
222
+ # Providing options to a GraphqlDevise::ResourceLoader
223
+ GraphqlDevise::ResourceLoader.new('User', {})
224
+ ```
83
225
 
84
- 1. `at`: Route where the GraphQL schema will be mounted on the Rails server. In this example your API will have these two routes: `POST /api/v1/graphql_auth` and `GET /api/v1/graphql_auth`.
85
- If this option is not specified, the schema will be mounted at `/graphql_auth`.
226
+ 1. `at`: Route where the GraphQL schema will be mounted on the Rails server.
227
+ In [this example](#mounting-auth-schema-on-a-separate-route) your API will have
228
+ these two routes: `POST /api/v1/graphql_auth` and `GET /api/v1/graphql_auth`.
229
+ If this option is not specified, the schema will be mounted at `/graphql_auth`. **This option only works if you are using the mount method.**
86
230
  1. `operations`: Specifying this is optional. Here you can override default
87
231
  behavior by specifying your own mutations and queries for every GraphQL operation.
88
232
  Check available operations in this file [mutations](https://github.com/graphql-devise/graphql_devise/blob/b5985036e01ea064e43e457b4f0c8516f172471c/lib/graphql_devise/rails/routes.rb#L19)
@@ -121,7 +265,7 @@ or [base resolver](https://github.com/graphql-devise/graphql_devise/blob/master/
121
265
  respectively, to take advantage of some of the methods provided by devise
122
266
  just like with `devise_scope`
123
267
 
124
- #### Available Operations
268
+ ### Available Operations
125
269
  The following is a list of the symbols you can provide to the `operations`, `skip` and `only` options of the mount method:
126
270
  ```ruby
127
271
  :login
@@ -133,7 +277,6 @@ The following is a list of the symbols you can provide to the `operations`, `ski
133
277
  :check_password_token
134
278
  ```
135
279
 
136
-
137
280
  ### Configuring Model
138
281
  Just like with Devise and DTA, you need to include a module in your authenticatable model,
139
282
  so with our example, your user model will have to look like this:
@@ -151,16 +294,12 @@ class User < ApplicationRecord
151
294
  :confirmable
152
295
 
153
296
  # including after calling the `devise` method is important.
154
- # include DeviseTokenAuth::Concerns::User # is also valid (generator includes this one).
155
297
  include GraphqlDevise::Concerns::Model
156
298
  end
157
299
  ```
158
300
 
159
301
  The install generator can do this for you if you specify the `user_class` option.
160
- See [Installation](#Installation) for details.
161
- The generator will include a different module in your model, `DeviseTokenAuth::Concerns::User` which is also correct,
162
- we just made an alias on our namespace for consistency and possible extension.
163
- Generators have to be updated to generate our module.
302
+ See [Installation](#installation) for details.
164
303
 
165
304
  ### Customizing Email Templates
166
305
  The approach of this gem is a bit different from DeviseTokenAuth. We have placed our templates in `app/views/graphql_devise/mailer`,
@@ -178,13 +317,15 @@ Keep in mind that if your app uses multiple locales, you should set the `I18n.lo
178
317
 
179
318
  ### Authenticating Controller Actions
180
319
  Just like with Devise or DTA, you will need to authenticate users in your controllers.
320
+ For this you have two alternatives.
321
+
322
+ #### Authenticate Before Reaching Your GQL Schema
181
323
  For this you need to call `authenticate_<model>!` in a before_action hook of your controller.
182
324
  In our example our model is `User`, so it would look like this:
183
325
  ```ruby
184
326
  # app/controllers/my_controller.rb
185
327
 
186
328
  class MyController < ApplicationController
187
- # include DeviseTokenAuth::Concerns::SetUserByToken # is also valid (generator includes this one).
188
329
  include GraphqlDevise::Concerns::SetUserByToken
189
330
 
190
331
  before_action :authenticate_user!
@@ -197,9 +338,62 @@ end
197
338
 
198
339
  The install generator can do this for you because it executes DTA installer.
199
340
  See [Installation](#Installation) for details.
200
- The generator will include a different module in your model, `DeviseTokenAuth::Concerns::SetUserByToken` which is also correct,
201
- we just made an alias on our namespace for consistency and possible extension.
202
- Generators have to be updated to generate our module.
341
+ If authentication fails for the request for whatever reason, execution of the request is halted
342
+ and an error is returned in a REST format as the request never reaches your GQL schema.
343
+
344
+ #### Authenticate in Your GQL Schema
345
+ For this you will need to add the `GraphqlDevise::SchemaPlugin` to your schema as described
346
+ [here](#mounting-operations-into-your-own-schema) and also set the authenticated resource
347
+ in a `before_action` hook.
348
+
349
+ ```ruby
350
+ # app/controllers/my_controller.rb
351
+
352
+ class MyController < ApplicationController
353
+ include GraphqlDevise::Concerns::SetUserByToken
354
+
355
+ before_action -> { set_resource_by_token(:user) }
356
+
357
+ def my_action
358
+ render json: DummySchema.execute(params[:query], context: graphql_context)
359
+ end
360
+ end
361
+
362
+ # @resource.to_s.underscore.tr('/', '_').to_sym
363
+ ```
364
+ The `set_resource_by_token` method receives a symbol identifying the resource you are trying
365
+ to authenticate. So if you mounted the `'User'` resource, the symbol is `:user`. You can use
366
+ this snippet to find the symbol for more complex scenarios
367
+ `resource_klass.to_s.underscore.tr('/', '_').to_sym`.
368
+
369
+ The `graphql_context` method is simply a helper method that returns a hash like this
370
+ ```ruby
371
+ { current_resource: @resource, controller: self }
372
+ ```
373
+ These are the two values the gem needs to check if a user is authenticated and to perform
374
+ other auth operations. All `set_resource_by_token` does is set the `@resource` variable if
375
+ the provided authentication headers are valid. If authentication fails, resource will be `nil`
376
+ and this is how `GraphqlDevise::SchemaPlugin` knows if a user is authenticated or not in
377
+ each query.
378
+
379
+ Please note that by using this mechanism your GQL schema will be in control of what queries are
380
+ restricted to authenticated users and you can only do this at the root level fields of your GQL
381
+ schema. Configure the plugin as explained [here](#mounting-operations-into-your-own-schema)
382
+ so this can work.
383
+
384
+ In you main app's schema this is how you might specify if a field needs to be authenticated or not:
385
+ ```ruby
386
+ module Types
387
+ class QueryType < Types::BaseObject
388
+ # user field used the default set in the Plugin's initializer
389
+ field :user, resolver: Resolvers::UserShow
390
+ # this field will never require authentication
391
+ field :public_field, String, null: false, authenticate: false
392
+ # this field requires authentication
393
+ field :private_field, String, null: false, authenticate: true
394
+ end
395
+ end
396
+ ```
203
397
 
204
398
  ### Making Requests
205
399
  Here is a list of the available mutations and queries assuming your mounted model is `User`.
@@ -214,10 +408,12 @@ Here is a list of the available mutations and queries assuming your mounted mode
214
408
  1. `userSignUp(email: String!, password: String!, passwordConfirmation: String!, confirmSuccessUrl: String): UserSignUpPayload`
215
409
 
216
410
  The parameter `confirmSuccessUrl` is optional unless you are using the `confirmable` plugin from Devise in your `resource`'s model. If you have `confirmable` set up, you will have to provide it unless you have `config.default_confirm_success_url` set in `config/initializers/devise_token_auth.rb`.
411
+ 1. `userSendResetPassword(email: String!, redirectUrl: String!): UserSendReserPasswordPayload`
217
412
  1. `userUpdatePassword(password: String!, passwordConfirmation: String!, currentPassword: String): UserUpdatePasswordPayload`
218
413
 
219
- The parameter `currentPassword` is optional if you have `config.check_current_password_before_update` set to false (disabled by default) or the `resource` model supports the `recoverable` Devise plugin and the `resource`'s `allow_password_change` attribute is set to true.
220
- 1. `userSendResetPassword(email: String!, redirectUrl: String!): UserSendReserPasswordPayload`
414
+ The parameter `currentPassword` is optional if you have `config.check_current_password_before_update` set to
415
+ false (disabled by default) on your generated `config/initializers/devise_token_aut.rb` or if the `resource`
416
+ model supports the `recoverable` Devise plugin and the `resource`'s `allow_password_change` attribute is set to true (this is done in the `userCheckPasswordToken` query when you click on the sent email's link).
221
417
  1. `userResendConfirmation(email: String!, redirectUrl: String!): UserResendConfirmationPayload`
222
418
 
223
419
  The `UserResendConfirmationPayload` will return the `authenticatable` resource that was sent the confirmation instructions but also has a `message: String!` that can be used to notify a user what to do after the instructions were sent to them
@@ -232,21 +428,64 @@ requests using the `GET` method on the Rails side, but looks like there might be
232
428
  on the [Apollo Client](https://www.apollographql.com/docs/apollo-server/v1/requests/#get-requests).
233
429
 
234
430
  We will continue to build better docs for the gem after this first release, but in the mean time
235
- you can use [our specs](https://github.com/graphql-devise/graphql_devise/tree/b5985036e01ea064e43e457b4f0c8516f172471c/spec/requests) to better understand how to use the gem.
236
- Also, the [dummy app](https://github.com/graphql-devise/graphql_devise/tree/b5985036e01ea064e43e457b4f0c8516f172471c/spec/dummy) used in our specs will give you
431
+ you can use [our specs](spec/requests) to better understand how to use the gem.
432
+ Also, the [dummy app](spec/dummy) used in our specs will give you
237
433
  a clear idea on how to configure the gem on your Rails application.
238
434
 
435
+ ### More Configuration Options
436
+ As mentioned in the introduction there are many configurations that will change how this gem behaves. You can change
437
+ this values on the initializer files generated by the installer.
438
+
439
+ #### Devise Token Auth Initializer
440
+ The generated initializer file `config/initializers/devise_token_auth.rb` has all the available options documented
441
+ as comments. You can also use
442
+ **[DTA's docs](https://devise-token-auth.gitbook.io/devise-token-auth/config/initialization)** as a reference.
443
+ In this section the most important configurations will be highlighted.
444
+
445
+ - **change_headers_on_each_request:** This configurations defaults to `false`. This will allow you to store the
446
+ credentials for as long as the token life_span permits. And you can send the same credentials in each request.
447
+ Setting this to `true` means that tokens will change on each request you make, and the new values will be returned
448
+ in the headers. So your client needs to handle this.
449
+ - **batch_request_buffer_throttle:** When change_headers_on_each_request is set to true, you might still want your
450
+ credentials to be valid more than once as you might send parallel request. The duration you set here will
451
+ determine how long the same credentials work after the first request is received.
452
+ - **token_lifespan:** This configuration takes a duration and you can set it to a value like
453
+ `1.month`, `2.weeks`, `1.hour`, etc.
454
+
455
+ **Note:** Remember this gem adds a layer on top of DTA, so some configurations might not apply.
456
+
457
+ #### Devise Initializer
458
+ The generated initializer file `config/initializers/devise_token_auth.rb` has all the available options documented
459
+ as comments. You can also use
460
+ **[Devise's docs](https://github.com/heartcombo/devise)** as a reference.
461
+ In this section the most important configurations will be highlighted.
462
+
463
+ - **password_length:** You can change this value to validate password length on sign up and password update
464
+ (must enable the validatable module).
465
+ - **mailer_sender:** Set it to a string with the sender's email address like `'support@example.com'`.
466
+ - **case_insensitive_keys:** Setting a value like `[:email]` will make email field case insensitive on login, sign up, etc.
467
+ - **email_regexp:** You can customize the regex that will validate the format of email addresses (must enable the validatable module).
468
+
469
+ **Note:** Remember this gem adds a layer on top of Devise, so some configurations might not apply.
470
+
471
+ ### GraphQL Interpreter
472
+ GraphQL-Ruby `>= 1.9.0` includes a new runtime module which you may use for your schema.
473
+ Eventually, it will become the default. You can read more about it
474
+ [here](https://graphql-ruby.org/queries/interpreter).
475
+
476
+ This gem supports schemas using the interpreter and it is recommended as it introduces several
477
+ improvements which focus mainly on performance.
478
+
239
479
  ### Using Alongside Standard Devise
240
480
  The DeviseTokenAuth gem allows experimental use of the standard Devise gem to be configured at the same time, for more
241
481
  information you can check [this answer here](https://github.com/lynndylanhurley/devise_token_auth/blob/2a32f18ccce15638a74e72f6cfde5cf15a808d3f/docs/faq.md#can-i-use-this-gem-alongside-standard-devise).
242
482
 
243
- This gem supports the same and should be easier to handle email templates due to the fact we don't override standard Devise
244
- templates.
483
+ This gem supports the same and should be easier to handle email templates due to the fact we don't override
484
+ standard Devise templates.
245
485
 
246
486
  ## Future Work
247
487
  We will continue to improve the gem and add better docs.
248
488
 
249
- 1. Add mount option that will create a separate schema for the mounted resource.
250
489
  1. Make sure this gem can correctly work alongside DTA and the original Devise gem.
251
490
  1. Improve DOCS.
252
491
  1. Add support for unlockable and other Devise modules.