graphql_devise 0.14.3 → 0.17.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +7 -0
  3. data/CHANGELOG.md +58 -0
  4. data/README.md +186 -82
  5. data/app/controllers/graphql_devise/concerns/additional_controller_methods.rb +72 -0
  6. data/app/controllers/graphql_devise/concerns/set_user_by_token.rb +5 -27
  7. data/app/helpers/graphql_devise/mailer_helper.rb +2 -2
  8. data/app/models/graphql_devise/concerns/additional_model_methods.rb +21 -0
  9. data/app/models/graphql_devise/concerns/model.rb +6 -9
  10. data/app/views/graphql_devise/mailer/confirmation_instructions.html.erb +7 -1
  11. data/lib/generators/graphql_devise/install_generator.rb +1 -1
  12. data/lib/graphql_devise.rb +20 -6
  13. data/lib/graphql_devise/concerns/controller_methods.rb +3 -3
  14. data/lib/graphql_devise/default_operations/mutations.rb +14 -8
  15. data/lib/graphql_devise/default_operations/resolvers.rb +2 -2
  16. data/lib/graphql_devise/model/with_email_updater.rb +34 -8
  17. data/lib/graphql_devise/mount_method/operation_preparer.rb +6 -6
  18. data/lib/graphql_devise/mount_method/operation_preparers/custom_operation_preparer.rb +6 -4
  19. data/lib/graphql_devise/mount_method/operation_preparers/default_operation_preparer.rb +7 -5
  20. data/lib/graphql_devise/mount_method/operation_preparers/{resource_name_setter.rb → resource_klass_setter.rb} +4 -4
  21. data/lib/graphql_devise/mount_method/operation_sanitizer.rb +13 -1
  22. data/lib/graphql_devise/mutations/confirm_registration_with_token.rb +30 -0
  23. data/lib/graphql_devise/mutations/login.rb +2 -0
  24. data/lib/graphql_devise/mutations/register.rb +60 -0
  25. data/lib/graphql_devise/mutations/resend_confirmation_with_token.rb +44 -0
  26. data/lib/graphql_devise/mutations/sign_up.rb +1 -1
  27. data/lib/graphql_devise/resolvers/confirm_account.rb +1 -1
  28. data/lib/graphql_devise/resource_loader.rb +26 -11
  29. data/lib/graphql_devise/schema_plugin.rb +20 -8
  30. data/lib/graphql_devise/version.rb +1 -1
  31. data/spec/dummy/app/controllers/api/v1/graphql_controller.rb +11 -0
  32. data/spec/dummy/app/graphql/dummy_schema.rb +4 -3
  33. data/spec/dummy/app/graphql/mutations/register.rb +14 -0
  34. data/spec/dummy/app/graphql/types/query_type.rb +5 -0
  35. data/spec/dummy/config/routes.rb +7 -5
  36. data/spec/dummy/db/migrate/20210516211417_add_vip_to_users.rb +5 -0
  37. data/spec/dummy/db/schema.rb +4 -3
  38. data/spec/generators/graphql_devise/install_generator_spec.rb +1 -1
  39. data/spec/graphql/user_queries_spec.rb +3 -1
  40. data/spec/graphql_devise/model/with_email_updater_spec.rb +97 -68
  41. data/spec/requests/graphql_controller_spec.rb +1 -1
  42. data/spec/requests/mutations/confirm_registration_with_token_spec.rb +117 -0
  43. data/spec/requests/mutations/register_spec.rb +166 -0
  44. data/spec/requests/mutations/resend_confirmation_with_token_spec.rb +137 -0
  45. data/spec/requests/user_controller_spec.rb +86 -25
  46. data/spec/services/mount_method/operation_preparer_spec.rb +5 -5
  47. data/spec/services/mount_method/operation_preparers/custom_operation_preparer_spec.rb +5 -5
  48. data/spec/services/mount_method/operation_preparers/default_operation_preparer_spec.rb +5 -5
  49. data/spec/services/mount_method/operation_preparers/{resource_name_setter_spec.rb → resource_klass_setter_spec.rb} +6 -6
  50. data/spec/services/mount_method/operation_sanitizer_spec.rb +3 -3
  51. data/spec/services/resource_loader_spec.rb +5 -5
  52. data/spec/support/contexts/graphql_request.rb +2 -2
  53. metadata +21 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8babaa3e2f0ece19b6abd429ea42fb2f87f93490beb6a781329756506c90a00b
4
- data.tar.gz: 599bb62bff4fa27c19f83a75ba328d1af3915b2fb726553168678a8a47a8a8ee
3
+ metadata.gz: 0a627bf05673e2c42f24eeb15db1101c060caade6270485146676c6e30840e5d
4
+ data.tar.gz: 9e97f20e1c073225d884e4d2e4fd9e0c9bddbf4eab52fc214c7c1cd5a113411f
5
5
  SHA512:
