mirror of
https://github.com/lingble/chatwoot.git
synced 2025-10-30 18:47:51 +00:00
feat: Add support for customizing expiry of widget token (#12446)
This PR is part of https://github.com/chatwoot/chatwoot/pull/12259. It adds a default expiry of 180 days for tokens issued on the widget. The expiry can be customized based on customer requests and internal security requirements. Co-authored-by: Balasaheb Dubale <bdubale@entrata.com>
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
class Widget::TokenService
|
class Widget::TokenService
|
||||||
|
DEFAULT_EXPIRY_DAYS = 180
|
||||||
|
|
||||||
pattr_initialize [:payload, :token]
|
pattr_initialize [:payload, :token]
|
||||||
|
|
||||||
def generate_token
|
def generate_token
|
||||||
JWT.encode payload, secret_key, 'HS256'
|
JWT.encode payload_with_expiry, secret_key, 'HS256'
|
||||||
end
|
end
|
||||||
|
|
||||||
def decode_token
|
def decode_token
|
||||||
@@ -15,6 +17,24 @@ class Widget::TokenService
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def payload_with_expiry
|
||||||
|
payload.merge(exp: exp, iat: iat)
|
||||||
|
end
|
||||||
|
|
||||||
|
def iat
|
||||||
|
Time.zone.now.to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
def exp
|
||||||
|
iat + expire_in.days.to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
def expire_in
|
||||||
|
# Value is stored in days, defaulting to 6 months (180 days)
|
||||||
|
token_expiry_value = InstallationConfig.find_by(name: 'WIDGET_TOKEN_EXPIRY')&.value
|
||||||
|
(token_expiry_value.presence || DEFAULT_EXPIRY_DAYS).to_i
|
||||||
|
end
|
||||||
|
|
||||||
def secret_key
|
def secret_key
|
||||||
Rails.application.secret_key_base
|
Rails.application.secret_key_base
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -439,3 +439,11 @@
|
|||||||
locked: false
|
locked: false
|
||||||
description: 'Zone ID for the Cloudflare domain'
|
description: 'Zone ID for the Cloudflare domain'
|
||||||
## ------ End of Configs added for Cloudflare ------ ##
|
## ------ End of Configs added for Cloudflare ------ ##
|
||||||
|
|
||||||
|
## ------ Customizations for Customers ------ ##
|
||||||
|
- name: WIDGET_TOKEN_EXPIRY
|
||||||
|
display_title: 'Widget Token Expiry'
|
||||||
|
value: 180
|
||||||
|
locked: false
|
||||||
|
description: 'Token expiry in days'
|
||||||
|
## ------ End of Customizations for Customers ------ ##
|
||||||
|
|||||||
42
spec/services/widget/token_service_expiry_spec.rb
Normal file
42
spec/services/widget/token_service_expiry_spec.rb
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Widget::TokenService, type: :service do
|
||||||
|
describe 'token expiry configuration' do
|
||||||
|
let(:service) { described_class.new(payload: {}) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
# Clear any existing configs to ensure test isolation
|
||||||
|
InstallationConfig.where(name: 'WIDGET_TOKEN_EXPIRY').destroy_all
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with valid configuration' do
|
||||||
|
before do
|
||||||
|
create(:installation_config, name: 'WIDGET_TOKEN_EXPIRY', value: '30')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'uses the configured value for token expiry' do
|
||||||
|
freeze_time do
|
||||||
|
token = service.generate_token
|
||||||
|
decoded = JWT.decode(token, Rails.application.secret_key_base, true, algorithm: 'HS256').first
|
||||||
|
expect(decoded['iat']).to eq(Time.now.to_i)
|
||||||
|
expect(decoded['exp']).to eq(30.days.from_now.to_i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with empty configuration' do
|
||||||
|
before do
|
||||||
|
create(:installation_config, name: 'WIDGET_TOKEN_EXPIRY', value: '')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'uses the default expiry' do
|
||||||
|
freeze_time do
|
||||||
|
token = service.generate_token
|
||||||
|
decoded = JWT.decode(token, Rails.application.secret_key_base, true, algorithm: 'HS256').first
|
||||||
|
expect(decoded['iat']).to eq(Time.now.to_i)
|
||||||
|
expect(decoded['exp']).to eq(180.days.from_now.to_i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user