so i'm using devise_token_auth gem for basic user functionalities, and I made some simple changes to the reset password flow. Basically instead of having a link in the email for the user to click and go to the reset page, I show the token, so the users has to copy it and enter manually in a field.
It is working like that, but the token is to large and ugly, i'd like it to be something like 6 alphanumeric digits. It looks better and it makes things easier for the user. I don't quite know how to do it, I probably should overwrite some devise original Controller. How to do it? As devise_token_auth places a controller "on top" of every original devise controller and what I want is to overwrite the set_reset_password_token from devise's recoverable module.
EDIT: I've found the answer myself so i'll answer it below! But please, feel free to complain, ask and propose better/alternative solutions.
So, first of, if you want to overwrite a function from a devise module, you can just write it with the same name on your model file, probably in models/user.rb. For overwriting the set_reset_password from recoverable module, you can just do the following (as suggested by Sergio Tulentsev here):
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:confirmable, :lockable
...
protected
def set_reset_password_token
...
end
end
Now for changing to how you want your raw token to be (before it's encrypted), in my case I wanted it to have 6 digits, containing only A-Z, a-z, 0-9 digits, lets see what devise does (link to github file):
def set_reset_password_token
raw, enc = Devise.token_generator.generate(self.class, :reset_password_token)
self.reset_password_token = enc
self.reset_password_sent_at = Time.now.utc
save(validate: false)
raw
end
What Devise.token_generator.generate
(seen here) does is generate a raw token using SecureRandom.urlsafe_base64(rlength).tr('lIO0', 'sxyz')
(of length 20, as seen here) and return the raw and encrypted token unless some user already has the same token assigned.
Finally, what you need to do is rewrite this set_password_token using SecureRandom functions allied with tr to generate tokens any way you like, and don't forget to make sure the token is unique and not currently being used.