Skip to content

Commit

Permalink
Merge pull request #128 from graphql-devise/ignore-reconfirmable-glob…
Browse files Browse the repository at this point in the history
…al-devise-config

Redefine if a model is reconfirmable per class
  • Loading branch information
mcelicalderon committed Aug 15, 2020
2 parents 1549099 + deb54bc commit 9b606e5
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 26 deletions.
30 changes: 16 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,20 +318,19 @@ The install generator can do this for you if you specify the `user_class` option
See [Installation](#installation) for details.

### Email Reconfirmation
DTA and Devise support email reconfirmation. When the `confirmable` module is added to your
resource, an email is sent to the provided email address when the `signUp` mutation is used.
You can also use this gem so every time a user updates the `email` field, a new email gets sent
for the user to confirm the new email address. Only after clicking on the confirmation link,
the email will be updated on the database to use the new value.

In order to use this feature there are a couple of things to setup first:
1. Make user your model includes the `:confirmable` module.
1. Add an `unconfirmed_email` String column to your resource's table.

After that is done, you simply need to call a different update method on your resource,
`update_with_email`. This method behaves exactly the same as ActiveRecord's `update` method
if the previous steps are not performed, or if you are not updating the `email` attribute.
It is also mandatory to provide two additional attributes when email will change or an error
Email reconfirmation is supported just like in Devise and DTA, but we want reconfirmable
in this gem to work on model basis instead of having a global configuration like in Devise.
**For this reason Devise's global `reconfirmable` setting is ignored.**

For a resource to be considered reconfirmable it has to meet 2 conditions:
1. Include the `:confirmable` module.
1. Has an `unconfirmed_email` column in the resource's table.

In order to trigger the reconfirmation email in a reconfirmable resource, you simply needi
to call a different update method on your resource,`update_with_email`.
When the resource is not reconfirmable or the email is not updated, this method behaves exactly
the same as ActiveRecord's `update`.
`update_with_email` requires two additional attributes when email will change or an error
will be raised:

1. `schema_url`: The full url where your GQL schema is mounted. You can get this value from the
Expand All @@ -355,6 +354,9 @@ user.update_with_email(
)
```

We want reconfirmable in this gem to work separately
from DTA's or Devise (too much complexity in the model based on callbacks).

### Customizing Email Templates
The approach of this gem is a bit different from DeviseTokenAuth. We have placed our templates in `app/views/graphql_devise/mailer`,
so if you want to change them, place yours on the same dir structure on your Rails project. You can customize these two templates:
Expand Down
10 changes: 6 additions & 4 deletions app/models/graphql_devise/concerns/model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ module Concerns
Model = DeviseTokenAuth::Concerns::User

Model.module_eval do
def update_with_email(attributes = {})
GraphqlDevise::Model::WithEmailUpdater.new(self, attributes).call
class_methods do
def reconfirmable
devise_modules.include?(:confirmable) && column_names.include?('unconfirmed_email')
end
end

def pending_reconfirmation?
devise_modules.include?(:confirmable) && try(:unconfirmed_email).present?
def update_with_email(attributes = {})
GraphqlDevise::Model::WithEmailUpdater.new(self, attributes).call
end
end
end
Expand Down
16 changes: 8 additions & 8 deletions spec/requests/mutations/resend_confirmation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
RSpec.describe 'Resend confirmation' do
include_context 'with graphql query request'

let!(:user) { create(:user, confirmed_at: nil, email: 'mwallace@wallaceinc.com') }
let(:email) { user.email }
let(:id) { user.id }
let(:redirect) { Faker::Internet.url }
let(:confirmed_at) { nil }
let!(:user) { create(:user, confirmed_at: nil, email: 'mwallace@wallaceinc.com') }
let(:email) { user.email }
let(:id) { user.id }
let(:redirect) { Faker::Internet.url }
let(:query) do
<<-GRAPHQL
mutation {
Expand Down Expand Up @@ -99,12 +100,11 @@
end

context 'when the email was changed' do
let(:email) { 'new-email@wallaceinc.com' }
let(:new_email) { email }
let(:confirmed_at) { 2.seconds.ago }
let(:email) { 'new-email@wallaceinc.com' }
let(:new_email) { email }

before do
user.class.reconfirmable = true
user.confirm
user.update_with_email(
email: new_email,
schema_url: 'http://localhost/test',
Expand Down

0 comments on commit 9b606e5

Please sign in to comment.