Skip to content
This repository has been archived by the owner on Jan 27, 2025. It is now read-only.

Commit

Permalink
[CM-1105] Send provided idcookie to our backend (#309)
Browse files Browse the repository at this point in the history
  • Loading branch information
mschuwalow authored Jan 18, 2024
1 parent acfdb5b commit c878e00
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 6 deletions.
7 changes: 7 additions & 0 deletions src/idex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { asParamOrEmpty, asStringParamWhen, asStringParam, mapAsParams } from '.
import { DEFAULT_IDEX_AJAX_TIMEOUT, DEFAULT_IDEX_URL, DEFAULT_REQUESTED_ATTRIBUTES } from './utils/consts'
import { IdentityResolutionConfig, State, ResolutionParams, EventBus, RetrievedIdentifier } from './types'
import { WrappedCallHandler } from './handlers/call-handler'
import { md5 } from 'tiny-hashes/dist'

export type ResolutionMetadata = {
expiresAt?: Date
Expand All @@ -22,6 +23,7 @@ export class IdentityResolver {
tuples: [string, string][]
privacyMode: boolean
resolvedIdCookie: string | null
idCookieMode: 'provided' | 'generated'

constructor (
config: State,
Expand All @@ -41,6 +43,7 @@ export class IdentityResolver {
this.requestedAttributes = this.idexConfig.requestedAttributes || DEFAULT_REQUESTED_ATTRIBUTES
this.privacyMode = nonNullConfig.privacyMode ?? false
this.resolvedIdCookie = nonNullConfig.resolvedIdCookie
this.idCookieMode = nonNullConfig.idCookie?.mode ?? 'generated'
this.tuples = []

this.tuples.push(...asStringParam('duid', nonNullConfig.peopleVerifiedId))
Expand All @@ -53,6 +56,10 @@ export class IdentityResolver {
this.tuples.push(...asStringParam('gpp_as', nonNullConfig.gppApplicableSections?.join(',')))
this.tuples.push(...asStringParam('cd', nonNullConfig.cookieDomain))

if (this.idCookieMode === 'provided' && this.resolvedIdCookie) {
this.tuples.push(...asStringParam('ic', md5(this.resolvedIdCookie)))
}

this.externalIds.forEach(retrievedIdentifier => {
this.tuples.push(...asStringParam(retrievedIdentifier.name, retrievedIdentifier.value))
})
Expand Down
14 changes: 11 additions & 3 deletions src/pixel/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import { asStringParam, asParamOrEmpty, asStringParamWhen, asStringParamTransfor
import { toParams } from '../utils/url'
import { EventBus, State } from '../types'
import { collectUrl } from './url-collector'
import { md5 } from 'tiny-hashes/dist'

type ParamExtractor = (state: State) => [string, string][]

const noOpEvents = ['setemail', 'setemailhash', 'sethashedemail']

function ifDefined<K extends keyof State>(key: K, fun: (value: NonNullable<State[K]>) => [string, string][]): (state: State) => [string, string][] {
function ifDefined<K extends keyof State>(key: K, fun: (value: NonNullable<State[K]>) => [string, string][]): ParamExtractor {
return state => {
const value = state[key]
if (nonNull(value)) {
Expand All @@ -20,7 +23,11 @@ function ifDefined<K extends keyof State>(key: K, fun: (value: NonNullable<State
}
}

const paramExtractors: ((state: State) => [string, string][])[] = [
function ifState(predicate: (state: State) => boolean, extractor: ParamExtractor): ParamExtractor {
return state => predicate(state) ? extractor(state) : []
}

const paramExtractors: ParamExtractor[] = [
ifDefined('appId', aid => asStringParam('aid', aid)),
ifDefined('distributorId', did => asStringParam('did', did)),
ifDefined('eventSource', source => asParamOrEmpty('se', source, (s) => base64UrlEncode(JSON.stringify(s, replacer)))),
Expand Down Expand Up @@ -67,7 +74,8 @@ const paramExtractors: ((state: State) => [string, string][])[] = [
ifDefined('contextElements', contextElements => asStringParam('c', contextElements)),
ifDefined('gppString', gppString => asStringParam('gpp_s', gppString)),
ifDefined('gppApplicableSections', gppApplicableSections => asStringParamTransform('gpp_as', gppApplicableSections, (gppAs) => gppAs.join(','))),
ifDefined('cookieDomain', d => asStringParam('cd', d))
ifDefined('cookieDomain', d => asStringParam('cd', d)),
ifState(state => state.idCookie?.mode === 'provided', ifDefined('resolvedIdCookie', p => asStringParam('ic', md5(p))))
]

export class Query {
Expand Down
1 change: 0 additions & 1 deletion test/unit/events/error-pixel.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ describe('ErrorPixel', () => {
eventBus.emitErrorWithMessage('Error', 'some other message')
expect(errors.length).to.eql(1)
const errorDetails = errors[0].data.errorDetails
console.log(errors[0].data)
// @ts-expect-error
expect(errorDetails.message).to.eql('some other message')
// @ts-expect-error
Expand Down
1 change: 0 additions & 1 deletion test/unit/events/event-bus.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ describe('EventsBus in a window', () => {
const name = 'testBus'
// @ts-expect-error
const firstBus = GlobalEventBus(name)
firstBus.on('a-dell', () => console.log('Hello, its me'))
// @ts-expect-error
const secondBus = GlobalEventBus(name)
expect(firstBus).to.eql(secondBus)
Expand Down
14 changes: 14 additions & 0 deletions test/unit/idex/identity-resolver.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,4 +327,18 @@ describe('IdentityResolver without cache', () => {
identityResolver.resolve(successCallback, () => {}, { resolve: ['idcookie'] })
requestToComplete.respond(200, { 'Content-Type': 'application/json' }, JSON.stringify({}))
})

it('should include the idcookie in the url if the mode is provided', () => {
const value = 'foo'
const identityResolver = new IdentityResolver({ resolvedIdCookie: value, idCookie: { mode: 'provided' } }, calls)

expect(identityResolver.getUrl({})).to.eq('https://idx.liadm.com/idex/unknown/any?ic=acbd18db4cc2f85cedef654fccc4a4d8')
})

it('should not include the idcookie in the url if the mode is generated', () => {
const value = 'foo'
const identityResolver = new IdentityResolver({ resolvedIdCookie: value, idCookie: { mode: 'generated' } }, calls)

expect(identityResolver.getUrl({})).to.eq('https://idx.liadm.com/idex/unknown/any')
})
})
1 change: 0 additions & 1 deletion test/unit/minimal-live-connect.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ describe('MinimalLiveConnect', () => {
it('should accept a single event and put it in the queue', () => {
const lc = MinimalLiveConnect({ globalVarName: 'liQ' }, storage, calls)
lc.push({ event: 'some' })
console.log(window.liQ)
expect(window.liQ.length).to.eql(1)
})

Expand Down
37 changes: 37 additions & 0 deletions test/unit/pixel/state.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -442,4 +442,41 @@ describe('EventComposition', () => {
expect(event.asQuery().toQueryString()).to.eql('?did=did-9898&duid=213245')
assert.includeDeepMembers(event.asTuples(), [['did', 'did-9898'], ['duid', '213245']])
})

it('should send ic if idcookie is in mode provided', () => {
const eventBus = LocalEventBus()
const pixelData = {
idCookie: {
mode: 'provided',
strategy: 'cookie',
name: 'test-name'
},
resolvedIdCookie: '123'
}
const event = new StateWrapper(pixelData, eventBus)

// golden test. md5 hash of 123
const expected = '202cb962ac59075b964b07152d234b70'

expect(event.data).to.eql(pixelData)
expect(event.asQuery().toQueryString()).to.eql(`?ic=${expected}`)
assert.includeDeepMembers(event.asTuples(), [['ic', expected]])
})

it('should not send ic if idcookie is in mode generated', () => {
const eventBus = LocalEventBus()
const pixelData = {
idCookie: {
mode: 'generated',
strategy: 'cookie',
name: 'test-name'
},
resolvedIdCookie: '123'
}
const event = new StateWrapper(pixelData, eventBus)

expect(event.data).to.eql(pixelData)
expect(event.asQuery().toQueryString()).to.be.empty()
assert.includeDeepMembers(event.asTuples(), [])
})
})

0 comments on commit c878e00

Please sign in to comment.