From 59a083220a6e8f6f09c92f23b26f2378426370dd Mon Sep 17 00:00:00 2001 From: Joey Paris Date: Wed, 23 Nov 2022 12:29:38 -0500 Subject: [PATCH] Add option to use expire_at instead of expire_duration --- lib/devise/passwordless/login_token.rb | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/devise/passwordless/login_token.rb b/lib/devise/passwordless/login_token.rb index 020872f..55a8477 100644 --- a/lib/devise/passwordless/login_token.rb +++ b/lib/devise/passwordless/login_token.rb @@ -2,7 +2,7 @@ module Devise::Passwordless class LoginToken class InvalidOrExpiredTokenError < StandardError; end - def self.encode(resource) + def self.encode(resource, **opts) now = Time.current len = ActiveSupport::MessageEncryptor.key_len salt = SecureRandom.random_bytes(len) @@ -16,6 +16,7 @@ def self.encode(resource) }, }, created_at: now.to_f, + **opts, }) salt_base64 = Base64.strict_encode64(salt) "#{salt_base64}:#{encrypted_data}" @@ -38,9 +39,16 @@ def self.decode(token, as_of=Time.current, expire_duration=Devise.passwordless_l raise InvalidOrExpiredTokenError end - created_at = ActiveSupport::TimeZone["UTC"].at(decrypted_data["created_at"]) - if as_of.to_f > (created_at + expire_duration).to_f - raise InvalidOrExpiredTokenError + if decrypted_data["expire_at"].present? + expire_at = ActiveSupport::TimeZone["UTC"].at(decrypted_data["expire_at"]) + if as_of.to_f > expire_at.to_f + raise InvalidOrExpiredTokenError + end + else + created_at = ActiveSupport::TimeZone["UTC"].at(decrypted_data["created_at"]) + if as_of.to_f > (created_at + expire_duration).to_f + raise InvalidOrExpiredTokenError + end end decrypted_data