Skip to content

Commit 256d9c9

Browse files
authored
Fix/reset password flow doco (#511)
* doco changes for forgot password flow * add information re server side config to allow PathLocationStrategy redirects flow through server without getting additional token added
1 parent c64ac59 commit 256d9c9

File tree

1 file changed

+34
-5
lines changed

1 file changed

+34
-5
lines changed

docs/session-management.md

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,11 @@ a user changing their password while they are already logged in and a "forgot pa
8989

9090
For a normal password update, you need to send the new password twice, for confirmation and you may also have to send the current password for extra security. The setting "check_current_password_before_update" in the Devise Token Auth library is used to control if the current password is required or not.
9191

92-
For the reset password flow where the user is not logged in, this library does not currently support a password update via this updatePassword call. This is because an update password call in that scenario requires the auth headers to be created from the query strings in the redirected URL sent from the server once the email reset link is clicked. You will need to provide this functionality yourself and use the .request() method below to send a PUT to the password endpoint with the correct headers. Your code should copy over the client_id, expiry, token and uid query string values from the redirected URL into their respective header properties.
92+
For the "forgot password" flow where the user is not logged in, review the .resetPassword() documentation below to understand how .updatePassword() fits into that flow. This library's updatePassword() in a "forgot password" flow is known to work with Angular apps using PathLocationStrategy (the default for Angular) but an [issue](https://github.com/lynndylanhurley/devise_token_auth/issues/599) with the Devise Token Auth library currently prevents apps using HashLocationStrategy from working. (See [https://angular.io/api/common/LocationStrategy](https://angular.io/api/common/LocationStrategy) for an explanation of the two strategies). A PR has been created on the Devise Token Auth library to fix this - watch [PR 1341](https://github.com/lynndylanhurley/devise_token_auth/pull/1341) for the current status on that. Only password and new password are required to be sent for a "forgot password" password update request - the optional resetPasswordToken is not required. Note however that the server library Devise Token Auth has a new feature (currently unreleased in the gem) whereby you can add the resetPasswordToken into this request and it will auth using that token and not require the client lib to add any auth headers to the request, as it currently does. See the section [Mobile alternative flow (use reset_password_token)](https://devise-token-auth.gitbook.io/devise-token-auth/usage/reset_password) in the server side library's documentation.
9393

94-
`updatePassword({password: string, passwordConfirmation: string, passwordCurrent: string, userType?: string}): Observable<Response>`
95-
96-
#### Example:
94+
`updatePassword({password: string, passwordConfirmation: string, passwordCurrent?: string, userType?: string, resetPasswordToken?: string}): Observable<Response>`
95+
` `
96+
#### Example (change password):
9797
```javascript
9898
this.tokenService.updatePassword({
9999
password: 'newPassword',
@@ -105,8 +105,37 @@ this.tokenService.updatePassword({
105105
);
106106
```
107107

108+
#### Example (reset password):
109+
```javascript
110+
this.tokenService.updatePassword({
111+
password: 'newPassword',
112+
passwordConfirmation: 'newPassword',
113+
}).subscribe(
114+
res => console.log(res),
115+
error => console.log(error)
116+
);
117+
```
118+
108119
## .resetPassword()
109-
Request a password reset from the server.
120+
Request a password reset from the server (aka "forgot password" flow). This only asks the server to issue an email with a reset password link it. Once that link is clicked, the server will auth against the reset token in the link, and redirect to your configured resetPasswordCallback url, which should be a component that asks for the new password and confirmation. At that point you are effectively logged into the server with a temporary session and this lib will have valid auth headers ready to be added to the final step which is to issue an updatePassword to actually do the change. The addition of auth headers to that updatePassword request is handled automatically by this lib, you don't need to do anything in your component other than issue the update request. The server side library Devise Token Auth has a useful description of the flow at [https://devise-token-auth.gitbook.io/devise-token-auth/usage/reset_password](https://devise-token-auth.gitbook.io/devise-token-auth/usage/reset_password).
121+
122+
********
123+
See the .resetPassword() documentation above for a possible issue with the "forgot password" flow for Angular apps using HashLocationStrategy. For apps using the default PathLocationStrategy everything should work correctly, but be aware of one potentional issue. The redirect after clicking the email link goes through the server under PathLocationStrategy. It is important that the server allows the redirect to flow through to the Angular app without adding any auth tokens. For some servers that "catch all unknown" can be done via low level config, to send any unknown routes into index.html (the start of the Angular app). For example this is usually done via the .htaccess file for an Apache server. For a rails back end, the usual approach is at a higher level, by putting in catch-all final route and rendering that to index.html. It is important the controller used to do that render does not inherit from a controller that has the Devise Token Auth's "concerns" added. In general that means do not base the render controller on the ApplicationController but instead go a level up to the ActionController. For example:
124+
125+
Catch any unmatched routes in routes.rb:
126+
127+
`match "*path", to: 'errors#angular' , via: :all`
128+
129+
Then make sure ErrorsController inherits from ActionController (or somewhere that doesn't have the Devise Auth Token "concerns"). Note the public/index.html is server specifc, yours might be in ,e.g., dist/index.html:
130+
131+
```ruby
132+
class ErrosController < ActionController
133+
def angular
134+
render file: 'public/index.html', :layout => false
135+
end
136+
end
137+
```
138+
********
110139

111140
`resetPassword({login: string, userType?: string}): Observable<Response>`
112141

0 commit comments

Comments
 (0)