Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,21 @@ __gpp("removeEventListener", callback?, parameter?)
| ustn | 22 | GpcSegmentType | 2 bit int. Value is 1 |
| ustn | 22 | GpcSegmentIncluded | Boolean. Default is true |
| ustn | 22 | Gpc | Boolean |
| usmn | 23 | Version | 6 bit int. Value is 1 |
| usmn | 23 | ProcessingNotice | 2 bit int. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | SaleOptOutNotice | 2 bit int. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | TargetedAdvertisingOptOutNotice | 2 bit int. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | SaleOptOut | 2 bit int. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | TargetedAdvertisingOptOut | 2 bit int. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | SensitiveDataProcessing | 2 bit int array of size 8. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | KnownChildSensitiveDataConsents | 2 bit int. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | AdditionalDataProcessingConsent | 2 bit int. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | MspaCoveredTransaction | 2 bit int. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | MspaOptOutOptionMode | 2 bit int. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | MspaServiceProviderMode | 2 bit int. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | GpcSegmentType | 2 bit int. Value is 1 |
| usmn | 23 | GpcSegmentIncluded | Boolean. Default is true |
| usmn | 23 | Gpc | Boolean |

## Example Usage / Encoder / Decoder

Expand Down
1 change: 1 addition & 0 deletions modules/cmpapi/.mocharc.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"./test/encoder/section/UsDe.test.ts",
"./test/encoder/section/UsFl.test.ts",
"./test/encoder/section/UsIa.test.ts",
"./test/encoder/section/UsMn.test.ts",
"./test/encoder/section/UsMt.test.ts",
"./test/encoder/section/UsNat.test.ts",
"./test/encoder/section/UsNe.test.ts",
Expand Down
15 changes: 15 additions & 0 deletions modules/cmpapi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,21 @@ __gpp("removeEventListener", callback?, parameter?)
| ustn | 22 | GpcSegmentType | 2 bit int. Value is 1 |
| ustn | 22 | GpcSegmentIncluded | Boolean. Default is true |
| ustn | 22 | Gpc | Boolean |
| usmn | 23 | Version | 6 bit int. Value is 1 |
| usmn | 23 | ProcessingNotice | 2 bit int. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | SaleOptOutNotice | 2 bit int. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | TargetedAdvertisingOptOutNotice | 2 bit int. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | SaleOptOut | 2 bit int. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | TargetedAdvertisingOptOut | 2 bit int. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | SensitiveDataProcessing | 2 bit int array of size 8. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | KnownChildSensitiveDataConsents | 2 bit int. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | AdditionalDataProcessingConsent | 2 bit int. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | MspaCoveredTransaction | 2 bit int. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | MspaOptOutOptionMode | 2 bit int. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | MspaServiceProviderMode | 2 bit int. 0=Not applicable, 1=Yes, 2=No |
| usmn | 23 | GpcSegmentType | 2 bit int. Value is 1 |
| usmn | 23 | GpcSegmentIncluded | Boolean. Default is true |
| usmn | 23 | Gpc | Boolean |

## Example Usage / Encoder / Decoder

Expand Down
10 changes: 10 additions & 0 deletions modules/cmpapi/src/encoder/GppModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { UsNe } from "./section/UsNe.js";
import { UsNh } from "./section/UsNh.js";
import { UsNj } from "./section/UsNj.js";
import { UsTn } from "./section/UsTn.js";
import { UsMn } from "./section/UsMn.js";

