Skip to content

Commit

Permalink
[NEW] Livechat GDPR compliance (#12982)
Browse files Browse the repository at this point in the history
* Initial implementation regarding GDPR compliance on Livechat.

* Add new settings regarding Livechat GDPR compliance.

* Added New Livechat settings, regarding the processing of the customers personal data.

* Implementation of methods regarding Livechat GDPR compliance has been completed.

* Meteor package added.

* Fix incorrect parameter name.

* Removed unused method(Livechat Lib).
  • Loading branch information
renatobecker authored and rodrigok committed Jan 16, 2019
1 parent 95e51c2 commit 5d0a2be
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 1 deletion.
7 changes: 7 additions & 0 deletions packages/rocketchat-i18n/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@
"All_messages": "All messages",
"All_users": "All users",
"All_users_in_the_channel_can_write_new_messages": "All users in the channel can write new messages",
"Allow_collect_and_store_HTTP_header_informations": "Allow to collect and store HTTP header informations",
"Allow_collect_and_store_HTTP_header_informations_description": "This setting determines whether Livechat is allowed to store information collected from HTTP header data, such as IP address, User-Agent, and so on.",
"Allow_Invalid_SelfSigned_Certs": "Allow Invalid Self-Signed Certs",
"Allow_Invalid_SelfSigned_Certs_Description": "Allow invalid and self-signed SSL certificate's for link validation and previews.",
"Allow_switching_departments": "Allow Visitor to Switch Departments",
Expand Down Expand Up @@ -923,6 +925,8 @@
"Customize": "Customize",
"CustomSoundsFilesystem": "Custom Sounds Filesystem",
"Dashboard": "Dashboard",
"Data_processing_consent_text": "Data processing consent text",
"Data_processing_consent_text_description": "Use this setting to explain that you can collect, store and process customer's personal informations along the conversation.",
"Date": "Date",
"Date_From": "From",
"Date_to": "to",
Expand Down Expand Up @@ -1307,6 +1311,9 @@
"Force_Disable_OpLog_For_Cache_Description": "Will not use OpLog to sync cache even when it's available",
"Force_SSL": "Force SSL",
"Force_SSL_Description": "*Caution!* _Force SSL_ should never be used with reverse proxy. If you have a reverse proxy, you should do the redirect THERE. This option exists for deployments like Heroku, that does not allow the redirect configuration at the reverse proxy.",
"Force_visitor_to_accept_data_processing_consent": "Force visitor to accept data processing consent",
"Force_visitor_to_accept_data_processing_consent_description": "Visitors are not allowed to start chatting without consent.",
"Force_visitor_to_accept_data_processing_consent_enabled_alert": "Agreement with data processing must be based on a transparent understanding of the reason for processing. Because of this, you must fill out the setting below which will be displayed to users in order to provide the reasons for collecting and processing your personal information.",
"Forgot_password": "Forgot your password?",
"Forgot_Password_Description": "You may use the following placeholders: <br/><ul><li>[Forgot_Password_Url] for the password recovery URL.</li><li>[name], [fname], [lname] for the user's full name, first name or last name, respectively.</li><li>[email] for the user's email.</li><li>[Site_Name] and [Site_URL] for the Application Name and URL respectively.</li></ul>",
"Forgot_Password_Email": "Click <a href=\"[Forgot_Password_Url]\">here</a> to reset your password.",
Expand Down
7 changes: 7 additions & 0 deletions packages/rocketchat-i18n/i18n/pt-BR.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@
"All_messages": "Todas as mensagens",
"All_users": "Todos usuários",
"All_users_in_the_channel_can_write_new_messages": "Todos usuários no canal podem enviar mensagens novas",
"Allow_collect_and_store_HTTP_header_informations": "Permitir coletar e armazenar informações do cabeçalho HTTP",
"Allow_collect_and_store_HTTP_header_informations_description": "Esta configuração determina se o Livechat tem permissão para armazenar informações coletadas do HTTP Header, como endereço IP, User-Agent, etc.",
"Allow_Invalid_SelfSigned_Certs": "Permitir certificados inválidos e auto-assinados para validação de links e previews",
"Allow_Invalid_SelfSigned_Certs_Description": "Permitir certificado SSL inválidos e auto-assinados para validação de link e previews.",
"Allow_switching_departments": "Permitir que Visitantes Mudem de Departamento",
Expand Down Expand Up @@ -877,6 +879,8 @@
"Customize": "Customizar",
"CustomSoundsFilesystem": "Sistema de arquivos de sons personalizados",
"Dashboard": "Dashboard",
"Data_processing_consent_text": "Texto de consentimento de processamento de dados",
"Data_processing_consent_text_description": "Use essa configuração para explicar que você pode coletar, armazenar e processar informações pessoais do usuário ao longo da conversa.",
"Date": "Data",
"Date_From": "De",
"Date_to": "até",
Expand Down Expand Up @@ -1233,6 +1237,9 @@
"Force_Disable_OpLog_For_Cache_Description": "Não usará o OpLog para sincronizar o cache mesmo quando estiver disponível",
"Force_SSL": "Forçar SSL",
"Force_SSL_Description": "*Cuidado!* _Forçar SSL_ nunca deve ser usado com proxy reverso. Se você tem um proxy reverso, você deve fazer o redirecionamento LÁ. Esta opção existe para implantações como Heroku, que não permite a configuração de redirecionamento de proxy reverso.",
"Force_visitor_to_accept_data_processing_consent": "Forçar o visitante a aceitar o consentimento de processamento de dados",
"Force_visitor_to_accept_data_processing_consent_description": "Os visitantes não podem inicar novas conversas sem o consentimento.",
"Force_visitor_to_accept_data_processing_consent_enabled_alert": "O acordo com o processamento de dados deve ser baseado em um entendimento transparente do motivo do processamento. Por isso, você deve preencher a configuração abaixo, que será exibida aos usuários, a fim de fornecer as razões para coletar e processar suas informações pessoais.",
"Forgot_password": "Esqueceu sua senha",
"Forgot_Password_Description": "Você pode usar os seguintes placeholders: <br/><ul><li>[Forgot_Password_Url] para o URL de recuperação de senha.</li><li>[nome], [fname], [lname] para o nome completo, primeiro nome ou sobrenome do usuário, respectivamente.</li><li>[email] para o email do usuário.</li><li>[Site_Name] e [Site_URL] para o Nome do Aplicativo e o URL, respectivamente.</li></ul>",
"Forgot_Password_Email": "Clique <a href=\"[Forgot_Password_Url]\">aqui</a> para redefinir sua senha.",
Expand Down
2 changes: 2 additions & 0 deletions packages/rocketchat-livechat/server/api/lib/livechat.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ export function settings() {
language: initSettings.Language,
transcript: initSettings.Livechat_enable_transcript,
historyMonitorType: initSettings.Livechat_history_monitor_type,
forceAcceptDataProcessingConsent: initSettings.Livechat_force_accept_data_processing_consent,
showConnecting: initSettings.Livechat_Show_Connecting,
},
theme: {
Expand All @@ -116,6 +117,7 @@ export function settings() {
conversationFinishedMessage: initSettings.Livechat_conversation_finished_message,
transcriptMessage: initSettings.Livechat_transcript_message,
registrationFormMessage: initSettings.Livechat_registration_form_message,
dataProcessingConsentText: initSettings.Livechat_data_processing_consent_text,
},
survey: {
items: ['satisfaction', 'agentKnowledge', 'agentResposiveness', 'agentFriendliness'],
Expand Down
27 changes: 27 additions & 0 deletions packages/rocketchat-livechat/server/api/v1/visitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,33 @@ RocketChat.API.v1.addRoute('livechat/visitor/:token', {
return RocketChat.API.v1.failure(e.error);
}
},
delete() {
try {
check(this.urlParams, {
token: String,
});

const visitor = LivechatVisitors.getVisitorByToken(this.urlParams.token);
if (!visitor) {
throw new Meteor.Error('invalid-token');
}

const { _id } = visitor;
const result = RocketChat.Livechat.removeGuest(_id);
if (result) {
return RocketChat.API.v1.success({
visitor: {
_id,
ts: new Date().toISOString(),
},
});
}

return RocketChat.API.v1.failure();
} catch (e) {
return RocketChat.API.v1.failure(e.error);
}
},
});

RocketChat.API.v1.addRoute('livechat/visitor/:token/room', { authRequired: true }, {
Expand Down
28 changes: 28 additions & 0 deletions packages/rocketchat-livechat/server/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -400,4 +400,32 @@ Meteor.startup(function() {
i18nLabel: 'Secret_token',
enableQuery: { _id: 'Livechat_Routing_Method', value: 'External' },
});

RocketChat.settings.add('Livechat_Allow_collect_and_store_HTTP_header_informations', false, {
type: 'boolean',
group: 'Livechat',
public: true,
i18nLabel: 'Allow_collect_and_store_HTTP_header_informations',
i18nDescription: 'Allow_collect_and_store_HTTP_header_informations_description',
});

RocketChat.settings.add('Livechat_force_accept_data_processing_consent', false, {
type: 'boolean',
group: 'Livechat',
public: true,
alert: 'Force_visitor_to_accept_data_processing_consent_enabled_alert',
i18nLabel: 'Force_visitor_to_accept_data_processing_consent',
i18nDescription: 'Force_visitor_to_accept_data_processing_consent_description',
});

RocketChat.settings.add('Livechat_data_processing_consent_text', '', {
type: 'string',
multiline: true,
group: 'Livechat',
public: true,
i18nLabel: 'Data_processing_consent_text',
i18nDescription: 'Data_processing_consent_text_description',
enableQuery: { _id: 'Livechat_force_accept_data_processing_consent', value: true },
});

});
1 change: 1 addition & 0 deletions packages/rocketchat-livechat/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import './methods/saveOfficeHours';
import './methods/sendTranscript';
import './models/Users';
import './models/Rooms';
import './models/Subscriptions';
import './models/Messages';
import '../lib/LivechatExternalMessage';
import './models/LivechatCustomField';
Expand Down
35 changes: 34 additions & 1 deletion packages/rocketchat-livechat/server/lib/Livechat.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,9 @@ RocketChat.Livechat = {
username,
};

if (this.connection) {
const storeHttpHeaderData = RocketChat.settings.get('Livechat_Allow_collect_and_store_HTTP_header_informations');

if (this.connection && storeHttpHeaderData) {
userData.userAgent = this.connection.httpHeaders['user-agent'];
userData.ip = this.connection.httpHeaders['x-real-ip'] || this.connection.httpHeaders['x-forwarded-for'] || this.connection.clientAddress;
userData.host = this.connection.httpHeaders.host;
Expand Down Expand Up @@ -366,6 +368,8 @@ RocketChat.Livechat = {
'Livechat_name_field_registration_form',
'Livechat_email_field_registration_form',
'Livechat_registration_form_message',
'Livechat_force_accept_data_processing_consent',
'Livechat_data_processing_consent_text',
]).forEach((setting) => {
settings[setting._id] = setting.value;
});
Expand Down Expand Up @@ -717,6 +721,35 @@ RocketChat.Livechat = {
return RocketChat.authz.removeUserFromRoles(user._id, 'livechat-manager');
},

removeGuest(_id) {
check(_id, String);

const guest = LivechatVisitors.findById(_id);
if (!guest) {
throw new Meteor.Error('error-invalid-guest', 'Invalid guest', { method: 'livechat:removeGuest' });
}

this.cleanGuestHistory(_id);
return LivechatVisitors.removeById(_id);
},

cleanGuestHistory(_id) {
const guest = LivechatVisitors.findById(_id);
if (!guest) {
throw new Meteor.Error('error-invalid-guest', 'Invalid guest', { method: 'livechat:cleanGuestHistory' });
}

const { token } = guest;

RocketChat.models.Rooms.findByVisitorToken(token).forEach((room) => {
RocketChat.models.Messages.removeFilesByRoomId(room._id);
RocketChat.models.Messages.removeByRoomId(room._id);
});

RocketChat.models.Subscriptions.removeByVisitorToken(token);
RocketChat.models.Rooms.removeByVisitorToken(token);
},

saveDepartment(_id, departmentData, departmentAgents) {
check(_id, Match.Maybe(String));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,12 @@ class LivechatVisitors extends RocketChat.models._Base {

return this.update({ _id }, update);
}

// REMOVE
removeById(_id) {
const query = { _id };
return this.remove(query);
}
}

export default new LivechatVisitors();
8 changes: 8 additions & 0 deletions packages/rocketchat-livechat/server/models/Rooms.js
Original file line number Diff line number Diff line change
Expand Up @@ -348,3 +348,11 @@ RocketChat.models.Rooms.removeAgentByRoomId = function(roomId) {

this.update(query, update);
};

RocketChat.models.Rooms.removeByVisitorToken = function(token) {
const query = {
'v.token': token,
};

this.remove(query);
};
9 changes: 9 additions & 0 deletions packages/rocketchat-livechat/server/models/Subscriptions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { RocketChat } from 'meteor/rocketchat:lib';

RocketChat.models.Subscriptions.removeByVisitorToken = function(token) {
const query = {
'v.token': token,
};

this.remove(query);
};

0 comments on commit 5d0a2be

Please sign in to comment.