Class: Retailer::CallbackTokenService
- Inherits:
-
Object
- Object
- Retailer::CallbackTokenService
- Defined in:
- app/services/retailer/callback_token_service.rb
Overview
Generates and validates time-limited JWT tokens for Oxylabs callback authentication.
Tokens are embedded in the callback URL to prevent unauthorized submissions.
Uses API_HOSTNAME_WITHOUT_PORT constant for environment-aware URLs:
- Production: api.warmlyyours.com
- Staging: api.warmlyyours.ws
- Development: Uses dev tunnel (api-hostname.warmlyyours.dev)
Constant Summary collapse
- JWT_SECRET =
Rails.application.secret_key_base
- JWT_ALGORITHM =
'HS256'- TOKEN_EXPIRY =
24.hours
Class Method Summary collapse
-
.callback_url(catalog_item_id: nil) ⇒ String
Generate a callback URL for production/staging Uses API_HOSTNAME_WITHOUT_PORT constant for environment-aware URLs.
-
.dev_callback_url(catalog_item_id: nil) ⇒ String
Generate a dev callback URL for testing via Cloudflare tunnel Uses hostname-specific subdomain: api-hostname.warmlyyours.dev.
-
.generate_token ⇒ String
Generate a JWT token for callback authentication.
-
.valid_token?(token) ⇒ Boolean
Check if a token is valid.
-
.validate_token(token) ⇒ Hash?
Validate and decode a JWT token.
Class Method Details
.callback_url(catalog_item_id: nil) ⇒ String
Generate a callback URL for production/staging
Uses API_HOSTNAME_WITHOUT_PORT constant for environment-aware URLs
65 66 67 68 69 70 |
# File 'app/services/retailer/callback_token_service.rb', line 65 def callback_url(catalog_item_id: nil) token = generate_token url = "https://#{API_HOSTNAME_WITHOUT_PORT}/webhooks/v1/oxylabs?token=#{token}" url += "&catalog_item_id=#{catalog_item_id}" if catalog_item_id url end |
.dev_callback_url(catalog_item_id: nil) ⇒ String
Generate a dev callback URL for testing via Cloudflare tunnel
Uses hostname-specific subdomain: api-hostname.warmlyyours.dev
76 77 78 79 80 81 82 |
# File 'app/services/retailer/callback_token_service.rb', line 76 def dev_callback_url(catalog_item_id: nil) hostname = `hostname -s`.strip.downcase token = generate_token url = "https://api-#{hostname}.warmlyyours.dev/webhooks/v1/oxylabs?token=#{token}" url += "&catalog_item_id=#{catalog_item_id}" if catalog_item_id url end |
.generate_token ⇒ String
Generate a JWT token for callback authentication
25 26 27 28 29 30 31 32 33 34 |
# File 'app/services/retailer/callback_token_service.rb', line 25 def generate_token payload = { purpose: 'oxylabs_callback', exp: TOKEN_EXPIRY.from_now.to_i, iat: Time.current.to_i, jti: SecureRandom.uuid # Unique token ID } JWT.encode(payload, JWT_SECRET, JWT_ALGORITHM) end |
.valid_token?(token) ⇒ Boolean
Check if a token is valid
57 58 59 |
# File 'app/services/retailer/callback_token_service.rb', line 57 def valid_token?(token) validate_token(token).present? end |
.validate_token(token) ⇒ Hash?
Validate and decode a JWT token
39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'app/services/retailer/callback_token_service.rb', line 39 def validate_token(token) return nil if token.blank? decoded_token = JWT.decode(token, JWT_SECRET, true, { algorithm: JWT_ALGORITHM }) payload = decoded_token.first # Check if token is for oxylabs callback return nil unless payload['purpose'] == 'oxylabs_callback' payload rescue JWT::DecodeError, JWT::ExpiredSignature => e Rails.logger.warn "[Oxylabs Callback] Token validation failed: #{e.class}" nil end |