Skip to content

Commit

Permalink
Ref #430 - Identify anonymous users by their hash and salted MAC address
Browse files Browse the repository at this point in the history
See #430 for the underlying details.
  • Loading branch information
balupton committed Feb 14, 2013
1 parent 5a515db commit fb8de48
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 26 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@
"lodash": "~1.0.0",
"backbone": "0.9.9",
"watchr": "~2.3.7",
"yamljs": "~0.1.4"
"yamljs": "~0.1.4",
"getmac": "~1.0.4"
},
"optionalDependencies": {
"airbrake": "~0.2.9",
Expand Down
83 changes: 58 additions & 25 deletions src/lib/docpad.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,10 @@ class DocPad extends EventEmitterEnhanced
# By default it is only enabled if we are not running inside a test
reportStatistics: process.argv.join('').indexOf('test') is -1

# Hash Key
# The key that we use to hash some data before sending it to our statistic server
hashKey: '7>9}$3hP86o,4=@T' # const

# Airbrake Token
airbrakeToken: 'e7374dd1c5a346efe3895b9b0c1c0325'

Expand Down Expand Up @@ -904,6 +908,7 @@ class DocPad extends EventEmitterEnhanced
docpad.log('warn', locale.trackError+'\n'+locale.errorFollows, err)
@trackRunnerInstance.total = Infinity


# Initialize a default logger
logger = new caterpillar.Logger(
transports:
Expand Down Expand Up @@ -983,6 +988,7 @@ class DocPad extends EventEmitterEnhanced
[instanceConfig,next] = balUtil.extractOptsAndCallback(instanceConfig,next)
docpad = @
locale = @getLocale()
mixpanelInstance = @getMixpanelInstance()

# Render Single Extensions
@DocumentModel::defaults.renderSingleExtensions = docpad.config.renderSingleExtensions
Expand All @@ -1005,41 +1011,68 @@ class DocPad extends EventEmitterEnhanced
tasks = new balUtil.Group (err) ->
# Error?
return docpad.error(err) if err

# All done, forward our DocPad instance onto our creator
return next?(null,docpad)

# Welcome
tasks.push (complete) =>
# No welcome
return complete() unless docpad.config.welcome

# Welcome
@emitSync('welcome', {docpad}, complete)

# Anyomous
tasks.push (complete) =>
# No statistics or username is already identified
return complete() if !mixpanelInstance or @userConfig.username

# User is anonymous, set their username to the hashed and salted mac address
require('getmac').getMac (err,macAddress) =>
return complete() if err

# Hash with salt
try
macAddressHash = require('crypto').createHmac('sha1',docpad.config.hashKey).update(macAddress).digest('hex')
catch err
return complete() if err

# Apply
@userConfig.name ?= "MAC #{macAddressHash}"
@userConfig.username ?= macAddressHash
return complete()

# Track
tasks.push =>
if @userConfig.username
lastLogin = new Date()
countryCode = @getCountryCode()
languageCode = @getLanguageCode()
mixpanelInstance = @getMixpanelInstance()
if mixpanelInstance
if @userConfig.identified isnt true
# identify the new user with mixpanel
mixpanelInstance.people.set(@userConfig.username, {
$email: @userConfig.email
$name: @userConfig.name
$username: @userConfig.username
$created: lastLogin
$last_login: lastLogin
$country_code: countryCode
languageCode: languageCode
})
@updateUserConfig({
identified: true
})
else
# only update last login if we are another day
mixpanelInstance.people.set(@userConfig.username, {
$last_login: new Date()
})
# No stats or no username
return if !mixpanelInstance or !@userConfig.username

# Update the user in mixpanel
lastLogin = new Date()
if @userConfig.identified isnt true
# Identify the new user with mixpanel
mixpanelInstance.people.set(@userConfig.username, {
$created: lastLogin
$username: @userConfig.username
$email: @userConfig.email
$name: @userConfig.name
$last_login: lastLogin
$country_code: @getCountryCode()
languageCode: @getLanguageCode()
})
@updateUserConfig({
identified: true
})
else
# Update existing user if they have already been identified
mixpanelInstance.people.set(@userConfig.username, {
$email: @userConfig.email
$name: @userConfig.name
$last_login: lastLogin
$country_code: @getCountryCode()
languageCode: @getLanguageCode()
})


# DocPad Ready
Expand Down

0 comments on commit fb8de48

Please sign in to comment.