graphql_devise 0.14.3 → 0.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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