6
- metadata.gz: dd833162fd74b0174358424a5ef0ec59ce663577c1ce6de6b84b712d05856cba2e226aece27e07c03eef681483862ef181ef4dc61674b2b74e6c8f939e6c7e0a
7
- data.tar.gz: 8e7af3981a3ad1d4a199ddf31cc3242f603205a02181b76d9e63be7ff09979927acd0305578d1583a421c08e076a666778a15d62e4fb1c9517d54f91a3b39111
6
+ metadata.gz: 2b4026ea6635fdb87856a57eb50ae58cd5406605ffc46347957e1839da04586e2015792905a8214aa24b4ba0b991102ea0edc4e4713e510e42fa23bc13569a9f
7
+ data.tar.gz: 9b24ea5c67644952818cb0dce4119696aa552e1cc9aeda5c67fbe045d15a64312be4c868eed5b9780f2114e4d6e50a73edf6ca13513fda0c5745213a10a9586f
data/Appraisals CHANGED
@@ -3,6 +3,7 @@ appraise 'rails4.2-graphql1.8' do
3
3
  gem 'bundler', '~> 1.17'
4
4
  gem 'rails', github: 'rails/rails', branch: '4-2-stable'
5
5
  gem 'graphql', '~> 1.8.0'
6
+ gem 'devise_token_auth', '< 1.2'
6
7
  gem 'rspec-rails', '< 4.0'
7
8
  end
8
9
 
@@ -19,6 +20,7 @@ appraise 'rails5.0-graphql1.9' do
19
20
  gem 'sqlite3', '~> 1.3.6'
20
21
  gem 'rails', github: 'rails/rails', branch: '5-0-stable'
21
22
  gem 'graphql', '~> 1.9.0'
23
+ gem 'devise_token_auth', '< 1.2'
22
24
  gem 'rspec-rails', '< 4.0'
23
25
  end
24
26
 
@@ -35,6 +37,7 @@ appraise 'rails5.1-graphql1.9' do
35
37
  gem 'sqlite3', '~> 1.3.6'
36
38
  gem 'rails', github: 'rails/rails', branch: '5-1-stable'
37
39
  gem 'graphql', '~> 1.9.0'
40
+ gem 'devise_token_auth', '< 1.2'
38
41
  gem 'rspec-rails', '< 4.0'
39
42
  end
40
43
 
@@ -51,6 +54,7 @@ appraise 'rails5.2-graphql1.9' do
51
54
  gem 'sqlite3', '~> 1.3.6'
52
55
  gem 'rails', github: 'rails/rails', branch: '5-2-stable'
53
56
  gem 'graphql', '~> 1.9.0'
57
+ gem 'devise_token_auth', '< 1.2'
54
58
  gem 'rspec-rails', '< 4.0'
55
59
  end
56
60
 
@@ -58,6 +62,7 @@ appraise 'rails5.2-graphql1.10' do
58
62
  gem 'sqlite3', '~> 1.3.6'
59
63
  gem 'rails', github: 'rails/rails', branch: '5-2-stable'
60
64
  gem 'graphql', '~> 1.10.0'
65
+ gem 'devise_token_auth', '< 1.2'
61
66
  gem 'rspec-rails', '< 4.0'
62
67
  end
63
68
 
@@ -65,6 +70,7 @@ appraise 'rails5.2-graphql1.11' do
65
70
  gem 'sqlite3', '~> 1.3.6'
66
71
  gem 'rails', github: 'rails/rails', branch: '5-2-stable'
67
72
  gem 'graphql', '~> 1.11.0'
73
+ gem 'devise_token_auth', '< 1.2'
68
74
  gem 'rspec-rails', '< 4.0'
69
75
  end
70
76
 
@@ -72,6 +78,7 @@ appraise 'rails5.2-graphql1.12' do
72
78
  gem 'sqlite3', '~> 1.3.6'
73
79
  gem 'rails', github: 'rails/rails', branch: '5-2-stable'
74
80
  gem 'graphql', '~> 1.12.0'
81
+ gem 'devise_token_auth', '< 1.2'
75
82
  gem 'rspec-rails', '< 4.0'
76
83
  end
77
84
 
data/CHANGELOG.md CHANGED
@@ -1,5 +1,63 @@
1
1
  # Changelog
2
2
 
