From afc97faa8bae226a915cc4f588d756d489131279 Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Sat, 27 May 2023 13:24:31 +0530 Subject: [PATCH] chore: Rotate pubsub token on password change (#7194) Fixes: https://linear.app/chatwoot/issue/CW-1350/ --- app/models/concerns/pubsubable.rb | 10 ++++++++++ spec/models/user_spec.rb | 16 ++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/app/models/concerns/pubsubable.rb b/app/models/concerns/pubsubable.rb index 7da99ea14..bbdef5100 100644 --- a/app/models/concerns/pubsubable.rb +++ b/app/models/concerns/pubsubable.rb @@ -6,6 +6,16 @@ module Pubsubable included do # Used by the actionCable/PubSub Service we use for real time communications has_secure_token :pubsub_token + before_save :rotate_pubsub_token + end + + def rotate_pubsub_token + # ATM we are only rotating the token if the user is changing their password + return unless is_a?(User) + + # Using the class method to avoid the extra Save + # TODO: Should we do this on signin ? + self.pubsub_token = self.class.generate_unique_secure_token if will_save_change_to_encrypted_password? end def pubsub_token diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 7bae381ac..f38b3db0b 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -34,6 +34,22 @@ RSpec.describe User do it { expect(user.pubsub_token).not_to be_nil } it { expect(user.saved_changes.keys).not_to eq('pubsub_token') } + + context 'rotates the pubsub_token' do + it 'changes the pubsub_token when password changes' do + pubsub_token = user.pubsub_token + user.password = Faker::Internet.password(special_characters: true) + user.save! + expect(user.pubsub_token).not_to eq(pubsub_token) + end + + it 'will not change pubsub_token when other attributes change' do + pubsub_token = user.pubsub_token + user.name = Faker::Name.name + user.save! + expect(user.pubsub_token).to eq(pubsub_token) + end + end end describe 'hmac_identifier' do