|
|
@@ -7,6 +7,7 @@ const crypto = require('crypto')
|
|
|
const _ = require('lodash')
|
|
|
const { expressify } = require('@overleaf/promise-utils')
|
|
|
const logger = require('@overleaf/logger')
|
|
|
+const { createHash } = require('crypto')
|
|
|
|
|
|
const analyticsEventsQueue = Queues.getQueue('analytics-events')
|
|
|
const analyticsEditingSessionsQueue = Queues.getQueue(
|
|
|
@@ -18,6 +19,7 @@ const analyticsUserPropertiesQueue = Queues.getQueue(
|
|
|
const analyticsAccountMappingQueue = Queues.getQueue(
|
|
|
'analytics-account-mapping'
|
|
|
)
|
|
|
+const analyticsEmailChangeQueue = Queues.getQueue('analytics-email-change')
|
|
|
|
|
|
const ONE_MINUTE_MS = 60 * 1000
|
|
|
|
|
|
@@ -148,6 +150,7 @@ function setUserPropertyForSessionInBackground(session, property, value) {
|
|
|
|
|
|
/**
|
|
|
* @typedef {(import('./types').AccountMapping)} AccountMapping
|
|
|
+ * @typedef {(import('./types').EmailChangePayload)} EmailChangePayload
|
|
|
*/
|
|
|
|
|
|
/**
|
|
|
@@ -193,6 +196,59 @@ function registerAccountMapping({
|
|
|
})
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * Registers operations relating to email addresses.
|
|
|
+ *
|
|
|
+ * Generally, this should be called through the EmailChangeHelper module to ensure
|
|
|
+ * that the right data is sent.
|
|
|
+ *
|
|
|
+ * This will be called whenever an email is created, updated or deleted.
|
|
|
+ *
|
|
|
+ * @param {EmailChangePayload} payload
|
|
|
+ */
|
|
|
+function registerEmailChange({
|
|
|
+ userId,
|
|
|
+ email,
|
|
|
+ action,
|
|
|
+ createdAt = new Date(),
|
|
|
+ emailCreatedAt,
|
|
|
+ isPrimary,
|
|
|
+ emailConfirmedAt,
|
|
|
+ emailDeletedAt,
|
|
|
+}) {
|
|
|
+ Metrics.analyticsQueue.inc({ status: 'adding', event_type: 'email-change' })
|
|
|
+
|
|
|
+ const salt = Settings.analytics?.hashedEmailSalt ?? ''
|
|
|
+
|
|
|
+ const hashedEmail = createHash('sha256')
|
|
|
+ .update(`${email}${salt}`)
|
|
|
+ .digest('hex')
|
|
|
+
|
|
|
+ analyticsEmailChangeQueue
|
|
|
+ .add('email-change', {
|
|
|
+ action,
|
|
|
+ createdAt,
|
|
|
+ emailDeletedAt,
|
|
|
+ email: hashedEmail,
|
|
|
+ emailConfirmedAt,
|
|
|
+ emailCreatedAt,
|
|
|
+ isPrimary,
|
|
|
+ userId,
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ Metrics.analyticsQueue.inc({
|
|
|
+ status: 'added',
|
|
|
+ event_type: 'email-change',
|
|
|
+ })
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ Metrics.analyticsQueue.inc({
|
|
|
+ status: 'error',
|
|
|
+ event_type: 'email-change',
|
|
|
+ })
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
function updateEditingSession(userId, projectId, countryCode, segmentation) {
|
|
|
if (!userId) {
|
|
|
return
|
|
|
@@ -400,5 +456,6 @@ module.exports = {
|
|
|
updateEditingSession,
|
|
|
getIdsFromSession,
|
|
|
registerAccountMapping,
|
|
|
+ registerEmailChange,
|
|
|
analyticsIdMiddleware: expressify(analyticsIdMiddleware),
|
|
|
}
|