3
+ ## [v0.17.1](https://github.com/graphql-devise/graphql_devise/tree/v0.17.1) (2021-08-02)
4
+
5
+ [Full Changelog](https://github.com/graphql-devise/graphql_devise/compare/v0.17.0...v0.17.1)
6
+
7
+ **Implemented enhancements:**
8
+
9
+ - Set context\[:current\_resource\] upon login [\#193](https://github.com/graphql-devise/graphql_devise/pull/193) ([TomasBarry](https://github.com/TomasBarry))
10
+
11
+ **Merged pull requests:**
12
+
13
+ - Improve README [\#190](https://github.com/graphql-devise/graphql_devise/pull/190) ([00dav00](https://github.com/00dav00))
14
+
15
+ ## [v0.17.0](https://github.com/graphql-devise/graphql_devise/tree/v0.17.0) (2021-06-09)
16
+
17
+ [Full Changelog](https://github.com/graphql-devise/graphql_devise/compare/v0.16.0...v0.17.0)
18
+
19
+ **Implemented enhancements:**
20
+
21
+ - Another click in confirm account results in error [\#184](https://github.com/graphql-devise/graphql_devise/issues/184)
22
+ - Add resendConfirmationWithToken mutation [\#186](https://github.com/graphql-devise/graphql_devise/pull/186) ([mcelicalderon](https://github.com/mcelicalderon))
23
+ - Add register mutation and alternate confirmation flow [\#185](https://github.com/graphql-devise/graphql_devise/pull/185) ([mcelicalderon](https://github.com/mcelicalderon))
24
+
25
+ **Deprecated:**
26
+
27
+ - Deprecate mutations and queries that required a redirect [\#187](https://github.com/graphql-devise/graphql_devise/pull/187) ([mcelicalderon](https://github.com/mcelicalderon))
28
+
29
+ **Merged pull requests:**
30
+
31
+ - Document new registration and confirmation flow [\#188](https://github.com/graphql-devise/graphql_devise/pull/188) ([mcelicalderon](https://github.com/mcelicalderon))
32
+
33
+ ## [v0.16.0](https://github.com/graphql-devise/graphql_devise/tree/v0.16.0) (2021-05-20)
34
+
35
+ [Full Changelog](https://github.com/graphql-devise/graphql_devise/compare/v0.15.0...v0.16.0)
36
+
37
+ **Implemented enhancements:**
38
+
39
+ - Allow checking of authenticaded resource via callable object [\#180](https://github.com/graphql-devise/graphql_devise/pull/180) ([mcelicalderon](https://github.com/mcelicalderon))
40
+
41
+ **Merged pull requests:**
42
+
43
+ - Document authenticate with callable [\#181](https://github.com/graphql-devise/graphql_devise/pull/181) ([mcelicalderon](https://github.com/mcelicalderon))
44
+
45
+ ## [v0.15.0](https://github.com/graphql-devise/graphql_devise/tree/v0.15.0) (2021-05-09)
46
+
47
+ [Full Changelog](https://github.com/graphql-devise/graphql_devise/compare/v0.14.3...v0.15.0)
48
+
49
+ **Implemented enhancements:**
50
+
51
+ - Allow controller level authentication [\#175](https://github.com/graphql-devise/graphql_devise/pull/175) ([mcelicalderon](https://github.com/mcelicalderon))
52
+
53
+ **Deprecated:**
54
+
55
+ - Deprecate authenticating resources inside the GQL schema [\#176](https://github.com/graphql-devise/graphql_devise/pull/176) ([mcelicalderon](https://github.com/mcelicalderon))
56
+
57
+ **Merged pull requests:**
58
+
59
+ - Add controller level auth documentation [\#177](https://github.com/graphql-devise/graphql_devise/pull/177) ([mcelicalderon](https://github.com/mcelicalderon))
60
+
3
61
  ## [v0.14.3](https://github.com/graphql-devise/graphql_devise/tree/v0.14.3) (2021-04-28)
4
62
 
5
63
  [Full Changelog](https://github.com/graphql-devise/graphql_devise/compare/v0.14.2...v0.14.3)
data/README.md CHANGED
@@ -8,43 +8,46 @@ GraphQL interface on top of the [Devise Token Auth](https://github.com/lynndylan
8
8
  ## Table of Contents
9
9
 
10
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
- * [Important](#important)
18
- * [Mounting Operations in Your Own Schema (&gt; v0.12.0)](#mounting-operations-in-your-own-schema--v0120)
19
- * [Important](#important-1)
20
- * [Usage](#usage)
21
- * [Mounting Auth Schema on a Separate Route](#mounting-auth-schema-on-a-separate-route)
22
- * [Mounting Operations Into Your Own Schema](#mounting-operations-into-your-own-schema)
23
- * [Available Mount Options](#available-mount-options)
24
- * [Available Operations](#available-operations)
25
- * [Configuring Model](#configuring-model)
26
- * [Email Reconfirmation](#email-reconfirmation)
27
- * [Customizing Email Templates](#customizing-email-templates)
28
- * [I18n](#i18n)
29
- * [Authenticating Controller Actions](#authenticating-controller-actions)
30
- * [Authenticate Before Reaching Your GQL Schema](#authenticate-before-reaching-your-gql-schema)
31
- * [Authenticate in Your GQL Schema](#authenticate-in-your-gql-schema)
32
- * [Important](#important-2)
33
- * [Making Requests](#making-requests)
34
- * [Introspection query](#introspection-query)
35
- * [Mutations](#mutations)
36
- * [Queries](#queries)
37
- * [Reset Password Flow](#reset-password-flow)
38
- * [More Configuration Options](#more-configuration-options)
39
- * [Devise Token Auth Initializer](#devise-token-auth-initializer)
40
- * [Devise Initializer](#devise-initializer)
41
- * [GraphQL Interpreter](#graphql-interpreter)
42
- * [Using Alongside Standard Devise](#using-alongside-standard-devise)
43
- * [Future Work](#future-work)
44
- * [Contributing](#contributing)
45
- * [License](#license)
46
-
47
- <!-- Added by: mcelicalderon, at: Mon Jan 25 22:48:17 -05 2021 -->
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 an Existing Schema (&gt; v0.12.0)](#mounting-operations-in-an-existing-schema--v0120)
18
+ * [Usage](#usage)
19
+ * [Mounting Auth Schema on a Separate Route](#mounting-auth-schema-on-a-separate-route)
20
+ * [Mounting Operations In an Existing Schema](#mounting-operations-in-an-existing-schema)
21
+ * [Available Mount Options](#available-mount-options)
22
+ * [Available Operations](#available-operations)
23
+ * [Configuring Model](#configuring-model)
24
+ * [Email Reconfirmation](#email-reconfirmation)
25
+ * [Current flow](#current-flow)
26
+ * [Deprecated flow - Do Not Use](#deprecated-flow---do-not-use)
27
+ * [Customizing Email Templates](#customizing-email-templates)
28
+ * [I18n](#i18n)
29
+ * [Authenticating Controller Actions](#authenticating-controller-actions)
30
+ * [Authenticate Resource in the Controller (&gt;= v0.15.0)](#authenticate-resource-in-the-controller--v0150)
31
+ * [Authentication Options](#authentication-options)
32
+ * [Authenticate Before Reaching Your GQL Schema (Deprecated)](#authenticate-before-reaching-your-gql-schema-deprecated)
33
+ * [Authenticate in an Existing Schema (Deprecated)](#authenticate-in-an-existing-schema-deprecated)
34
+ * [Authentication Options](#authentication-options-1)
35
+ * [Important](#important)
36
+ * [Making Requests](#making-requests)
37
+ * [Introspection query](#introspection-query)
38
+ * [Mutations](#mutations)
39
+ * [Queries](#queries)
40
+ * [Reset Password Flow](#reset-password-flow)
41
+ * [More Configuration Options](#more-configuration-options)
42
+ * [Devise Token Auth Initializer](#devise-token-auth-initializer)
43
+ * [Devise Initializer](#devise-initializer)
44
+ * [GraphQL Interpreter](#graphql-interpreter)
45
+ * [Using Alongside Standard Devise](#using-alongside-standard-devise)
46
+ * [Future Work](#future-work)
47
+ * [Contributing](#contributing)
48
+ * [License](#license)
49
+
50
+ <!-- Added by: david, at: jue jun 24 18:32:27 -05 2021 -->
48
51
 
49
52
  <!--te-->
50
53
 
@@ -78,11 +81,10 @@ Graphql Devise generator will execute `Devise` and `Devise Token Auth` generator
78
81
  ```bash
79
82
  $ bundle exec rails generate graphql_devise:install
80
83
  ```
81
- The generator accepts 2 params:
84
+ The generator accepts 2 params and 1 option:
82
85
  - `user_class`: Model name in which `Devise` modules will be included. This uses a `find or create` strategy. Defaults to `User`.
83
86
  - `mount_path`: Path in which the dedicated graphql schema for devise will be mounted. Defaults to `/graphql_auth`.
84
-
85
- The option `mount` is available starting from `v0.12.0`. This option will allow you to mount the operations in your own schema instead of a dedicated one. When this option is provided `mount_path` param is not used.
87
+ - `--mount`: This options is available starting from `v0.12.0`, it allows you to mount the operations in your own schema instead of a dedicated one. When provided `mount_path` param is ignored.
86
88
 
87
89
  #### Mounting the Schema in a Separate Route
88
90
 
@@ -100,17 +102,17 @@ Will do the following:
100
102
  - Add `devise` modules to `Admin` model
101
103
  - Other changes that you can find [here](https://devise-token-auth.gitbook.io/devise-token-auth/config)
102
104
  - Add the route to `config/routes.rb`
103
- - `mount_graphql_devise_for 'Admin', at: 'api/auth'`
105
+ - `mount_graphql_devise_for Admin, at: 'api/auth'`
104
106
 
105
107
  `Admin` could be any model name you are going to be using for authentication,
106
108
  and `api/auth` could be any mount path you would like to use for auth.
107
109
 
108
- ##### Important
110
+ **Important**
109
111
  - Remember that by default this gem mounts a completely separate GraphQL schema on a separate controller in the route provided by the `at` option in the `mount_graphql_devise_for` method in the `config/routes.rb` file. If no `at` option is provided, the route will be `/graphql_auth`.
110
- - Avoid passing the `--mount` option or the gem will try to use an existing schema.
112
+ - Avoid passing the `--mount` option if you want to use a separate route and schema.
111
113
 
112
- #### Mounting Operations in Your Own Schema (> v0.12.0)
113
- To configure the gem to use your own GQL schema use the `--mount` option.
114
+ #### Mounting Operations in an Existing Schema (> v0.12.0)
115
+ To configure the gem to use an existing GQL schema use the `--mount` option.
114
116
  For instance the executing:
115
117
 
116
118
  ```bash
@@ -126,8 +128,8 @@ Will do the following:
126
128
  - Add `SchemaPlugin` to the specified schema.
127
129
 
128
130
 
129
- ##### Important
130
- - When using the `--mount` option the `mount_path` params is ignored.
131
+ **Important**
132
+ - When using the `--mount` option the `mount_path` param is ignored.
131
133
  - The generator will look for your schema under `app/graphql/` directory. We are expecting the name of the file is the same as the as the one passed in the mount option transformed with `underscore`. In the example, passing `MySchema`, will try to find the file `app/graphql/my_schema.rb`.
132
134
  - You can actually mount a resource's auth schema in a separate route and in your app's schema at the same time, but that's probably not a common scenario.
133
135
 
@@ -149,13 +151,13 @@ You can mount this gem's GraphQL auth schema in your routes file like this:
149
151
 
150
152
  Rails.application.routes.draw do
151
153
  mount_graphql_devise_for(
152
- 'User',
154
+ User,
153
155
  at: 'api/v1',
154
156
  authenticatable_type: Types::MyCustomUserType,
155
157
  operations: {
156
158
  login: Mutations::Login
157
159
  },
158
- skip: [:sign_up],
160
+ skip: [:register],
159
161
  additional_mutations: {
160
162
  # generates mutation { adminUserSignUp }
161
163
  admin_user_sign_up: Mutations::AdminUserSignUp
@@ -172,10 +174,10 @@ The second argument of the `mount_graphql_devise` method is a hash of options wh
172
174
  customize how the queries and mutations are mounted into the schema. For a list of available
173
175
  options go [here](#available-mount-options)
174
176
 
175
- ### Mounting Operations Into Your Own Schema
177
+ ### Mounting Operations In an Existing Schema
176
178
 
177
- Starting with `v0.12.0` you can now mount the GQL operations provided by this gem into your
178
- app's main schema.
179
+ Starting with `v0.12.0` you can mount the GQL operations provided by this gem into an
180
+ existing schema in you app.
179
181
 
180
182
  ```ruby
181
183
  # app/graphql/dummy_schema.rb
@@ -187,7 +189,7 @@ class DummySchema < GraphQL::Schema
187
189
  query: Types::QueryType,
188
190
  mutation: Types::MutationType,
189
191
  resource_loaders: [
190
- GraphqlDevise::ResourceLoader.new('User', only: [:login, :confirm_account])
192
+ GraphqlDevise::ResourceLoader.new(User, only: [:login, :confirm_registration_with_token])
191
193
  ]
192
194
  )
193
195
 
@@ -242,10 +244,10 @@ this gem's auth operation into your schema, these are the options you can provid
242
244
 
243
245
  ```ruby
244
246
  # Using the mount method in your config/routes.rb file
245
- mount_graphql_devise_for('User', {})
247
+ mount_graphql_devise_for(User, {})
246
248
 
247
249
  # Providing options to a GraphqlDevise::ResourceLoader
248
- GraphqlDevise::ResourceLoader.new('User', {})
250
+ GraphqlDevise::ResourceLoader.new(User, {})
249
251
  ```
250
252
 
251
253
  1. `at`: Route where the GraphQL schema will be mounted on the Rails server.
@@ -295,13 +297,17 @@ The following is a list of the symbols you can provide to the `operations`, `ski
295
297
  ```ruby
296
298
  :login
297
299
  :logout
298
- :sign_up
299
- :confirm_account
300
- :send_password_reset
301
- :check_password_token
302
- :update_password
303
- :send_password_reset_with_token
300
+ :sign_up (deprecated)
301
+ :register
302
+ :update_password (deprecated)
304
303
  :update_password_with_token
304
+ :send_password_reset (deprecated)
305
+ :send_password_reset_with_token
306
+ :resend_confirmation (deprecated)
307
+ :resend_confirmation_with_token
308
+ :confirm_registration_with_token
309
+ :confirm_account (deprecated)
310
+ :check_password_token (deprecated)
305
311
  ```
306
312
 
307
313
  ### Configuring Model
@@ -329,6 +335,9 @@ The install generator can do this for you if you specify the `user_class` option
329
335
  See [Installation](#installation) for details.
330
336
 
331
337
  ### Email Reconfirmation
338
+ We want reconfirmable in this gem to work separately
339
+ from DTA's or Devise (too much complexity in the model based on callbacks).
340
+
332
341
  Email reconfirmation is supported just like in Devise and DTA, but we want reconfirmable
333
342
  in this gem to work on model basis instead of having a global configuration like in Devise.
334
343
  **For this reason Devise's global `reconfirmable` setting is ignored.**
@@ -337,19 +346,39 @@ For a resource to be considered reconfirmable it has to meet 2 conditions:
337
346
  1. Include the `:confirmable` module.
338
347
  1. Has an `unconfirmed_email` column in the resource's table.
339
348
 
340
- In order to trigger the reconfirmation email in a reconfirmable resource, you simply needi
349
+ In order to trigger the reconfirmation email in a reconfirmable resource, you simply need
341
350
  to call a different update method on your resource,`update_with_email`.
342
351
  When the resource is not reconfirmable or the email is not updated, this method behaves exactly
343
352
  the same as ActiveRecord's `update`.
353
+
354
+ #### Current flow
355
+ `update_with_email` requires one additional attribute when email will change or an error
356
+ will be raised:
357
+
358
+ - `confirmation_url`: The full url of your client application. The confirmation email will contain this url plus
359
+ a confirmation token. You need to call `confirmRegistrationWithToken` with the given token on
360
+ your client application.
361
+
362
+ So, it's up to you where you require confirmation of changing emails.
363
+ Here's a demonstration on the method usage:
364
+ ```ruby
365
+ user.update_with_email(
366
+ name: 'New Name',
367
+ email: 'new@domain.com',
368
+ confirmation_url: 'https://google.com'
369
+ )
370
+ ```
371
+
372
+ #### Deprecated flow - Do Not Use
344
373
  `update_with_email` requires two additional attributes when email will change or an error
345
374
  will be raised:
346
375
 
347
- 1. `schema_url`: The full url where your GQL schema is mounted. You can get this value from the
376
+ - `schema_url`: The full url where your GQL schema is mounted. You can get this value from the
348
377
  controller available in the context of your mutations and queries like this:
349
378
  ```ruby
350
379
  context[:controller].full_url_without_params
351
380
  ```
352
- 1. `confirmation_success_url`: This the full url where you want users to be redirected after
381
+ - `confirmation_success_url`: This the full url where you want users to be redirected after
353
382
  the email has changed successfully (usually a front-end url). This value is mandatory
354
383
  unless you have set `default_confirm_success_url` in your devise_token_auth initializer.
355
384
 
@@ -365,9 +394,6 @@ user.update_with_email(
365
394
  )
366
395
  ```
367
396
 
368
- We want reconfirmable in this gem to work separately
369
- from DTA's or Devise (too much complexity in the model based on callbacks).
370
-
371
397
  ### Customizing Email Templates
372
398
  The approach of this gem is a bit different from DeviseTokenAuth. We have placed our templates in `app/views/graphql_devise/mailer`,
373
399
  so if you want to change them, place yours on the same dir structure on your Rails project. You can customize these two templates:
@@ -385,7 +411,75 @@ Keep in mind that if your app uses multiple locales, you should set the `I18n.lo
385
411
  ### Authenticating Controller Actions
386
412
  When mounting the operation is in you own schema instead of a dedicated one, you will need to authenticate users in your controllers, just like in DTA. There are 2 alternatives to accomplish this.
387
413
 
388
- #### Authenticate Before Reaching Your GQL Schema
414
+ #### Authenticate Resource in the Controller (>= v0.15.0)
415
+ This authentication mechanism sets the resource by token in the controller, or it doesn't if credentials are invalid.
416
+ You simply need to pass the return value of our `gql_devise_context` method in the context of your
417
+ GQL schema execution like this:
418
+
419
+ ```ruby
420
+ # app/controllers/my_controller.rb
421
+
422
+ class MyController < ApplicationController
423
+ include GraphqlDevise::Concerns::SetUserByToken
424
+
425
+ def my_action
426
+ result = DummySchema.execute(params[:query], context: gql_devise_context(User))
427
+ render json: result unless performed?
428
+ end
429
+ end
430
+ ```
431
+ `gql_devise_context` receives as many models as you need to authenticate in the request, like this:
432
+ ```ruby
433
+ # app/controllers/my_controller.rb
434
+
435
+ class MyController < ApplicationController
436
+ include GraphqlDevise::Concerns::SetUserByToken
437
+
438
+ def my_action
439
+ result = DummySchema.execute(params[:query], context: gql_devise_context(User, Admin))
440
+ render json: result unless performed?
441
+ end
442
+ end
443
+ ```
444
+ Internally in your own mutations and queries a key `current_resource` will be available in
445
+ the context if a resource was successfully authenticated or `nil` otherwise.
446
+
447
+ Keep in mind that sending multiple models to the `gql_devise_context` method means that depending
448
+ on who makes the request, the context value `current_resource` might contain instances of the
449
+ different models you provided.
450
+
451
+ **Note:** If for any reason you need more control over how users are authenticated, you can use the `authenticate_model`
452
+ method anywhere in your controller. The method will return the authenticated resource or nil if authentication fails.
453
+ It will also set the instance variable `@resource` in the controller.
454
+
455
+ Please note that by using this mechanism your GQL schema will be in control of what queries are
456
+ restricted to authenticated users and you can only do this at the root level fields of your GQL
457
+ schema. Configure the plugin as explained [here](#mounting-operations-into-your-own-schema)
458
+ so this can work.
459
+
460
+ ##### Authentication Options
461
+ Whether you setup authentications as a default in the plugin, or you do it at the field level,
462
+ these are the options you can use:
463
+ 1. **Any truthy value:** If `current_resource` is not `.present?`, query will return an authentication error.
464
+ 1. **A callable object:** Provided object will be called with `current_resource` as the only argument if `current_resource` is `.present?`. If return value of the callable object is false, query will return an authentication error.
465
+
466
+ In your main app's schema this is how you might specify if a field needs to be authenticated or not:
467
+ ```ruby
468
+ module Types
469
+ class QueryType < Types::BaseObject
470
+ # user field used the default set in the Plugin's initializer
471
+ field :user, resolver: Resolvers::UserShow
472
+ # this field will never require authentication
473
+ field :public_field, String, null: false, authenticate: false
474
+ # this field requires authentication
475
+ field :private_field, String, null: false, authenticate: true
476
+ # this field requires authenticated users to also be admins
477
+ field :admin_field, String, null: false, authenticate: ->(user) { user.admin? }
478
+ end
479
+ end
480
+ ```
481
+
482
+ #### Authenticate Before Reaching Your GQL Schema (Deprecated)
389
483
  For this you will need to call `authenticate_<model>!` in a `before_action` controller hook.
390
484
  In our example our model is `User`, so it would look like this:
391
485
  ```ruby
@@ -397,7 +491,7 @@ class MyController < ApplicationController
397
491
  before_action :authenticate_user!
398
492
 
399
493
  def my_action
400
- result = DummySchema.execute(params[:query], context: current_user: current_user)
494
+ result = DummySchema.execute(params[:query], context: { current_resource: current_user })
401
495
  render json: result unless performed?
402
496
  end
403
497
  end
@@ -406,7 +500,7 @@ end
406
500
  The install generator can include the concern in you application controller.
407
501
  If authentication fails for a request, execution will halt and a REST error will be returned since the request never reaches your GQL schema.
408
502
 
409
- #### Authenticate in Your GQL Schema
503
+ #### Authenticate in an Existing Schema (Deprecated)
410
504
  For this you will need to add the `GraphqlDevise::SchemaPlugin` to your schema as described
411
505
  [here](#mounting-operations-into-your-own-schema).
412
506
 
@@ -423,7 +517,7 @@ class MyController < ApplicationController
423
517
  end
424
518
  ```
425
519
  The `graphql_context` method receives a symbol identifying the resource you are trying
426
- to authenticate. So if you mounted the `'User'` resource, the symbol is `:user`. You can use
520
+ to authenticate. So if you mounted the `User` resource, the symbol is `:user`. You can use
427
521
  this snippet to find the symbol for more complex scenarios
428
522
  `resource_klass.to_s.underscore.tr('/', '_').to_sym`. `graphql_context` can also take an
429
523
  array of resources if you mounted more than one into your schema. The gem will try to
@@ -441,7 +535,13 @@ restricted to authenticated users and you can only do this at the root level fie
441
535
  schema. Configure the plugin as explained [here](#mounting-operations-into-your-own-schema)
442
536
  so this can work.
443
537
 
444
- In you main app's schema this is how you might specify if a field needs to be authenticated or not:
538
+ ##### Authentication Options
539
+ Whether you setup authentications as a default in the plugin, or you do it at the field level,
540
+ these are the options you can use:
541
+ 1. **Any truthy value:** If `current_resource` is not `.present?`, query will return an authentication error.
542
+ 1. **A callable object:** Provided object will be called with `current_resource` as the only argument if `current_resource` is `.present?`. If return value of the callable object is false, query will return an authentication error.
543
+
544
+ In your main app's schema this is how you might specify if a field needs to be authenticated or not:
445
545
  ```ruby
446
546
  module Types
447
547
  class QueryType < Types::BaseObject
@@ -451,6 +551,8 @@ module Types
451
551
  field :public_field, String, null: false, authenticate: false
452
552
  # this field requires authentication
453
553
  field :private_field, String, null: false, authenticate: true
554
+ # this field requires authenticated users to also be admins
555
+ field :admin_field, String, null: false, authenticate: ->(user) { user.admin? }
454
556
  end
455
557
  end
456
558
  ```
@@ -468,20 +570,22 @@ If you are using the schema plugin, you can require authentication before doing
468
570
 
469
571
  Operation | Description | Example
470
572
  :--- | :--- | :------------------:
471
- login | This mutation has a second field by default. `credentials` can be fetched directly on the mutation return type.<br>Credentials are still returned in the headers of the response. | userLogin(email: String!, password: String!): UserLoginPayload
472
- logout | | userLogout: UserLogoutPayload
473
- signUp | 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`. | userSignUp(email: String!, password: String!, passwordConfirmation: String!, confirmSuccessUrl: String): UserSignUpPayload
474
- sendPasswordResetWithToken | Sends an email to the provided address with a link to reset the password of the resource. First step of the most recently implemented password reset flow. | userSendPasswordResetWithToken(email: String!, redirectUrl: String!): UserSendPasswordResetWithTokenPayload
475
- updatePasswordWithToken | Uses a `resetPasswordToken` to update the password of a resource. Second and last step of the most recently implemented password reset flow. | userSendPasswordResetWithToken(resetPasswordToken: String!, password: String!, passwordConfirmation: String!): UserUpdatePasswordWithTokenPayload
476
- resendConfirmation | 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 | userResendConfirmation(email: String!, redirectUrl: String!): UserResendConfirmationPayload
477
- sendResetPassword | Sends an email to the provided address with a link to reset the password of the resource. **This mutation is part of the first and soon to be deprecated password reset flow.** | userSendResetPassword(email: String!, redirectUrl: String!): UserSendReserPasswordPayload
478
- updatePassword | The parameter `currentPassword` is optional if you have `config.check_current_password_before_update` set to false (disabled by default) on your generated `config/initializers/devise_token_aut.rb` or if the `resource` 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). **This mutation is part of the first and soon to be deprecated password reset flow.** | userUpdatePassword(password: String!, passwordConfirmation: String!, currentPassword: String): UserUpdatePasswordPayload
573
+ login | This mutation has a second field by default. `credentials` can be fetched directly on the mutation return type.<br>Credentials are still returned in the headers of the response. | userLogin(email: String!, password: String!): UserLoginPayload |
574
+ logout | requires authentication headers. Deletes current session if successful. | userLogout: UserLogoutPayload |
575
+ signUp **(Deprecated)** | 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`. | userSignUp(email: String!, password: String!, passwordConfirmation: String!, confirmSuccessUrl: String): UserSignUpPayload |
576
+ register | The parameter `confirmUrl` 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`. | userRegister(email: String!, password: String!, passwordConfirmation: String!, confirmUrl: String): UserRegisterPayload |
577
+ sendPasswordResetWithToken | Sends an email to the provided address with a link to reset the password of the resource. First step of the most recently implemented password reset flow. | userSendPasswordResetWithToken(email: String!, redirectUrl: String!): UserSendPasswordResetWithTokenPayload |
578
+ updatePasswordWithToken | Uses a `resetPasswordToken` to update the password of a resource. Second and last step of the most recently implemented password reset flow. | userSendPasswordResetWithToken(resetPasswordToken: String!, password: String!, passwordConfirmation: String!): UserUpdatePasswordWithTokenPayload |
579
+ resendConfirmation **(Deprecated)** | The `UserResendConfirmationPayload` will return a `message: String!` that can be used to notify a user what to do after the instructions were sent to them | userResendConfirmation(email: String!, redirectUrl: String!): UserResendConfirmationPayload |
580
+ resendConfirmationWithToken | The `UserResendConfirmationWithTokenPayload` will return a `message: String!` that can be used to notify a user what to do after the instructions were sent to them. Email will contain a link to the provided `confirmUrl` and a `confirmationToken` query param. | userResendConfirmationWithToken(email: String!, confirmUrl: String!): UserResendConfirmationWithTokenPayload |
581
+ sendResetPassword **(Deprecated)** | Sends an email to the provided address with a link to reset the password of the resource. **This mutation is part of the first and soon to be deprecated password reset flow.** | userSendResetPassword(email: String!, redirectUrl: String!): UserSendResetPasswordPayload |
582
+ updatePassword **(Deprecated)** | The parameter `currentPassword` is optional if you have `config.check_current_password_before_update` set to false (disabled by default) on your generated `config/initializers/devise_token_aut.rb` or if the `resource` 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). **This mutation is part of the first and soon to be deprecated password reset flow.** | userUpdatePassword(password: String!, passwordConfirmation: String!, currentPassword: String): UserUpdatePasswordPayload |
479
583
 
480
584
  #### Queries
481
585
  Operation | Description | Example
482
586
  :--- | :--- | :------------------:
483
- confirmAccount | Performs a redirect using the `redirectUrl` param | userConfirmAccount(confirmationToken: String!, redirectUrl: String!): User
484
- checkPasswordToken | Performs a redirect using the `redirectUrl` param | userCheckPasswordToken(resetPasswordToken: String!, redirectUrl: String): User
587
+ confirmAccount **(Deprecated)** | Performs a redirect using the `redirectUrl` param | userConfirmAccount(confirmationToken: String!, redirectUrl: String!): User
588
+ checkPasswordToken **(Deprecated)** | Performs a redirect using the `redirectUrl` param | userCheckPasswordToken(resetPasswordToken: String!, redirectUrl: String): User
485
589
 
486
590
  The reason for having 2 queries is that these 2 are going to be accessed when clicking on
487
591
  the confirmation and reset password email urls. There is no limitation for making mutation