export class GppModel {
private sections = new Map<string, EncodableSection>();
Expand Down Expand Up @@ -103,6 +104,9 @@ export class GppModel {
} else if (sectionName === UsTn.NAME) {
section = new UsTn();
this.sections.set(UsTn.NAME, section);
} else if (sectionName === UsMn.NAME) {
section = new UsMn();
this.sections.set(UsMn.NAME, section);
}
} else {
section = this.sections.get(sectionName);
Expand Down Expand Up @@ -335,6 +339,9 @@ export class GppModel {
} else if (sectionIds[i] === UsTn.ID) {
let section = new UsTn(encodedSections[i + 1]);
sections.set(UsTn.NAME, section);
} else if (sectionIds[i] === UsMn.ID) {
let section = new UsMn(encodedSections[i + 1]);
sections.set(UsMn.NAME, section);
}
}
}
Expand Down Expand Up @@ -440,6 +447,9 @@ export class GppModel {
} else if (sectionName === UsTn.NAME) {
section = new UsTn();
this.sections.set(UsTn.NAME, section);
} else if (sectionName === UsMn.NAME) {
section = new UsMn();
this.sections.set(UsMn.NAME, section);
}
} else {
section = this.sections.get(sectionName);
Expand Down
35 changes: 35 additions & 0 deletions modules/cmpapi/src/encoder/field/UsMnField.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
export enum UsMnField {
VERSION = "Version",
PROCESSING_NOTICE = "ProcessingNotice",
SALE_OPT_OUT_NOTICE = "SaleOptOutNotice",
TARGETED_ADVERTISING_OPT_OUT_NOTICE = "TargetedAdvertisingOptOutNotice",
SALE_OPT_OUT = "SaleOptOut",
TARGETED_ADVERTISING_OPT_OUT = "TargetedAdvertisingOptOut",
SENSITIVE_DATA_PROCESSING = "SensitiveDataProcessing",
KNOWN_CHILD_SENSITIVE_DATA_CONSENTS = "KnownChildSensitiveDataConsents",
ADDITIONAL_DATA_PROCESSING_CONSENT = "AdditionalDataProcessingConsent",
MSPA_COVERED_TRANSACTION = "MspaCoveredTransaction",
MSPA_OPT_OUT_OPTION_MODE = "MspaOptOutOptionMode",
MSPA_SERVICE_PROVIDER_MODE = "MspaServiceProviderMode",

GPC_SEGMENT_TYPE = "GpcSegmentType",
GPC_SEGMENT_INCLUDED = "GpcSegmentIncluded",
GPC = "Gpc",
}

export const UsMn_CORE_SEGMENT_FIELD_NAMES = [
UsMnField.VERSION,
UsMnField.PROCESSING_NOTICE,
UsMnField.SALE_OPT_OUT_NOTICE,
UsMnField.TARGETED_ADVERTISING_OPT_OUT_NOTICE,
UsMnField.SALE_OPT_OUT,
UsMnField.TARGETED_ADVERTISING_OPT_OUT,
UsMnField.SENSITIVE_DATA_PROCESSING,
UsMnField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS,
UsMnField.ADDITIONAL_DATA_PROCESSING_CONSENT,
UsMnField.MSPA_COVERED_TRANSACTION,
UsMnField.MSPA_OPT_OUT_OPTION_MODE,
UsMnField.MSPA_SERVICE_PROVIDER_MODE,
];

export const UsMn_GPC_SEGMENT_FIELD_NAMES = [UsMnField.GPC_SEGMENT_TYPE, UsMnField.GPC];
1 change: 1 addition & 0 deletions modules/cmpapi/src/encoder/field/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export * from "./UsCtField.js";
export * from "./UsDeField.js";
export * from "./UsFlField.js";
export * from "./UsIaField.js";
export * from "./UsMnField.js";
export * from "./UsMtField.js";
export * from "./UsNatField.js";
export * from "./UsNeField.js";
Expand Down
3 changes: 3 additions & 0 deletions modules/cmpapi/src/encoder/section/Sections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { UsNe } from "./UsNe.js";
import { UsNh } from "./UsNh.js";
import { UsNj } from "./UsNj.js";
import { UsTn } from "./UsTn.js";
import { UsMn } from "./UsMn.js";

export class Sections {
public static SECTION_ID_NAME_MAP = new Map([
Expand All @@ -39,6 +40,7 @@ export class Sections {
[UsNh.ID, UsNh.NAME],
[UsNj.ID, UsNj.NAME],
[UsTn.ID, UsTn.NAME],
[UsMn.ID, UsMn.NAME],
]);
public static SECTION_ORDER = [
TcfEuV2.NAME,
Expand All @@ -60,5 +62,6 @@ export class Sections {
UsNh.NAME,
UsNj.NAME,
UsTn.NAME,
UsMn.NAME
];
}
77 changes: 77 additions & 0 deletions modules/cmpapi/src/encoder/section/UsMn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { UsMnField } from "../field/UsMnField.js";
import { EncodableSegment } from "../segment/EncodableSegment.js";
import { UsMnCoreSegment } from "../segment/UsMnCoreSegment.js";
import { UsMnGpcSegment } from "../segment/UsMnGpcSegment.js";
import { AbstractLazilyEncodableSection } from "./AbstractLazilyEncodableSection.js";

export class UsMn extends AbstractLazilyEncodableSection {
public static readonly ID = 23;
public static readonly VERSION = 1;
public static readonly NAME = "usmn";

constructor(encodedString?: string) {
super();
if (encodedString && encodedString.length > 0) {
this.decode(encodedString);
}
}

//Overriden
public getId(): number {
return UsMn.ID;
}

//Overriden
public getName(): string {
return UsMn.NAME;
}

//Override
public getVersion(): number {
return UsMn.VERSION;
}

//Overriden
protected initializeSegments(): EncodableSegment[] {
let segments: EncodableSegment[] = [];
segments.push(new UsMnCoreSegment());
segments.push(new UsMnGpcSegment());
return segments;
}

//Overriden
protected decodeSection(encodedString: string): EncodableSegment[] {
let segments: EncodableSegment[] = this.initializeSegments();

if (encodedString != null && encodedString.length !== 0) {
let encodedSegments = encodedString.split(".");

if (encodedSegments.length > 0) {
segments[0].decode(encodedSegments[0]);
}

if (encodedSegments.length > 1) {
segments[1].setFieldValue(UsMnField.GPC_SEGMENT_INCLUDED, true);
segments[1].decode(encodedSegments[1]);
} else {
segments[1].setFieldValue(UsMnField.GPC_SEGMENT_INCLUDED, false);
}
}

return segments;
}

// Overriden
protected encodeSection(segments: EncodableSegment[]): string {
let encodedSegments: string[] = [];

if (segments.length >= 1) {
encodedSegments.push(segments[0].encode());
if (segments.length >= 2 && segments[1].getFieldValue(UsMnField.GPC_SEGMENT_INCLUDED) === true) {
encodedSegments.push(segments[1].encode());
}
}

return encodedSegments.join(".");
}
}
1 change: 1 addition & 0 deletions modules/cmpapi/src/encoder/section/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export * from "./UsCt.js";
export * from "./UsDe.js";
export * from "./UsFl.js";
export * from "./UsIa.js";
export * from "./UsMn.js";
export * from "./UsMt.js";
export * from "./UsNat.js";
export * from "./UsNe.js";
Expand Down
126 changes: 126 additions & 0 deletions modules/cmpapi/src/encoder/segment/UsMnCoreSegment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { AbstractBase64UrlEncoder } from "../base64/AbstractBase64UrlEncoder.js";
import { CompressedBase64UrlEncoder } from "../base64/CompressedBase64UrlEncoder.js";
import { BitStringEncoder } from "../bitstring/BitStringEncoder.js";
import { EncodableFixedInteger } from "../datatype/EncodableFixedInteger.js";
import { EncodableFixedIntegerList } from "../datatype/EncodableFixedIntegerList.js";
import { Predicate } from "../datatype/validate/Predicate.js";
import { DecodingError } from "../error/DecodingError.js";
import { ValidationError } from "../error/ValidationError.js";
import { EncodableBitStringFields } from "../field/EncodableBitStringFields.js";
import { UsMn_CORE_SEGMENT_FIELD_NAMES } from "../field/UsMnField.js";
import { UsMnField } from "../field/UsMnField.js";
import { UsMn } from "../section/UsMn.js";
import { AbstractLazilyEncodableSegment } from "./AbstractLazilyEncodableSegment.js";

export class UsMnCoreSegment extends AbstractLazilyEncodableSegment<EncodableBitStringFields> {
private base64UrlEncoder: AbstractBase64UrlEncoder = CompressedBase64UrlEncoder.getInstance();
private bitStringEncoder: BitStringEncoder = BitStringEncoder.getInstance();

constructor(encodedString?: string) {
super();
if (encodedString) {
this.decode(encodedString);
}
}

// overriden
public getFieldNames(): string[] {
return UsMn_CORE_SEGMENT_FIELD_NAMES;
}

// overriden
protected initializeFields(): EncodableBitStringFields {
const nullableBooleanAsTwoBitIntegerValidator = new (class implements Predicate<number> {
test(n: number): boolean {
return n >= 0 && n <= 2;
}
})();

const nonNullableBooleanAsTwoBitIntegerValidator = new (class implements Predicate<number> {
test(n: number): boolean {
return n >= 1 && n <= 2;
}
})();
const nullableBooleanAsTwoBitIntegerListValidator = new (class implements Predicate<number[]> {
test(l: number[]): boolean {
for (let i = 0; i < l.length; i++) {
let n = l[i];
if (n < 0 || n > 2) {
return false;
}
}
return true;
}
})();

let fields: EncodableBitStringFields = new EncodableBitStringFields();
fields.put(UsMnField.VERSION.toString(), new EncodableFixedInteger(6, UsMn.VERSION));
fields.put(
UsMnField.PROCESSING_NOTICE.toString(),
new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)
);
fields.put(
UsMnField.SALE_OPT_OUT_NOTICE.toString(),
new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)
);
fields.put(
UsMnField.TARGETED_ADVERTISING_OPT_OUT_NOTICE.toString(),
new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)
);
fields.put(
UsMnField.SALE_OPT_OUT.toString(),
new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)
);
fields.put(
UsMnField.TARGETED_ADVERTISING_OPT_OUT.toString(),
new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)
);
fields.put(
UsMnField.SENSITIVE_DATA_PROCESSING.toString(),
new EncodableFixedIntegerList(2, [0, 0, 0, 0, 0, 0, 0, 0]).withValidator(
nullableBooleanAsTwoBitIntegerListValidator
)
);
fields.put(
UsMnField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS.toString(),
new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)
);
fields.put(
UsMnField.ADDITIONAL_DATA_PROCESSING_CONSENT.toString(),
new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)
);
fields.put(
UsMnField.MSPA_COVERED_TRANSACTION.toString(),
new EncodableFixedInteger(2, 1).withValidator(nonNullableBooleanAsTwoBitIntegerValidator)
);
fields.put(
UsMnField.MSPA_OPT_OUT_OPTION_MODE.toString(),
new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)
);
fields.put(
UsMnField.MSPA_SERVICE_PROVIDER_MODE.toString(),
new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)
);
return fields;
}

// overriden
protected encodeSegment(fields: EncodableBitStringFields): string {
let bitString: string = this.bitStringEncoder.encode(fields, this.getFieldNames());
let encodedString: string = this.base64UrlEncoder.encode(bitString);
return encodedString;
}

// overriden
protected decodeSegment(encodedString: string, fields: EncodableBitStringFields): void {
if (encodedString == null || encodedString.length === 0) {
this.fields.reset(fields);
}
try {
let bitString: string = this.base64UrlEncoder.decode(encodedString);
this.bitStringEncoder.decode(bitString, this.getFieldNames(), fields);
} catch (e) {
throw new DecodingError("Unable to decode UsMnCoreSegment '" + encodedString + "'");
}
}
}
Loading