UNPKG

@segment/analytics-react-native

Version:

The hassle-free way to add Segment analytics to your React-Native app.

139 lines (137 loc) 4.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ConsentPlugin = void 0; var _plugin = require("../plugin"); var _types = require("../types"); var _SegmentDestination = require("./SegmentDestination"); const CONSENT_PREF_UPDATE_EVENT = 'Segment Consent Preference'; /** * This plugin interfaces with the consent provider and it: * * - stamps all events with the consent metadata. * - augments all destinations with a consent filter plugin that prevents events from reaching them if * they are not compliant current consent setup * - listens for consent change from the provider and notifies Segment */ class ConsentPlugin extends _plugin.Plugin { type = _types.PluginType.before; categories = []; queuedEvents = []; consentStarted = false; constructor(consentCategoryProvider) { super(); this.consentCategoryProvider = consentCategoryProvider; } update(_settings, _type) { const consentSettings = this.analytics?.consentSettings.get(); this.categories = consentSettings?.allCategories || []; this.consentCategoryProvider.setApplicableCategories(this.categories); } configure(analytics) { super.configure(analytics); analytics.getPlugins().forEach(this.injectConsentFilterIfApplicable); analytics.onPluginLoaded(this.injectConsentFilterIfApplicable); this.consentCategoryProvider.onConsentChange(() => { this.notifyConsentChange(); }); let lastDeviceAttrs = analytics.context.get()?.device; analytics.context.onChange(c => { const newAttrs = c?.device; if (newAttrs?.adTrackingEnabled !== lastDeviceAttrs?.adTrackingEnabled || newAttrs?.advertisingId !== lastDeviceAttrs?.advertisingId || newAttrs?.trackingStatus !== lastDeviceAttrs?.trackingStatus) { this.notifyConsentChange(); } lastDeviceAttrs = newAttrs; }); } async execute(event) { if (this.consentStarted === true) { event.context = { ...event.context, consent: { categoryPreferences: await this.consentCategoryProvider.getConsentStatus() } }; return event; } if (this.consentStarted === false) { // constrain the queue to avoid running out of memory if consent is never started if (this.queuedEvents.length <= 1000) { this.queuedEvents.push(event); return; } return; } return; } shutdown() { this.consentCategoryProvider.shutdown?.(); } injectConsentFilterIfApplicable = plugin => { if (this.isDestinationPlugin(plugin)) { plugin.add(new ConsentFilterPlugin(event => { const allCategories = this.analytics?.consentSettings.get()?.allCategories || []; const settings = this.analytics?.settings.get() || {}; const preferences = event.context?.consent?.categoryPreferences || {}; if (plugin.key === _SegmentDestination.SEGMENT_DESTINATION_KEY) { const noneConsented = allCategories.every(category => !preferences[category]); return this.isConsentUpdateEvent(event) || !this.isConsentFeatureSetup() || !(noneConsented && !this.hasUnmappedDestinations()); } const integrationSettings = settings?.[plugin.key]; if (this.containsConsentSettings(integrationSettings)) { const categories = integrationSettings.consentSettings.categories; return !this.isConsentUpdateEvent(event) && categories.every(category => preferences?.[category]); } return true; })); } }; isDestinationPlugin(plugin) { return plugin.type === _types.PluginType.destination; } containsConsentSettings = settings => { return typeof settings?.consentSettings?.categories === 'object'; }; isConsentUpdateEvent(event) { return event.event === CONSENT_PREF_UPDATE_EVENT; } hasUnmappedDestinations() { return this.analytics?.consentSettings.get()?.hasUnmappedDestinations === true; } isConsentFeatureSetup() { return typeof this.analytics?.consentSettings.get() === 'object'; } notifyConsentChange() { // actual preferences will be attached in the execute method this.analytics?.track(CONSENT_PREF_UPDATE_EVENT).catch(e => { throw e; }); } start() { this.consentStarted = true; this.sendQueuedEvents(); } sendQueuedEvents() { this.queuedEvents.forEach(event => { this.analytics?.process(event); }); this.queuedEvents = []; } } /** * This plugin reads the consent metadata set on the context object and then drops the events * if they are going into a destination which violates's set consent preferences */ exports.ConsentPlugin = ConsentPlugin; class ConsentFilterPlugin extends _plugin.Plugin { type = _types.PluginType.before; constructor(shouldAllowEvent) { super(); this.shouldAllowEvent = shouldAllowEvent; } execute(event) { return this.shouldAllowEvent(event) ? event : undefined; } } //# sourceMappingURL=ConsentPlugin.js.map