@osano/osano-cmp-react-native 0.19.0 โ 0.19.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/lib/commonjs/ConsentManager.js +23 -0
- package/lib/commonjs/ConsentManager.js.map +1 -1
- package/lib/commonjs/components/Button.js +7 -2
- package/lib/commonjs/components/Button.js.map +1 -1
- package/lib/commonjs/iab/tcf/iab-storage-utils.js +53 -49
- package/lib/commonjs/iab/tcf/iab-storage-utils.js.map +1 -1
- package/lib/commonjs/iab/tcf/middleware.js +20 -23
- package/lib/commonjs/iab/tcf/middleware.js.map +1 -1
- package/lib/commonjs/iab/tcf/reducer.js +0 -22
- package/lib/commonjs/iab/tcf/reducer.js.map +1 -1
- package/lib/commonjs/index.js +16 -2
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/reducer.js +5 -1
- package/lib/commonjs/reducer.js.map +1 -1
- package/lib/commonjs/services/consent.js +182 -81
- package/lib/commonjs/services/consent.js.map +1 -1
- package/lib/commonjs/utils/Translator.js +25 -20
- package/lib/commonjs/utils/Translator.js.map +1 -1
- package/lib/module/ConsentManager.js +23 -0
- package/lib/module/ConsentManager.js.map +1 -1
- package/lib/module/components/Button.js +7 -2
- package/lib/module/components/Button.js.map +1 -1
- package/lib/module/iab/tcf/iab-storage-utils.js +53 -49
- package/lib/module/iab/tcf/iab-storage-utils.js.map +1 -1
- package/lib/module/iab/tcf/middleware.js +22 -25
- package/lib/module/iab/tcf/middleware.js.map +1 -1
- package/lib/module/iab/tcf/reducer.js +1 -23
- package/lib/module/iab/tcf/reducer.js.map +1 -1
- package/lib/module/index.js +17 -3
- package/lib/module/index.js.map +1 -1
- package/lib/module/reducer.js +5 -1
- package/lib/module/reducer.js.map +1 -1
- package/lib/module/services/consent.js +178 -79
- package/lib/module/services/consent.js.map +1 -1
- package/lib/module/utils/Translator.js +25 -20
- package/lib/module/utils/Translator.js.map +1 -1
- package/lib/typescript/src/ConsentManager.d.ts +11 -1
- package/lib/typescript/src/ConsentManager.d.ts.map +1 -1
- package/lib/typescript/src/components/Button.d.ts.map +1 -1
- package/lib/typescript/src/iab/tcf/iab-storage-utils.d.ts +7 -7
- package/lib/typescript/src/iab/tcf/iab-storage-utils.d.ts.map +1 -1
- package/lib/typescript/src/iab/tcf/middleware.d.ts.map +1 -1
- package/lib/typescript/src/iab/tcf/reducer.d.ts +1 -0
- package/lib/typescript/src/iab/tcf/reducer.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/reducer.d.ts.map +1 -1
- package/lib/typescript/src/services/consent.d.ts +28 -0
- package/lib/typescript/src/services/consent.d.ts.map +1 -1
- package/lib/typescript/src/utils/Translator.d.ts +2 -0
- package/lib/typescript/src/utils/Translator.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/ConsentManager.ts +24 -1
- package/src/components/Button.tsx +10 -2
- package/src/iab/tcf/iab-storage-utils.ts +101 -56
- package/src/iab/tcf/middleware.ts +36 -32
- package/src/iab/tcf/reducer.ts +2 -29
- package/src/index.tsx +15 -1
- package/src/reducer.ts +4 -0
- package/src/services/consent.ts +223 -90
- package/src/types/consent-config.d.ts +5 -1
- package/src/types/store.d.ts +5 -0
- package/src/utils/Translator.ts +35 -25
|
@@ -29,27 +29,65 @@ export interface IABConsentData {
|
|
|
29
29
|
enableAdvertiserConsentMode?: boolean;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
osanoLogger.info(
|
|
48
|
-
'โ
All IAB consent keys cleared from both custom and default storage',
|
|
32
|
+
let storageQueue = Promise.resolve();
|
|
33
|
+
|
|
34
|
+
const enqueueStorageOperation = <T>(
|
|
35
|
+
operation: () => Promise<T>,
|
|
36
|
+
): Promise<T> => {
|
|
37
|
+
const result = storageQueue.then(operation, operation);
|
|
38
|
+
storageQueue = result.then(
|
|
39
|
+
() => undefined,
|
|
40
|
+
(error) => {
|
|
41
|
+
osanoLogger.error(
|
|
42
|
+
`IAB storage operation failed: ${String(error)}`,
|
|
43
|
+
error instanceof Error ? error : undefined,
|
|
44
|
+
);
|
|
45
|
+
},
|
|
49
46
|
);
|
|
47
|
+
return result;
|
|
50
48
|
};
|
|
51
49
|
|
|
52
|
-
|
|
50
|
+
const enqueueSetStorage = (key: string, value: string) =>
|
|
51
|
+
enqueueStorageOperation(() => setStorage(key, value));
|
|
52
|
+
|
|
53
|
+
const enqueueSetStorageToDefault = (key: string, value: string) =>
|
|
54
|
+
enqueueStorageOperation(() => setStorageToDefault(key, value));
|
|
55
|
+
|
|
56
|
+
const enqueueSetIntStorageToDefault = (key: string, value: number) =>
|
|
57
|
+
enqueueStorageOperation(() => setIntStorageToDefault(key, value));
|
|
58
|
+
|
|
59
|
+
export const clearAllIABKeys = (
|
|
60
|
+
additionalCustomKeys: string[] = [],
|
|
61
|
+
): Promise<void> =>
|
|
62
|
+
enqueueStorageOperation(async () => {
|
|
63
|
+
osanoLogger.info('๐งน Clearing all IAB consent keys...');
|
|
64
|
+
const operations = [
|
|
65
|
+
...Object.values(IABKeys.LEGACY).map((key) =>
|
|
66
|
+
clearStorageFromDefault(key),
|
|
67
|
+
),
|
|
68
|
+
...DEFAULT_STORAGE_KEYS.IABTCF.map((key) => clearStorageFromDefault(key)),
|
|
69
|
+
...[...CUSTOM_STORAGE_KEYS, ...additionalCustomKeys].map((key) =>
|
|
70
|
+
clearStorage(key),
|
|
71
|
+
),
|
|
72
|
+
];
|
|
73
|
+
const failures = await Promise.all(
|
|
74
|
+
operations.map((operation) =>
|
|
75
|
+
operation.then(
|
|
76
|
+
() => ({ failed: false as const }),
|
|
77
|
+
(error: unknown) => ({ failed: true as const, error }),
|
|
78
|
+
),
|
|
79
|
+
),
|
|
80
|
+
);
|
|
81
|
+
const failure = failures.find((result) => result.failed);
|
|
82
|
+
if (failure?.failed) {
|
|
83
|
+
throw failure.error;
|
|
84
|
+
}
|
|
85
|
+
osanoLogger.info(
|
|
86
|
+
'โ
All IAB consent keys cleared from both custom and default storage',
|
|
87
|
+
);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
export const setAllIABKeys = (consentData: IABConsentData): Promise<void> => {
|
|
53
91
|
const {
|
|
54
92
|
tcString,
|
|
55
93
|
cmpId,
|
|
@@ -72,57 +110,66 @@ export const setAllIABKeys = (consentData: IABConsentData): void => {
|
|
|
72
110
|
const subjectToGDPR = gdprApplies ? '1' : '0';
|
|
73
111
|
|
|
74
112
|
// === Save to Custom Storage ===
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
113
|
+
enqueueSetStorage(IABKeys.IABTCF.CMP_SDK_ID, cmpId.toString());
|
|
114
|
+
enqueueSetStorage(IABKeys.IABTCF.CMP_SDK_VERSION, cmpVersion.toString());
|
|
115
|
+
enqueueSetStorage(IABKeys.IABTCF.POLICY_VERSION, policyVersion);
|
|
116
|
+
enqueueSetStorage(IABKeys.IABTCF.PUBLISHER_CC, publisherCC);
|
|
117
|
+
enqueueSetStorage(IABKeys.IABTCF.GDPR_APPLIES, subjectToGDPR);
|
|
118
|
+
enqueueSetStorage(
|
|
81
119
|
IABKeys.IABTCF.PURPOSE_ONE_TREATMENT,
|
|
82
120
|
purposeOneTreatment ? '1' : '0',
|
|
83
121
|
);
|
|
84
|
-
|
|
122
|
+
enqueueSetStorage(
|
|
85
123
|
IABKeys.IABTCF.USE_NON_STANDARD_TEXTS,
|
|
86
124
|
useNonStandardStacks ? '1' : '0',
|
|
87
125
|
);
|
|
88
|
-
|
|
89
|
-
|
|
126
|
+
enqueueSetStorage(IABKeys.IABTCF.VENDOR_CONSENTS, vendorConsentsString);
|
|
127
|
+
enqueueSetStorage(
|
|
90
128
|
IABKeys.IABTCF.VENDOR_LEGITIMATE_INTERESTS,
|
|
91
129
|
vendorLegitimateInterestsString,
|
|
92
130
|
);
|
|
93
|
-
|
|
94
|
-
|
|
131
|
+
enqueueSetStorage(IABKeys.IABTCF.PURPOSE_CONSENTS, purposeConsentsString);
|
|
132
|
+
enqueueSetStorage(
|
|
95
133
|
IABKeys.IABTCF.PURPOSE_LEGITIMATE_INTERESTS,
|
|
96
134
|
purposeLegitimateInterestsString,
|
|
97
135
|
);
|
|
98
|
-
|
|
136
|
+
enqueueSetStorage(
|
|
99
137
|
IABKeys.IABTCF.SPECIAL_FEATURES_OPT_INS,
|
|
100
138
|
specialFeatureOptinsString,
|
|
101
139
|
);
|
|
102
140
|
|
|
103
141
|
// === Save to Default Storage for AdMob Compatibility ===
|
|
104
142
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
143
|
+
enqueueSetStorageToDefault(IABKeys.LEGACY.CMP_PRESENT, 'true');
|
|
144
|
+
enqueueSetStorageToDefault(IABKeys.LEGACY.SUBJECT_TO_GDPR, subjectToGDPR);
|
|
145
|
+
enqueueSetStorageToDefault(IABKeys.LEGACY.CONSENT_STRING, tcString);
|
|
146
|
+
enqueueSetStorageToDefault(
|
|
109
147
|
IABKeys.LEGACY.PARSED_PURPOSE_CONSENTS,
|
|
110
148
|
purposeConsentsString,
|
|
111
149
|
);
|
|
112
|
-
|
|
150
|
+
enqueueSetStorageToDefault(
|
|
113
151
|
IABKeys.LEGACY.PARSED_VENDOR_CONSENTS,
|
|
114
152
|
vendorConsentsString,
|
|
115
153
|
);
|
|
116
154
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
155
|
+
enqueueSetIntStorageToDefault(
|
|
156
|
+
IABKeys.IABTCF.GDPR_APPLIES,
|
|
157
|
+
gdprApplies ? 1 : 0,
|
|
158
|
+
);
|
|
159
|
+
enqueueSetStorageToDefault(IABKeys.IABTCF.TC_STRING, tcString);
|
|
160
|
+
enqueueSetStorageToDefault(
|
|
161
|
+
IABKeys.IABTCF.PURPOSE_CONSENTS,
|
|
162
|
+
purposeConsentsString,
|
|
163
|
+
);
|
|
164
|
+
enqueueSetStorageToDefault(
|
|
165
|
+
IABKeys.IABTCF.VENDOR_CONSENTS,
|
|
166
|
+
vendorConsentsString,
|
|
167
|
+
);
|
|
168
|
+
enqueueSetStorageToDefault(IABKeys.IABTCF.ADDTL_CONSENT, '');
|
|
122
169
|
|
|
123
170
|
// Handle Google Consent Mode integration
|
|
124
171
|
if (enableAdvertiserConsentMode !== undefined) {
|
|
125
|
-
|
|
172
|
+
enqueueSetIntStorageToDefault(
|
|
126
173
|
IABKeys.IABTCF.ENABLE_ADVERTISER_CONSENT_MODE,
|
|
127
174
|
enableAdvertiserConsentMode ? 1 : 0,
|
|
128
175
|
);
|
|
@@ -143,24 +190,22 @@ export const setAllIABKeys = (consentData: IABConsentData): void => {
|
|
|
143
190
|
osanoLogger.debug(
|
|
144
191
|
`๐ Updated IAB keys: CMP=true, SubjectToGDPR=${subjectToGDPR}, PurposeConsents=${purposeConsentsString.length} chars, VendorConsents=${vendorConsentsString.length} chars`,
|
|
145
192
|
);
|
|
193
|
+
return enqueueStorageOperation(() => Promise.resolve());
|
|
146
194
|
};
|
|
147
195
|
|
|
148
|
-
export const setCustomIABKey = (key: string, value: string):
|
|
149
|
-
|
|
150
|
-
};
|
|
196
|
+
export const setCustomIABKey = (key: string, value: string): Promise<string> =>
|
|
197
|
+
enqueueSetStorage(key, value);
|
|
151
198
|
|
|
152
|
-
export const setDefaultIABKey = (key: string, value: string):
|
|
153
|
-
|
|
154
|
-
};
|
|
199
|
+
export const setDefaultIABKey = (key: string, value: string): Promise<string> =>
|
|
200
|
+
enqueueSetStorageToDefault(key, value);
|
|
155
201
|
|
|
156
|
-
export const setDefaultIABKeyAsInt = (
|
|
157
|
-
|
|
158
|
-
|
|
202
|
+
export const setDefaultIABKeyAsInt = (
|
|
203
|
+
key: string,
|
|
204
|
+
value: number,
|
|
205
|
+
): Promise<number> => enqueueSetIntStorageToDefault(key, value);
|
|
159
206
|
|
|
160
|
-
export const clearCustomIABKey = (key: string): void =>
|
|
161
|
-
clearStorage(key);
|
|
162
|
-
};
|
|
207
|
+
export const clearCustomIABKey = (key: string): Promise<void> =>
|
|
208
|
+
enqueueStorageOperation(() => clearStorage(key));
|
|
163
209
|
|
|
164
|
-
export const clearDefaultIABKey = (key: string): void =>
|
|
165
|
-
clearStorageFromDefault(key);
|
|
166
|
-
};
|
|
210
|
+
export const clearDefaultIABKey = (key: string): Promise<void> =>
|
|
211
|
+
enqueueStorageOperation(() => clearStorageFromDefault(key));
|
|
@@ -8,8 +8,12 @@ import {
|
|
|
8
8
|
setConsent,
|
|
9
9
|
} from './actions';
|
|
10
10
|
import { SET_CONSENT_DATA, setConsentData } from '../actions';
|
|
11
|
-
import {
|
|
12
|
-
|
|
11
|
+
import {
|
|
12
|
+
clearAllIABKeys,
|
|
13
|
+
setAllIABKeys,
|
|
14
|
+
setCustomIABKey,
|
|
15
|
+
} from './iab-storage-utils';
|
|
16
|
+
import { clearStorage, getStorage } from '../../native/OsanoCmp';
|
|
13
17
|
import { getConsentString, getPurposeIds } from './selectors';
|
|
14
18
|
import {
|
|
15
19
|
idRecordToBinaryString,
|
|
@@ -25,12 +29,18 @@ import { Platform } from 'react-native';
|
|
|
25
29
|
import type { Store } from '../../hooks/useThunkReducer';
|
|
26
30
|
import { osanoLogger } from '../../utils/OsanoLogger';
|
|
27
31
|
|
|
32
|
+
const TCF_GPP_SECTIONS = ['tcfeuv2', 'tcfcav1'];
|
|
33
|
+
|
|
28
34
|
export const makeMiddleware: IabMiddlewareFactory = (
|
|
29
35
|
initOptions: IabInitOptions,
|
|
30
36
|
) => {
|
|
31
37
|
const { createConsentPayload, gppSection, version } = initOptions;
|
|
32
38
|
const parseConsentString = makeParseConsentString(initOptions);
|
|
33
39
|
const formatConsentString = makeFormatConsentString(initOptions);
|
|
40
|
+
const clearStoredTcfConsent = (configId: string) =>
|
|
41
|
+
clearAllIABKeys(
|
|
42
|
+
TCF_GPP_SECTIONS.map((section) => `${section}_${configId}`),
|
|
43
|
+
);
|
|
34
44
|
return (store: Store<OsanoState & IabState, OsanoAction>) =>
|
|
35
45
|
(next: (action: OsanoAction) => OsanoState & IabState) =>
|
|
36
46
|
(action: OsanoAction) => {
|
|
@@ -64,6 +74,20 @@ export const makeMiddleware: IabMiddlewareFactory = (
|
|
|
64
74
|
}
|
|
65
75
|
store.dispatch(setConsent(payload));
|
|
66
76
|
};
|
|
77
|
+
// Wipe instead of rehydrating a granted string. A localStorage-only
|
|
78
|
+
// path left IABTCF_* behind; OsanoCmp covers every platform.
|
|
79
|
+
if (newState.consentInvalidated) {
|
|
80
|
+
newState.iab.consentStrings = {
|
|
81
|
+
...newState.iab.consentStrings,
|
|
82
|
+
[gppSection]: '',
|
|
83
|
+
};
|
|
84
|
+
store.dispatch(setConsentData(gppSection, ''));
|
|
85
|
+
clearStoredTcfConsent(configId).then(
|
|
86
|
+
() => resConsent(null),
|
|
87
|
+
() => resConsent(null),
|
|
88
|
+
);
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
67
91
|
switch (Platform.OS) {
|
|
68
92
|
case 'ios':
|
|
69
93
|
case 'android':
|
|
@@ -87,20 +111,12 @@ export const makeMiddleware: IabMiddlewareFactory = (
|
|
|
87
111
|
break;
|
|
88
112
|
}
|
|
89
113
|
case CLEAR_CONSENT: {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
clearAllIABKeys();
|
|
96
|
-
break;
|
|
97
|
-
default:
|
|
98
|
-
try {
|
|
99
|
-
window.localStorage.removeItem(`${gppSection}_${configId}`);
|
|
100
|
-
} catch {}
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
114
|
+
newState.iab.consentStrings = {
|
|
115
|
+
...newState.iab.consentStrings,
|
|
116
|
+
[gppSection]: '',
|
|
117
|
+
};
|
|
103
118
|
store.dispatch(setConsentData(gppSection, ''));
|
|
119
|
+
clearStoredTcfConsent(configId).catch(() => {});
|
|
104
120
|
break;
|
|
105
121
|
}
|
|
106
122
|
case SET_ALL_PURPOSE_CONSENT: {
|
|
@@ -147,22 +163,10 @@ export const makeMiddleware: IabMiddlewareFactory = (
|
|
|
147
163
|
case SAVE_BEGIN: {
|
|
148
164
|
if (config && configId) {
|
|
149
165
|
const consentPayload = createConsentPayload(newState);
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
setStorage(
|
|
155
|
-
`${gppSection}_${configId}`,
|
|
156
|
-
JSON.stringify(consentPayload),
|
|
157
|
-
);
|
|
158
|
-
} catch (err) {
|
|
159
|
-
osanoLogger.error(
|
|
160
|
-
`Failed to save consent to device storage: ${err}`,
|
|
161
|
-
err instanceof Error ? err : undefined,
|
|
162
|
-
);
|
|
163
|
-
}
|
|
164
|
-
break;
|
|
165
|
-
}
|
|
166
|
+
setCustomIABKey(
|
|
167
|
+
`${gppSection}_${configId}`,
|
|
168
|
+
JSON.stringify(consentPayload),
|
|
169
|
+
);
|
|
166
170
|
store.dispatch(
|
|
167
171
|
setConsentData(gppSection, formatConsentString(config, newState)),
|
|
168
172
|
);
|
|
@@ -183,7 +187,7 @@ export const makeMiddleware: IabMiddlewareFactory = (
|
|
|
183
187
|
osanoLogger.info(`Setting new consent string -> ${value}`);
|
|
184
188
|
const consent = parseConsentString(value);
|
|
185
189
|
|
|
186
|
-
|
|
190
|
+
setCustomIABKey(storageKey, value);
|
|
187
191
|
|
|
188
192
|
const consentData = {
|
|
189
193
|
tcString: value,
|
package/src/iab/tcf/reducer.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CLEAR_CONSENT, RELOAD,
|
|
1
|
+
import { CLEAR_CONSENT, RELOAD, SET_CONFIG } from '../../actions';
|
|
2
2
|
import type { OsanoAction, OsanoState } from '../../types/store';
|
|
3
3
|
import {
|
|
4
4
|
SET_CONSENT,
|
|
@@ -21,8 +21,6 @@ import {
|
|
|
21
21
|
import type { Config } from '../../types/consent-config';
|
|
22
22
|
import type { IabInitOptions } from './types';
|
|
23
23
|
import type { IabState } from '../types';
|
|
24
|
-
import { Platform } from 'react-native';
|
|
25
|
-
import { setStorage } from '../../native/OsanoCmp';
|
|
26
24
|
|
|
27
25
|
export const initialState = {
|
|
28
26
|
iab: {
|
|
@@ -91,7 +89,7 @@ const updateOptions = (
|
|
|
91
89
|
};
|
|
92
90
|
|
|
93
91
|
export default function makeReducer(initOptions: IabInitOptions) {
|
|
94
|
-
const { createConsentPayload,
|
|
92
|
+
const { createConsentPayload, version } = initOptions;
|
|
95
93
|
return (state: OsanoState & IabState, action: OsanoAction) => {
|
|
96
94
|
const { type, payload } = action;
|
|
97
95
|
switch (type) {
|
|
@@ -135,31 +133,6 @@ export default function makeReducer(initOptions: IabInitOptions) {
|
|
|
135
133
|
};
|
|
136
134
|
}
|
|
137
135
|
|
|
138
|
-
case SAVE_BEGIN: {
|
|
139
|
-
const config = state.config;
|
|
140
|
-
if (config?.configId && config.iabEnabled) {
|
|
141
|
-
const consentPayload = createConsentPayload(state);
|
|
142
|
-
switch (Platform.OS) {
|
|
143
|
-
case 'ios':
|
|
144
|
-
case 'android':
|
|
145
|
-
setStorage(
|
|
146
|
-
`${gppSection}_${config.configId}`,
|
|
147
|
-
JSON.stringify(consentPayload),
|
|
148
|
-
);
|
|
149
|
-
break;
|
|
150
|
-
default:
|
|
151
|
-
try {
|
|
152
|
-
window.localStorage.setItem(
|
|
153
|
-
`${gppSection}_${config.configId}`,
|
|
154
|
-
JSON.stringify(consentPayload),
|
|
155
|
-
);
|
|
156
|
-
} catch {}
|
|
157
|
-
break;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
return state;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
136
|
case CLEAR_CONSENT: {
|
|
164
137
|
const consentPayload = createConsentPayload();
|
|
165
138
|
return {
|
package/src/index.tsx
CHANGED
|
@@ -2,6 +2,7 @@ import React, { memo, useCallback, useEffect, useMemo, useRef } from 'react';
|
|
|
2
2
|
import { Platform, UIManager } from 'react-native';
|
|
3
3
|
import {
|
|
4
4
|
CLEAR_CONSENT,
|
|
5
|
+
SAVE_BEGIN,
|
|
5
6
|
reload,
|
|
6
7
|
setConfig,
|
|
7
8
|
setLocale,
|
|
@@ -105,7 +106,13 @@ export const Osano: React.FunctionComponent<
|
|
|
105
106
|
}),
|
|
106
107
|
);
|
|
107
108
|
}
|
|
108
|
-
|
|
109
|
+
dispatch({ type: SAVE_BEGIN, payload: consentedCategories });
|
|
110
|
+
return recordConsent(consentManager.current, consentedCategories).then(
|
|
111
|
+
(recordedConsent) => {
|
|
112
|
+
consentManager.current.triggerGoogleConsentUpdate(recordedConsent);
|
|
113
|
+
return recordedConsent;
|
|
114
|
+
},
|
|
115
|
+
);
|
|
109
116
|
},
|
|
110
117
|
[],
|
|
111
118
|
);
|
|
@@ -208,6 +215,7 @@ export const Osano: React.FunctionComponent<
|
|
|
208
215
|
})
|
|
209
216
|
.then((reloadProps) => {
|
|
210
217
|
// We need to reset the state when the configId or customerId changes
|
|
218
|
+
const consentInvalidated = consentManager.current.consentInvalidated;
|
|
211
219
|
dispatch(
|
|
212
220
|
reload({
|
|
213
221
|
// Pass config so init-time opt-out normalization runs on the
|
|
@@ -217,8 +225,14 @@ export const Osano: React.FunctionComponent<
|
|
|
217
225
|
configId: reloadProps.configId,
|
|
218
226
|
customerId: reloadProps.customerId,
|
|
219
227
|
consent: reloadProps.consent,
|
|
228
|
+
// Signals the IAB TCF middleware to wipe (not rehydrate) the
|
|
229
|
+
// stored TC string on this RELOAD; see its RELOAD handler.
|
|
230
|
+
consentInvalidated,
|
|
220
231
|
}),
|
|
221
232
|
);
|
|
233
|
+
if (consentManager.current.consentPromptRequired) {
|
|
234
|
+
dispatch(showDialog());
|
|
235
|
+
}
|
|
222
236
|
return reloadProps;
|
|
223
237
|
})
|
|
224
238
|
.catch(() => {
|
package/src/reducer.ts
CHANGED
|
@@ -127,6 +127,10 @@ export function reducer(state: OsanoState, action: OsanoAction): OsanoState {
|
|
|
127
127
|
...state,
|
|
128
128
|
consent,
|
|
129
129
|
savedConsent: { ...consent } as Record<ConsentCategoryType, boolean>,
|
|
130
|
+
// The user just re-consented, so the invalidation is resolved. Clear
|
|
131
|
+
// the marker so a later SET_CONFIG rehydrates this freshly-saved TCF
|
|
132
|
+
// payload instead of wiping it (the IAB middleware wipes while set).
|
|
133
|
+
consentInvalidated: false,
|
|
130
134
|
};
|
|
131
135
|
}
|
|
132
136
|
case CLEAR_CONSENT: {
|