graphql_devise 0.15.0 → 0.18.0
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.
- checksums.yaml +4 -4
- data/Appraisals +7 -0
- data/CHANGELOG.md +42 -0
- data/README.md +89 -50
- data/app/views/graphql_devise/mailer/confirmation_instructions.html.erb +7 -1
- data/graphql_devise.gemspec +1 -1
- data/lib/graphql_devise/default_operations/mutations.rb +14 -8
- data/lib/graphql_devise/default_operations/resolvers.rb +2 -2
- data/lib/graphql_devise/model/with_email_updater.rb +34 -8
- data/lib/graphql_devise/mount_method/operation_preparers/default_operation_preparer.rb +1 -1
- data/lib/graphql_devise/mount_method/operation_sanitizer.rb +13 -1
- data/lib/graphql_devise/mutations/confirm_registration_with_token.rb +30 -0
- data/lib/graphql_devise/mutations/login.rb +2 -0
- data/lib/graphql_devise/mutations/register.rb +60 -0
- data/lib/graphql_devise/mutations/resend_confirmation_with_token.rb +44 -0
- data/lib/graphql_devise/mutations/sign_up.rb +1 -1
- data/lib/graphql_devise/schema_plugin.rb +6 -2
- data/lib/graphql_devise/version.rb +1 -1
- data/spec/dummy/app/graphql/dummy_schema.rb +4 -3
- data/spec/dummy/app/graphql/mutations/register.rb +14 -0
- data/spec/dummy/app/graphql/types/query_type.rb +5 -0
- data/spec/dummy/config/routes.rb +5 -4
- data/spec/dummy/db/migrate/20210516211417_add_vip_to_users.rb +5 -0
- data/spec/dummy/db/schema.rb +4 -3
- data/spec/graphql_devise/model/with_email_updater_spec.rb +97 -68
- data/spec/requests/mutations/confirm_registration_with_token_spec.rb +117 -0
- data/spec/requests/mutations/register_spec.rb +166 -0
- data/spec/requests/mutations/resend_confirmation_with_token_spec.rb +137 -0
- data/spec/requests/user_controller_spec.rb +71 -30
- data/spec/services/mount_method/operation_sanitizer_spec.rb +3 -3
- metadata +18 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a59e0e9162a90d33da8e0d9738c6960db2286acd49db59d85bdc4c352402205b
|
|
4
|
+
data.tar.gz: c1255d172a2825dcc54f21f68151a64985346f2f2e3d4b236a77ff8ce40c40e4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2df583c0be8b0df69c62c5663b7176a54b0e762b4800bdb01b6f90f8835446878fb7c45a5722f78a45a5903681e946c167f80d9d8b7cc23dfc872b7a956ec187
|
|
7
|
+
data.tar.gz: ae453c594be804358d5dec8a3f8f0526867352b2f77346e42c1c2ccab093df22d9c3f520b70e5e680afd292ab8d316efae3004f4555e4e0ac975e09b7ee0eb5d
|
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,47 @@
|
|
|
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
|
+
|
|
3
45
|
## [v0.15.0](https://github.com/graphql-devise/graphql_devise/tree/v0.15.0) (2021-05-09)
|
|
4
46
|
|
|
5
47
|
[Full Changelog](https://github.com/graphql-devise/graphql_devise/compare/v0.14.3...v0.15.0)
|
data/README.md
CHANGED
|
@@ -14,23 +14,25 @@ GraphQL interface on top of the [Devise Token Auth](https://github.com/lynndylan
|
|
|
14
14
|
* [Installation](#installation)
|
|
15
15
|
* [Running the Generator](#running-the-generator)
|
|
16
16
|
* [Mounting the Schema in a Separate Route](#mounting-the-schema-in-a-separate-route)
|
|
17
|
-
|
|
18
|
-
* [Mounting Operations in Your Own Schema (> v0.12.0)](#mounting-operations-in-your-own-schema--v0120)
|
|
19
|
-
* [Important](#important-1)
|
|
17
|
+
* [Mounting Operations in an Existing Schema (> v0.12.0)](#mounting-operations-in-an-existing-schema--v0120)
|
|
20
18
|
* [Usage](#usage)
|
|
21
19
|
* [Mounting Auth Schema on a Separate Route](#mounting-auth-schema-on-a-separate-route)
|
|
22
|
-
* [Mounting Operations
|
|
20
|
+
* [Mounting Operations In an Existing Schema](#mounting-operations-in-an-existing-schema)
|
|
23
21
|
* [Available Mount Options](#available-mount-options)
|
|
24
22
|
* [Available Operations](#available-operations)
|
|
25
23
|
* [Configuring Model](#configuring-model)
|
|
26
24
|
* [Email Reconfirmation](#email-reconfirmation)
|
|
25
|
+
* [Current flow](#current-flow)
|
|
26
|
+
* [Deprecated flow - Do Not Use](#deprecated-flow---do-not-use)
|
|
27
27
|
* [Customizing Email Templates](#customizing-email-templates)
|
|
28
28
|
* [I18n](#i18n)
|
|
29
29
|
* [Authenticating Controller Actions](#authenticating-controller-actions)
|
|
30
30
|
* [Authenticate Resource in the Controller (>= v0.15.0)](#authenticate-resource-in-the-controller--v0150)
|
|
31
|
+
* [Authentication Options](#authentication-options)
|
|
31
32
|
* [Authenticate Before Reaching Your GQL Schema (Deprecated)](#authenticate-before-reaching-your-gql-schema-deprecated)
|
|
32
|
-
* [Authenticate in
|
|
33
|
-
|
|
33
|
+
* [Authenticate in an Existing Schema (Deprecated)](#authenticate-in-an-existing-schema-deprecated)
|
|
34
|
+
* [Authentication Options](#authentication-options-1)
|
|
35
|
+
* [Important](#important)
|
|
34
36
|
* [Making Requests](#making-requests)
|
|
35
37
|
* [Introspection query](#introspection-query)
|
|
36
38
|
* [Mutations](#mutations)
|
|
@@ -45,7 +47,7 @@ GraphQL interface on top of the [Devise Token Auth](https://github.com/lynndylan
|
|
|
45
47
|
* [Contributing](#contributing)
|
|
46
48
|
* [License](#license)
|
|
47
49
|
|
|
48
|
-
<!-- Added by:
|
|
50
|
+
<!-- Added by: david, at: jue jun 24 18:32:27 -05 2021 -->
|
|
49
51
|
|
|
50
52
|
<!--te-->
|
|
51
53
|
|
|
@@ -79,11 +81,10 @@ Graphql Devise generator will execute `Devise` and `Devise Token Auth` generator
|
|
|
79
81
|
```bash
|
|
80
82
|
$ bundle exec rails generate graphql_devise:install
|
|
81
83
|
```
|
|
82
|
-
The generator accepts 2 params:
|
|
84
|
+
The generator accepts 2 params and 1 option:
|
|
83
85
|
- `user_class`: Model name in which `Devise` modules will be included. This uses a `find or create` strategy. Defaults to `User`.
|
|
84
86
|
- `mount_path`: Path in which the dedicated graphql schema for devise will be mounted. Defaults to `/graphql_auth`.
|
|
85
|
-
|
|
86
|
-
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.
|
|
87
88
|
|
|
88
89
|
#### Mounting the Schema in a Separate Route
|
|
89
90
|
|
|
@@ -106,12 +107,12 @@ Will do the following:
|
|
|
106
107
|
`Admin` could be any model name you are going to be using for authentication,
|
|
107
108
|
and `api/auth` could be any mount path you would like to use for auth.
|
|
108
109
|
|
|
109
|
-
|
|
110
|
+
**Important**
|
|
110
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`.
|
|
111
|
-
- Avoid passing the `--mount` option
|
|
112
|
+
- Avoid passing the `--mount` option if you want to use a separate route and schema.
|
|
112
113
|
|
|
113
|
-
#### Mounting Operations in
|
|
114
|
-
To configure the gem to use
|
|
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.
|
|
115
116
|
For instance the executing:
|
|
116
117
|
|
|
117
118
|
```bash
|
|
@@ -127,8 +128,8 @@ Will do the following:
|
|
|
127
128
|
- Add `SchemaPlugin` to the specified schema.
|
|
128
129
|
|
|
129
130
|
|
|
130
|
-
|
|
131
|
-
- When using the `--mount` option the `mount_path`
|
|
131
|
+
**Important**
|
|
132
|
+
- When using the `--mount` option the `mount_path` param is ignored.
|
|
132
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`.
|
|
133
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.
|
|
134
135
|
|
|
@@ -156,7 +157,7 @@ Rails.application.routes.draw do
|
|
|
156
157
|
operations: {
|
|
157
158
|
login: Mutations::Login
|
|
158
159
|
},
|
|
159
|
-
skip: [:
|
|
160
|
+
skip: [:register],
|
|
160
161
|
additional_mutations: {
|
|
161
162
|
# generates mutation { adminUserSignUp }
|
|
162
163
|
admin_user_sign_up: Mutations::AdminUserSignUp
|
|
@@ -173,10 +174,10 @@ The second argument of the `mount_graphql_devise` method is a hash of options wh
|
|
|
173
174
|
customize how the queries and mutations are mounted into the schema. For a list of available
|
|
174
175
|
options go [here](#available-mount-options)
|
|
175
176
|
|
|
176
|
-
### Mounting Operations
|
|
177
|
+
### Mounting Operations In an Existing Schema
|
|
177
178
|
|
|
178
|
-
Starting with `v0.12.0` you can
|
|
179
|
-
|
|
179
|
+
Starting with `v0.12.0` you can mount the GQL operations provided by this gem into an
|
|
180
|
+
existing schema in you app.
|
|
180
181
|
|
|
181
182
|
```ruby
|
|
182
183
|
# app/graphql/dummy_schema.rb
|
|
@@ -188,7 +189,7 @@ class DummySchema < GraphQL::Schema
|
|
|
188
189
|
query: Types::QueryType,
|
|
189
190
|
mutation: Types::MutationType,
|
|
190
191
|
resource_loaders: [
|
|
191
|
-
GraphqlDevise::ResourceLoader.new(User, only: [:login, :
|
|
192
|
+
GraphqlDevise::ResourceLoader.new(User, only: [:login, :confirm_registration_with_token])
|
|
192
193
|
]
|
|
193
194
|
)
|
|
194
195
|
|
|
@@ -296,13 +297,17 @@ The following is a list of the symbols you can provide to the `operations`, `ski
|
|
|
296
297
|
```ruby
|
|
297
298
|
:login
|
|
298
299
|
:logout
|
|
299
|
-
:sign_up
|
|
300
|
-
:
|
|
301
|
-
:
|
|
302
|
-
:check_password_token
|
|
303
|
-
:update_password
|
|
304
|
-
:send_password_reset_with_token
|
|
300
|
+
:sign_up (deprecated)
|
|
301
|
+
:register
|
|
302
|
+
:update_password (deprecated)
|
|
305
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)
|
|
306
311
|
```
|
|
307
312
|
|
|
308
313
|
### Configuring Model
|
|
@@ -330,6 +335,9 @@ The install generator can do this for you if you specify the `user_class` option
|
|
|
330
335
|
See [Installation](#installation) for details.
|
|
331
336
|
|
|
332
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
|
+
|
|
333
341
|
Email reconfirmation is supported just like in Devise and DTA, but we want reconfirmable
|
|
334
342
|
in this gem to work on model basis instead of having a global configuration like in Devise.
|
|
335
343
|
**For this reason Devise's global `reconfirmable` setting is ignored.**
|
|
@@ -338,19 +346,39 @@ For a resource to be considered reconfirmable it has to meet 2 conditions:
|
|
|
338
346
|
1. Include the `:confirmable` module.
|
|
339
347
|
1. Has an `unconfirmed_email` column in the resource's table.
|
|
340
348
|
|
|
341
|
-
In order to trigger the reconfirmation email in a reconfirmable resource, you simply
|
|
349
|
+
In order to trigger the reconfirmation email in a reconfirmable resource, you simply need
|
|
342
350
|
to call a different update method on your resource,`update_with_email`.
|
|
343
351
|
When the resource is not reconfirmable or the email is not updated, this method behaves exactly
|
|
344
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
|
|
345
373
|
`update_with_email` requires two additional attributes when email will change or an error
|
|
346
374
|
will be raised:
|
|
347
375
|
|
|
348
|
-
|
|
376
|
+
- `schema_url`: The full url where your GQL schema is mounted. You can get this value from the
|
|
349
377
|
controller available in the context of your mutations and queries like this:
|
|
350
378
|
```ruby
|
|
351
379
|
context[:controller].full_url_without_params
|
|
352
380
|
```
|
|
353
|
-
|
|
381
|
+
- `confirmation_success_url`: This the full url where you want users to be redirected after
|
|
354
382
|
the email has changed successfully (usually a front-end url). This value is mandatory
|
|
355
383
|
unless you have set `default_confirm_success_url` in your devise_token_auth initializer.
|
|
356
384
|
|
|
@@ -366,9 +394,6 @@ user.update_with_email(
|
|
|
366
394
|
)
|
|
367
395
|
```
|
|
368
396
|
|
|
369
|
-
We want reconfirmable in this gem to work separately
|
|
370
|
-
from DTA's or Devise (too much complexity in the model based on callbacks).
|
|
371
|
-
|
|
372
397
|
### Customizing Email Templates
|
|
373
398
|
The approach of this gem is a bit different from DeviseTokenAuth. We have placed our templates in `app/views/graphql_devise/mailer`,
|
|
374
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:
|
|
@@ -432,7 +457,13 @@ restricted to authenticated users and you can only do this at the root level fie
|
|
|
432
457
|
schema. Configure the plugin as explained [here](#mounting-operations-into-your-own-schema)
|
|
433
458
|
so this can work.
|
|
434
459
|
|
|
435
|
-
|
|
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:
|
|
436
467
|
```ruby
|
|
437
468
|
module Types
|
|
438
469
|
class QueryType < Types::BaseObject
|
|
@@ -442,13 +473,11 @@ module Types
|
|
|
442
473
|
field :public_field, String, null: false, authenticate: false
|
|
443
474
|
# this field requires authentication
|
|
444
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? }
|
|
445
478
|
end
|
|
446
479
|
end
|
|
447
480
|
```
|
|
448
|
-
**Important:** Currently, the only check the plugin does to see if the user is authenticated or not when executing
|
|
449
|
-
the query, is verifying that `context[:current_resource].present?` in the GraphQL context.
|
|
450
|
-
So, be careful not to populate that key of the context with values other than what `gql_devise_context`
|
|
451
|
-
returns. The option to do more complex verifications will be added in the future.
|
|
452
481
|
|
|
453
482
|
#### Authenticate Before Reaching Your GQL Schema (Deprecated)
|
|
454
483
|
For this you will need to call `authenticate_<model>!` in a `before_action` controller hook.
|
|
@@ -471,7 +500,7 @@ end
|
|
|
471
500
|
The install generator can include the concern in you application controller.
|
|
472
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.
|
|
473
502
|
|
|
474
|
-
#### Authenticate in
|
|
503
|
+
#### Authenticate in an Existing Schema (Deprecated)
|
|
475
504
|
For this you will need to add the `GraphqlDevise::SchemaPlugin` to your schema as described
|
|
476
505
|
[here](#mounting-operations-into-your-own-schema).
|
|
477
506
|
|
|
@@ -506,7 +535,13 @@ restricted to authenticated users and you can only do this at the root level fie
|
|
|
506
535
|
schema. Configure the plugin as explained [here](#mounting-operations-into-your-own-schema)
|
|
507
536
|
so this can work.
|
|
508
537
|
|
|
509
|
-
|
|
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:
|
|
510
545
|
```ruby
|
|
511
546
|
module Types
|
|
512
547
|
class QueryType < Types::BaseObject
|
|
@@ -516,6 +551,8 @@ module Types
|
|
|
516
551
|
field :public_field, String, null: false, authenticate: false
|
|
517
552
|
# this field requires authentication
|
|
518
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? }
|
|
519
556
|
end
|
|
520
557
|
end
|
|
521
558
|
```
|
|
@@ -533,20 +570,22 @@ If you are using the schema plugin, you can require authentication before doing
|
|
|
533
570
|
|
|
534
571
|
Operation | Description | Example
|
|
535
572
|
:--- | :--- | :------------------:
|
|
536
|
-
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
|
|
537
|
-
logout | | userLogout: UserLogoutPayload
|
|
538
|
-
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
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
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 |
|
|
544
583
|
|
|
545
584
|
#### Queries
|
|
546
585
|
Operation | Description | Example
|
|
547
586
|
:--- | :--- | :------------------:
|
|
548
|
-
confirmAccount | Performs a redirect using the `redirectUrl` param | userConfirmAccount(confirmationToken: String!, redirectUrl: String!): User
|
|
549
|
-
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
|
|
550
589
|
|
|
551
590
|
The reason for having 2 queries is that these 2 are going to be accessed when clicking on
|
|
552
591
|
the confirmation and reset password email urls. There is no limitation for making mutation
|
|
@@ -2,4 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
<p><%= t('.confirm_link_msg') %></p>
|
|
4
4
|
|
|
5
|
-
<p
|
|
5
|
+
<p>
|
|
6
|
+
<% if message['schema_url'].present? %>
|
|
7
|
+
<%= link_to t('.confirm_account_link'), "#{message['schema_url']}?#{confirmation_query(resource_name: @resource.class.to_s, redirect_url: message['redirect-url'], token: @token).to_query}" %>
|
|
8
|
+
<% else %>
|
|
9
|
+
<%= link_to t('.confirm_account_link'), "#{CGI.escape(message['redirect-url'].to_s)}?#{{ confirmationToken: @token }.to_query}" %>
|
|
10
|
+
<% end %>
|
|
11
|
+
</p>
|
data/graphql_devise.gemspec
CHANGED
|
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
|
|
|
28
28
|
spec.required_ruby_version = '>= 2.2.0'
|
|
29
29
|
|
|
30
30
|
spec.add_dependency 'devise_token_auth', '>= 0.1.43', '< 2.0'
|
|
31
|
-
spec.add_dependency 'graphql', '>= 1.8', '< 1.
|
|
31
|
+
spec.add_dependency 'graphql', '>= 1.8', '< 1.14.0'
|
|
32
32
|
spec.add_dependency 'rails', '>= 4.2', '< 6.2'
|
|
33
33
|
|
|
34
34
|
spec.add_development_dependency 'appraisal'
|
|
@@ -4,23 +4,29 @@ require 'graphql_devise/mutations/base'
|
|
|
4
4
|
require 'graphql_devise/mutations/login'
|
|
5
5
|
require 'graphql_devise/mutations/logout'
|
|
6
6
|
require 'graphql_devise/mutations/resend_confirmation'
|
|
7
|
+
require 'graphql_devise/mutations/resend_confirmation_with_token'
|
|
7
8
|
require 'graphql_devise/mutations/send_password_reset'
|
|
8
9
|
require 'graphql_devise/mutations/send_password_reset_with_token'
|
|
9
10
|
require 'graphql_devise/mutations/sign_up'
|
|
11
|
+
require 'graphql_devise/mutations/register'
|
|
10
12
|
require 'graphql_devise/mutations/update_password'
|
|
11
13
|
require 'graphql_devise/mutations/update_password_with_token'
|
|
14
|
+
require 'graphql_devise/mutations/confirm_registration_with_token'
|
|
12
15
|
|
|
13
16
|
module GraphqlDevise
|
|
14
17
|
module DefaultOperations
|
|
15
18
|
MUTATIONS = {
|
|
16
|
-
login:
|
|
17
|
-
logout:
|
|
18
|
-
sign_up:
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
login: { klass: GraphqlDevise::Mutations::Login, authenticatable: true },
|
|
20
|
+
logout: { klass: GraphqlDevise::Mutations::Logout, authenticatable: true },
|
|
21
|
+
sign_up: { klass: GraphqlDevise::Mutations::SignUp, authenticatable: true, deprecation_reason: 'use register instead' },
|
|
22
|
+
register: { klass: GraphqlDevise::Mutations::Register, authenticatable: true },
|
|
23
|
+
update_password: { klass: GraphqlDevise::Mutations::UpdatePassword, authenticatable: true, deprecation_reason: 'use update_password_with_token instead' },
|
|
24
|
+
update_password_with_token: { klass: GraphqlDevise::Mutations::UpdatePasswordWithToken, authenticatable: true },
|
|
25
|
+
send_password_reset: { klass: GraphqlDevise::Mutations::SendPasswordReset, authenticatable: false, deprecation_reason: 'use send_password_reset_with_token instead' },
|
|
26
|
+
send_password_reset_with_token: { klass: GraphqlDevise::Mutations::SendPasswordResetWithToken, authenticatable: false },
|
|
27
|
+
resend_confirmation: { klass: GraphqlDevise::Mutations::ResendConfirmation, authenticatable: false, deprecation_reason: 'use resend_confirmation_with_token instead' },
|
|
28
|
+
resend_confirmation_with_token: { klass: GraphqlDevise::Mutations::ResendConfirmationWithToken, authenticatable: false },
|
|
29
|
+
confirm_registration_with_token: { klass: GraphqlDevise::Mutations::ConfirmRegistrationWithToken, authenticatable: true }
|
|
24
30
|
}.freeze
|
|
25
31
|
end
|
|
26
32
|
end
|
|
@@ -7,8 +7,8 @@ require 'graphql_devise/resolvers/confirm_account'
|
|
|
7
7
|
module GraphqlDevise
|
|
8
8
|
module DefaultOperations
|
|
9
9
|
QUERIES = {
|
|
10
|
-
confirm_account: { klass: GraphqlDevise::Resolvers::ConfirmAccount },
|
|
11
|
-
check_password_token: { klass: GraphqlDevise::Resolvers::CheckPasswordToken }
|
|
10
|
+
confirm_account: { klass: GraphqlDevise::Resolvers::ConfirmAccount, deprecation_reason: 'use the new confirmation flow as it does not require this query anymore' },
|
|
11
|
+
check_password_token: { klass: GraphqlDevise::Resolvers::CheckPasswordToken, deprecation_reason: 'use the new password reset flow as it does not require this query anymore' }
|
|
12
12
|
}.freeze
|
|
13
13
|
end
|
|
14
14
|
end
|
|
@@ -4,12 +4,14 @@ module GraphqlDevise
|
|
|
4
4
|
module Model
|
|
5
5
|
class WithEmailUpdater
|
|
6
6
|
def initialize(resource, attributes)
|
|
7
|
-
@attributes = attributes
|
|
7
|
+
@attributes = attributes.with_indifferent_access
|
|
8
8
|
@resource = resource
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def call
|
|
12
|
-
|
|
12
|
+
check_deprecated_attributes
|
|
13
|
+
|
|
14
|
+
resource_attributes = @attributes.except(:schema_url, :confirmation_success_url, :confirmation_url)
|
|
13
15
|
return @resource.update(resource_attributes) unless requires_reconfirmation?(resource_attributes)
|
|
14
16
|
|
|
15
17
|
@resource.assign_attributes(resource_attributes)
|
|
@@ -27,16 +29,31 @@ module GraphqlDevise
|
|
|
27
29
|
else
|
|
28
30
|
raise(
|
|
29
31
|
GraphqlDevise::Error,
|
|
30
|
-
'Method `update_with_email` requires
|
|
32
|
+
'Method `update_with_email` requires attribute `confirmation_url` for email reconfirmation to work'
|
|
31
33
|
)
|
|
32
34
|
end
|
|
33
35
|
end
|
|
34
36
|
|
|
35
37
|
private
|
|
36
38
|
|
|
39
|
+
def check_deprecated_attributes
|
|
40
|
+
if [@attributes[:schema_url], @attributes[:confirmation_success_url]].any?(&:present?)
|
|
41
|
+
ActiveSupport::Deprecation.warn(<<-DEPRECATION.strip_heredoc, caller)
|
|
42
|
+
Providing `schema_url` and `confirmation_success_url` to `update_with_email` is deprecated and will be
|
|
43
|
+
removed in a future version of this gem.
|
|
44
|
+
|
|
45
|
+
Now you must only provide `confirmation_url` and the email will contain the new format of the confirmation
|
|
46
|
+
url that needs to be used with the new `confirmRegistrationWithToken` on the client application.
|
|
47
|
+
DEPRECATION
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
37
51
|
def required_reconfirm_attributes?
|
|
38
|
-
@attributes[:schema_url].present?
|
|
39
|
-
|
|
52
|
+
if @attributes[:schema_url].present?
|
|
53
|
+
[@attributes[:confirmation_success_url], DeviseTokenAuth.default_confirm_success_url].any?(&:present?)
|
|
54
|
+
else
|
|
55
|
+
[@attributes[:confirmation_url], DeviseTokenAuth.default_confirm_success_url].any?(&:present?)
|
|
56
|
+
end
|
|
40
57
|
end
|
|
41
58
|
|
|
42
59
|
def requires_reconfirmation?(resource_attributes)
|
|
@@ -60,13 +77,22 @@ module GraphqlDevise
|
|
|
60
77
|
end
|
|
61
78
|
end
|
|
62
79
|
|
|
80
|
+
def confirmation_method_params
|
|
81
|
+
if @attributes[:schema_url].present?
|
|
82
|
+
{
|
|
83
|
+
redirect_url: @attributes[:confirmation_success_url] || DeviseTokenAuth.default_confirm_success_url,
|
|
84
|
+
schema_url: @attributes[:schema_url]
|
|
85
|
+
}
|
|
86
|
+
else
|
|
87
|
+
{ redirect_url: @attributes[:confirmation_url] || DeviseTokenAuth.default_confirm_success_url }
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
63
91
|
def send_confirmation_instructions(saved)
|
|
64
92
|
return unless saved
|
|
65
93
|
|
|
66
94
|
@resource.send_confirmation_instructions(
|
|
67
|
-
|
|
68
|
-
template_path: ['graphql_devise/mailer'],
|
|
69
|
-
schema_url: @attributes[:schema_url]
|
|
95
|
+
confirmation_method_params.merge(template_path: ['graphql_devise/mailer'])
|
|
70
96
|
)
|
|
71
97
|
end
|
|
72
98
|
end
|
|
@@ -17,7 +17,7 @@ module GraphqlDevise
|
|
|
17
17
|
@selected_operations.except(*@custom_keys).each_with_object({}) do |(action, operation_info), result|
|
|
18
18
|
mapped_action = "#{mapping_name}_#{action}"
|
|
19
19
|
operation = operation_info[:klass]
|
|
20
|
-
options = operation_info.except(:klass)
|
|
20
|
+
options = operation_info.except(:klass, :deprecation_reason)
|
|
21
21
|
|
|
22
22
|
result[mapped_action.to_sym] = [
|
|
23
23
|
OperationPreparers::GqlNameSetter.new(mapped_action),
|
|
@@ -18,13 +18,25 @@ module GraphqlDevise
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def call
|
|
21
|
-
if @only.present?
|
|
21
|
+
operations = if @only.present?
|
|
22
22
|
@default.slice(*@only)
|
|
23
23
|
elsif @skipped.present?
|
|
24
24
|
@default.except(*@skipped)
|
|
25
25
|
else
|
|
26
26
|
@default
|
|
27
27
|
end
|
|
28
|
+
|
|
29
|
+
operations.each do |operation, values|
|
|
30
|
+
next if values[:deprecation_reason].blank?
|
|
31
|
+
|
|
32
|
+
ActiveSupport::Deprecation.warn(<<-DEPRECATION.strip_heredoc, caller)
|
|
33
|
+
`#{operation}` is deprecated and will be removed in a future version of this gem.
|
|
34
|
+
#{values[:deprecation_reason]}
|
|
35
|
+
|
|
36
|
+
You can supress this message by skipping `#{operation}` on your ResourceLoader or the
|
|
37
|
+
mount_graphql_devise_for method on your routes file.
|
|
38
|
+
DEPRECATION
|
|
39
|
+
end
|
|
28
40
|
end
|
|
29
41
|
end
|
|
30
42
|
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GraphqlDevise
|
|
4
|
+
module Mutations
|
|
5
|
+
class ConfirmRegistrationWithToken < Base
|
|
6
|
+
argument :confirmation_token, String, required: true
|
|
7
|
+
|
|
8
|
+
field :credentials,
|
|
9
|
+
GraphqlDevise::Types::CredentialType,
|
|
10
|
+
null: true,
|
|
11
|
+
description: 'Authentication credentials. Null unless user is signed in after confirmation.'
|
|
12
|
+
|
|
13
|
+
def resolve(confirmation_token:)
|
|
14
|
+
resource = resource_class.confirm_by_token(confirmation_token)
|
|
15
|
+
|
|
16
|
+
if resource.errors.empty?
|
|
17
|
+
yield resource if block_given?
|
|
18
|
+
|
|
19
|
+
response_payload = { authenticatable: resource }
|
|
20
|
+
|
|
21
|
+
response_payload[:credentials] = set_auth_headers(resource) if resource.active_for_authentication?
|
|
22
|
+
|
|
23
|
+
response_payload
|
|
24
|
+
else
|
|
25
|
+
raise_user_error(I18n.t('graphql_devise.confirmations.invalid_token'))
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|