Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ GraphQL interface on top of the [Devise Token Auth](https://github.com/lynndylan
* [Making Requests](#making-requests)
* [Mutations](#mutations)
* [Queries](#queries)
* [Reset Password Flow](#reset-password-flow)
* [More Configuration Options](#more-configuration-options)
* [Devise Token Auth Initializer](#devise-token-auth-initializer)
* [Devise Initializer](#devise-initializer)
Expand All @@ -42,7 +43,7 @@ GraphQL interface on top of the [Devise Token Auth](https://github.com/lynndylan
* [Contributing](#contributing)
* [License](#license)

<!-- Added by: david, at: mar jul 14 08:08:02 -05 2020 -->
<!-- Added by: mcelicalderon, at: Mon Jan 25 22:48:17 -05 2021 -->

<!--te-->

Expand Down Expand Up @@ -288,10 +289,12 @@ The following is a list of the symbols you can provide to the `operations`, `ski
:login
:logout
:sign_up
:update_password
:send_password_reset
:confirm_account
:send_password_reset
:check_password_token
:update_password
:send_password_reset_with_token
:update_password_with_token
```

### Configuring Model
Expand Down Expand Up @@ -458,9 +461,11 @@ Operation | Description | Example
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
logout | | userLogout: UserLogoutPayload
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
sendResetPassword | | userSendResetPassword(email: String!, redirectUrl: String!): UserSendReserPasswordPayload
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). | userUpdatePassword(password: String!, passwordConfirmation: String!, currentPassword: String): UserUpdatePasswordPayload
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
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
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
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
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

#### Queries
Operation | Description | Example
Expand All @@ -478,6 +483,11 @@ you can use [our specs](spec/requests) to better understand how to use the gem.
Also, the [dummy app](spec/dummy) used in our specs will give you
a clear idea on how to configure the gem on your Rails application.

### Reset Password Flow
This gem supports two password recovery flows. The most recently implemented is preferred and
requires less steps. More detail on how it works can be found
[here](docs/usage/reset_password_flow.md).

### More Configuration Options
As mentioned in the introduction there are many configurations that will change how this gem behaves. You can change
this values on the initializer files generated by the installer.
Expand Down
90 changes: 90 additions & 0 deletions docs/usage/reset_password_flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Reset Password Flow
This gem supports two different ways to reset a password on a resource. Each password reset flow has it's own set of
operations and this document will explain in more detail how to use each.
The first and most recently implemented flow is preferred as it requires less steps and doesn't require a mutation
to return a redirect on the response. Flow 2 might be deprecated in the future.

## Flow #1 (Preferred)
This flow only has two steps. Each step name refers to the operation name you can use in the mount options to skip or override.

### 1. send_password_reset_with_token
This mutation will send an email to the specified address if it's found on the system. Returns an error if the email is not found. Here's an example assuming the resource used
for authentication is `User`:
```graphql
mutation {
userSendPasswordResetWithToken(
email: "vvega@wallaceinc.com",
redirectUrl: "https://google.com"
) {
message
}
}
```
The email will contain a link to the `redirectUrl` (https://google.com in the example) and append a `reset_password_token` query param. This is the token you will
need to use in the next step in order to reset the password.

### 2. update_password_with_token
This mutation uses the token sent on the email to find the resource you are trying to recover.
All you have to do is send a valid token together with the new password and password confirmation.
Here's an example assuming the resource used for authentication is `User`:

```graphql
mutation {
userUpdatePasswordWithToken(
resetPasswordToken: "token_here",
password: "password123",
passwordConfirmation: "password123"
) {
authenticatable { email }
credentials { accessToken }
}
}
```
The mutation has two fields:
1. `authenticatable`: Just like other mutations, returns the actual resource you just recover the password for.
1. `credentials`: This is a nullable field. It will only return credentials as if you had just logged
in into the app if you explicitly say so by overriding the mutation. The docs have more detail
on how to extend the default behavior of mutations, but
[here](https://github.com/graphql-devise/graphql_devise/blob/8c7c8a5ff1b35fb026e4c9499c70dc5f90b9187a/spec/dummy/app/graphql/mutations/reset_admin_password_with_token.rb)
you can find an example mutation on what needs to be done in order for the mutation to return
credentials after updating the password.

## Flow 2 (Deprecated)
This was the first flow to be implemented, requires an additional step and also to encode a GQL query in a url, so this is not the preferred method.
Each step name refers to the operation name you can use in the mount options to skip or override.

### 1. send_password_reset
This mutation will send an email to the specified address if it's found on the system. Returns an error if the email is not found. Here's an example assuming the resource used
for authentication is `User`:
```graphql
mutation {
userSendPasswordReset(
email: "vvega@wallaceinc.com",
redirectUrl: "https://google.com"
) {
message
}
}
```
The email will contain an encoded GraphQL query that holds the reset token and redirectUrl.
The query is described in the next step.

### 2. check_password_token
This query checks the reset password token and if successful changes a column in the DB (`allow_password_change`) to true.
This change will allow for the next step to update the password without providing the current password.
Then, this query will redirect to the provided `redirectUrl` with credentials.

### 3. update_password
This step requires the request to include authentication headers and will allow the user to
update the password if step 2 was successful.
Here's an example assuming the resource used for authentication is `User`:
```graphql
mutation {
userUpdatePassword(
password: "password123",
passwordConfirmation: "password123"
) {
authenticatable { email }
}
}
```