mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-02 20:18:08 +00:00
feat: do not send contact details to the widget (#9223)
* refactor: use has_email instead of email * feat: remove usage of details directly in forms * test: update payload * test: fix transcript test * refactor: use computed hasEmail --------- Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
This commit is contained in:
@@ -33,10 +33,10 @@ class Api::V1::Widget::ConversationsController < Api::V1::Widget::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def transcript
|
def transcript
|
||||||
if permitted_params[:email].present? && conversation.present?
|
if conversation.present? && conversation.contact.present? && conversation.contact.email.present?
|
||||||
ConversationReplyMailer.with(account: conversation.account).conversation_transcript(
|
ConversationReplyMailer.with(account: conversation.account).conversation_transcript(
|
||||||
conversation,
|
conversation,
|
||||||
permitted_params[:email]
|
conversation.contact.email
|
||||||
)&.deliver_later
|
)&.deliver_later
|
||||||
end
|
end
|
||||||
head :ok
|
head :ok
|
||||||
|
|||||||
@@ -38,10 +38,9 @@ const setUserLastSeenAt = async ({ lastSeen }) => {
|
|||||||
{ contact_last_seen_at: lastSeen }
|
{ contact_last_seen_at: lastSeen }
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
const sendEmailTranscript = async ({ email }) => {
|
const sendEmailTranscript = async () => {
|
||||||
return API.post(
|
return API.post(
|
||||||
`/api/v1/widget/conversations/transcript${window.location.search}`,
|
`/api/v1/widget/conversations/transcript${window.location.search}`
|
||||||
{ email }
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
const toggleStatus = async () => {
|
const toggleStatus = async () => {
|
||||||
|
|||||||
@@ -87,7 +87,10 @@ export default {
|
|||||||
return !allowMessagesAfterResolved && status === 'resolved';
|
return !allowMessagesAfterResolved && status === 'resolved';
|
||||||
},
|
},
|
||||||
showEmailTranscriptButton() {
|
showEmailTranscriptButton() {
|
||||||
return this.currentUser && this.currentUser.email;
|
return this.hasEmail;
|
||||||
|
},
|
||||||
|
hasEmail() {
|
||||||
|
return this.currentUser && this.currentUser.has_email;
|
||||||
},
|
},
|
||||||
hasReplyTo() {
|
hasReplyTo() {
|
||||||
return (
|
return (
|
||||||
@@ -141,12 +144,9 @@ export default {
|
|||||||
this.inReplyTo = message;
|
this.inReplyTo = message;
|
||||||
},
|
},
|
||||||
async sendTranscript() {
|
async sendTranscript() {
|
||||||
const { email } = this.currentUser;
|
if (this.hasEmail) {
|
||||||
if (email) {
|
|
||||||
try {
|
try {
|
||||||
await sendEmailTranscript({
|
await sendEmailTranscript();
|
||||||
email,
|
|
||||||
});
|
|
||||||
window.bus.$emit(BUS_EVENTS.SHOW_ALERT, {
|
window.bus.$emit(BUS_EVENTS.SHOW_ALERT, {
|
||||||
message: this.$t('EMAIL_TRANSCRIPT.SEND_EMAIL_SUCCESS'),
|
message: this.$t('EMAIL_TRANSCRIPT.SEND_EMAIL_SUCCESS'),
|
||||||
type: 'success',
|
type: 'success',
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<FormulateForm
|
<FormulateForm
|
||||||
v-model="formValues"
|
v-model="formValues"
|
||||||
class="flex flex-1 flex-col p-6 overflow-y-auto"
|
class="flex flex-col flex-1 p-6 overflow-y-auto"
|
||||||
@submit="onSubmit"
|
@submit="onSubmit"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<custom-button
|
<custom-button
|
||||||
class="font-medium mt-2 mb-5"
|
class="mt-2 mb-5 font-medium"
|
||||||
block
|
block
|
||||||
:bg-color="widgetColor"
|
:bg-color="widgetColor"
|
||||||
:text-color="textColor"
|
:text-color="textColor"
|
||||||
@@ -133,9 +133,10 @@ export default {
|
|||||||
return this.preChatFormEnabled ? this.options.preChatFields : [];
|
return this.preChatFormEnabled ? this.options.preChatFields : [];
|
||||||
},
|
},
|
||||||
filteredPreChatFields() {
|
filteredPreChatFields() {
|
||||||
const isUserEmailAvailable = !!this.currentUser.email;
|
const isUserEmailAvailable = this.currentUser.has_email;
|
||||||
const isUserPhoneNumberAvailable = !!this.currentUser.phone_number;
|
const isUserPhoneNumberAvailable = this.currentUser.has_phone_number;
|
||||||
const isUserIdentifierAvailable = !!this.currentUser.identifier;
|
const isUserIdentifierAvailable = !!this.currentUser.identifier;
|
||||||
|
|
||||||
const isUserNameAvailable = !!(
|
const isUserNameAvailable = !!(
|
||||||
isUserIdentifierAvailable ||
|
isUserIdentifierAvailable ||
|
||||||
isUserEmailAvailable ||
|
isUserEmailAvailable ||
|
||||||
@@ -302,11 +303,10 @@ export default {
|
|||||||
},
|
},
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
const { emailAddress, fullName, phoneNumber, message } = this.formValues;
|
const { emailAddress, fullName, phoneNumber, message } = this.formValues;
|
||||||
const { email } = this.currentUser;
|
|
||||||
this.$emit('submit', {
|
this.$emit('submit', {
|
||||||
fullName,
|
fullName,
|
||||||
phoneNumber,
|
phoneNumber,
|
||||||
emailAddress: emailAddress || email,
|
emailAddress,
|
||||||
message,
|
message,
|
||||||
activeCampaignId: this.activeCampaign.id,
|
activeCampaignId: this.activeCampaign.id,
|
||||||
conversationCustomAttributes: this.conversationCustomAttributes,
|
conversationCustomAttributes: this.conversationCustomAttributes,
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import { getters } from '../../contacts';
|
|||||||
describe('#getters', () => {
|
describe('#getters', () => {
|
||||||
it('getCurrentUser', () => {
|
it('getCurrentUser', () => {
|
||||||
const user = {
|
const user = {
|
||||||
email: 'thoma@sphadikam.com',
|
has_email: true,
|
||||||
name: 'Adu Thoma',
|
has_name: true,
|
||||||
avatar_url: '',
|
avatar_url: '',
|
||||||
identifier_hash: 'malana_hash',
|
identifier_hash: 'malana_hash',
|
||||||
};
|
};
|
||||||
@@ -12,8 +12,8 @@ describe('#getters', () => {
|
|||||||
currentUser: user,
|
currentUser: user,
|
||||||
};
|
};
|
||||||
expect(getters.getCurrentUser(state)).toEqual({
|
expect(getters.getCurrentUser(state)).toEqual({
|
||||||
email: 'thoma@sphadikam.com',
|
has_email: true,
|
||||||
name: 'Adu Thoma',
|
has_name: true,
|
||||||
avatar_url: '',
|
avatar_url: '',
|
||||||
identifier_hash: 'malana_hash',
|
identifier_hash: 'malana_hash',
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ describe('#mutations', () => {
|
|||||||
describe('#SET_CURRENT_USER', () => {
|
describe('#SET_CURRENT_USER', () => {
|
||||||
it('set current user', () => {
|
it('set current user', () => {
|
||||||
const user = {
|
const user = {
|
||||||
email: 'thoma@sphadikam.com',
|
has_email: true,
|
||||||
name: 'Adu Thoma',
|
has_name: true,
|
||||||
avatar_url: '',
|
avatar_url: '',
|
||||||
identifier_hash: 'malana_hash',
|
identifier_hash: 'malana_hash',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
json.id @contact.id
|
json.id @contact.id
|
||||||
json.name @contact.name
|
json.has_email @contact.email.present?
|
||||||
json.email @contact.email
|
json.has_name @contact.name.present?
|
||||||
json.phone_number @contact.phone_number
|
json.has_phone_number @contact.phone_number.present?
|
||||||
json.widget_auth_token @widget_auth_token if @widget_auth_token.present?
|
json.widget_auth_token @widget_auth_token if @widget_auth_token.present?
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
json.id @contact.id
|
json.id @contact.id
|
||||||
json.name @contact.name
|
json.has_email @contact.email.present?
|
||||||
json.email @contact.email
|
json.has_name @contact.name.present?
|
||||||
json.phone_number @contact.phone_number
|
json.has_phone_number @contact.phone_number.present?
|
||||||
json.identifier @contact.identifier
|
json.identifier @contact.identifier
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
json.id @contact.id
|
json.id @contact.id
|
||||||
json.name @contact.name
|
json.has_email @contact.email.present?
|
||||||
json.email @contact.email
|
json.has_name @contact.name.present?
|
||||||
json.phone_number @contact.phone_number
|
json.has_phone_number @contact.phone_number.present?
|
||||||
|
|||||||
@@ -48,7 +48,9 @@ RSpec.describe '/api/v1/widget/contacts', type: :request do
|
|||||||
headers: { 'X-Auth-Token' => token },
|
headers: { 'X-Auth-Token' => token },
|
||||||
as: :json
|
as: :json
|
||||||
body = response.parsed_body
|
body = response.parsed_body
|
||||||
expect(body['phone_number']).to eq('+745623239')
|
expect(body['has_phone_number']).to be true
|
||||||
|
contact.reload
|
||||||
|
expect(contact.phone_number).to eq('+745623239')
|
||||||
expect(response).to have_http_status(:success)
|
expect(response).to have_http_status(:success)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -58,7 +60,9 @@ RSpec.describe '/api/v1/widget/contacts', type: :request do
|
|||||||
headers: { 'X-Auth-Token' => token },
|
headers: { 'X-Auth-Token' => token },
|
||||||
as: :json
|
as: :json
|
||||||
body = response.parsed_body
|
body = response.parsed_body
|
||||||
expect(body['phone_number']).to eq('+245623239')
|
expect(body['has_phone_number']).to be true
|
||||||
|
contact.reload
|
||||||
|
expect(contact.phone_number).to eq('+245623239')
|
||||||
expect(response).to have_http_status(:success)
|
expect(response).to have_http_status(:success)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -68,7 +72,33 @@ RSpec.describe '/api/v1/widget/contacts', type: :request do
|
|||||||
headers: { 'X-Auth-Token' => token },
|
headers: { 'X-Auth-Token' => token },
|
||||||
as: :json
|
as: :json
|
||||||
body = response.parsed_body
|
body = response.parsed_body
|
||||||
expect(body['email']).to eq('test@test.com')
|
expect(body['has_email']).to be true
|
||||||
|
contact.reload
|
||||||
|
expect(contact.email).to eq('test@test.com')
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'dont update email if empty value email passed' do
|
||||||
|
patch '/api/v1/widget/contact',
|
||||||
|
params: params.merge({ email: '' }),
|
||||||
|
headers: { 'X-Auth-Token' => token },
|
||||||
|
as: :json
|
||||||
|
body = response.parsed_body
|
||||||
|
expect(body['has_email']).to be true
|
||||||
|
contact.reload
|
||||||
|
expect(contact.email).to eq('test@test.com')
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'dont update email if nil value email passed' do
|
||||||
|
patch '/api/v1/widget/contact',
|
||||||
|
params: params.merge({ email: nil }),
|
||||||
|
headers: { 'X-Auth-Token' => token },
|
||||||
|
as: :json
|
||||||
|
body = response.parsed_body
|
||||||
|
expect(body['has_email']).to be true
|
||||||
|
contact.reload
|
||||||
|
expect(contact.email).to eq('test@test.com')
|
||||||
expect(response).to have_http_status(:success)
|
expect(response).to have_http_status(:success)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -78,7 +108,9 @@ RSpec.describe '/api/v1/widget/contacts', type: :request do
|
|||||||
headers: { 'X-Auth-Token' => token },
|
headers: { 'X-Auth-Token' => token },
|
||||||
as: :json
|
as: :json
|
||||||
body = response.parsed_body
|
body = response.parsed_body
|
||||||
expect(body['email']).to eq('test-1@test.com')
|
expect(body['has_email']).to be true
|
||||||
|
contact.reload
|
||||||
|
expect(contact.email).to eq('test-1@test.com')
|
||||||
expect(response).to have_http_status(:success)
|
expect(response).to have_http_status(:success)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -190,17 +190,19 @@ RSpec.describe '/api/v1/widget/conversations/toggle_typing', type: :request do
|
|||||||
describe 'POST /api/v1/widget/conversations/transcript' do
|
describe 'POST /api/v1/widget/conversations/transcript' do
|
||||||
context 'with a conversation' do
|
context 'with a conversation' do
|
||||||
it 'sends transcript email' do
|
it 'sends transcript email' do
|
||||||
|
contact.update(email: 'test@test.com')
|
||||||
mailer = double
|
mailer = double
|
||||||
allow(ConversationReplyMailer).to receive(:with).and_return(mailer)
|
allow(ConversationReplyMailer).to receive(:with).and_return(mailer)
|
||||||
allow(mailer).to receive(:conversation_transcript)
|
allow(mailer).to receive(:conversation_transcript)
|
||||||
|
|
||||||
post '/api/v1/widget/conversations/transcript',
|
post '/api/v1/widget/conversations/transcript',
|
||||||
headers: { 'X-Auth-Token' => token },
|
headers: { 'X-Auth-Token' => token },
|
||||||
params: { website_token: web_widget.website_token, email: 'test@test.com' },
|
params: { website_token: web_widget.website_token },
|
||||||
as: :json
|
as: :json
|
||||||
|
|
||||||
expect(response).to have_http_status(:success)
|
expect(response).to have_http_status(:success)
|
||||||
expect(mailer).to have_received(:conversation_transcript).with(conversation, 'test@test.com')
|
expect(mailer).to have_received(:conversation_transcript).with(conversation, 'test@test.com')
|
||||||
|
contact.update(email: nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user