Skip to content

Commit

Permalink
Fix sua low entropy check for empty objects (#10167)
Browse files Browse the repository at this point in the history
  • Loading branch information
pycnvr authored Jul 12, 2023
1 parent f606397 commit 89a1e1e
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 3 deletions.
10 changes: 8 additions & 2 deletions src/fpd/sua.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ export const HIGH_ENTROPY_HINTS = [
'fullVersionList'
]

export const LOW_ENTROPY_HINTS = [
'brands',
'mobile',
'platform'
]

/**
* Returns low entropy UA client hints encoded as an ortb2.6 device.sua object; or null if no UA client hints are available.
*/
Expand All @@ -32,7 +38,7 @@ export const getLowEntropySUA = lowEntropySUAAccessor();
export const getHighEntropySUA = highEntropySUAAccessor();

export function lowEntropySUAAccessor(uaData = window.navigator?.userAgentData) {
const sua = isEmpty(uaData) ? null : Object.freeze(uaDataToSUA(SUA_SOURCE_LOW_ENTROPY, uaData));
const sua = (uaData && LOW_ENTROPY_HINTS.some(h => typeof uaData[h] !== 'undefined')) ? Object.freeze(uaDataToSUA(SUA_SOURCE_LOW_ENTROPY, uaData)) : null;
return function () {
return sua;
}
Expand Down Expand Up @@ -85,7 +91,7 @@ export function uaDataToSUA(source, uaData) {
if (uaData.fullVersionList || uaData.brands) {
sua.browsers = (uaData.fullVersionList || uaData.brands).map(({brand, version}) => toBrandVersion(brand, version));
}
if (uaData.hasOwnProperty('mobile')) {
if (typeof uaData['mobile'] !== 'undefined') {
sua.mobile = uaData.mobile ? 1 : 0;
}
['model', 'bitness', 'architecture'].forEach(prop => {
Expand Down
8 changes: 7 additions & 1 deletion test/spec/fpd/enrichment_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,13 @@ describe('FPD enrichment', () => {

describe('sua', () => {
it('does not set device.sua if resolved sua is null', () => {
sandbox.stub(dep, 'getHighEntropySUA').returns(Promise.resolve())
sandbox.stub(dep, 'getHighEntropySUA').returns(Promise.resolve());
// Add hints so it will attempt to retrieve high entropy values
config.setConfig({
firstPartyData: {
uaHints: ['bitness'],
}
});
return fpd().then(ortb2 => {
expect(ortb2.device.sua).to.not.exist;
})
Expand Down
12 changes: 12 additions & 0 deletions test/spec/fpd/sua_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,14 @@ describe('uaDataToSUA', () => {
});

describe('lowEntropySUAAccessor', () => {
// Set up a mock data with readonly property
class MockUserAgentData {}
Object.defineProperty(MockUserAgentData.prototype, 'mobile', {
value: false,
writable: false,
enumerable: true
});

function getSUA(uaData) {
return lowEntropySUAAccessor(uaData)();
}
Expand All @@ -181,6 +189,10 @@ describe('lowEntropySUAAccessor', () => {
it('should return null if uaData is empty', () => {
expect(getSUA({})).to.eql(null);
})

it('should return mobile and source', () => {
expect(getSUA(new MockUserAgentData())).to.eql({mobile: 0, source: 1})
})
});

describe('highEntropySUAAccessor', () => {
Expand Down

0 comments on commit 89a1e1e

Please sign in to comment.