Extract shared types and add Regulation type with parsing methods
Move cookie banner types (CookieItem, Category, Regulation, BannerConfig, etc.) into a dedicated types.ts file. Add a coredata.Regulation type with parsing, JSON marshaling, and database scanning methods. Hardcode the geoloc-import data directory since the submodule path is fixed. Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
@@ -57,6 +57,7 @@ export const cookieBannerConsentRecordPageQuery = graphql`
|
|||||||
ipAddress
|
ipAddress
|
||||||
userAgent
|
userAgent
|
||||||
sdkVersion
|
sdkVersion
|
||||||
|
regulation
|
||||||
consentData
|
consentData
|
||||||
createdAt
|
createdAt
|
||||||
}
|
}
|
||||||
@@ -152,6 +153,11 @@ export default function CookieBannerConsentRecordPage({
|
|||||||
<PropertyRow label={__("SDK Version")}>
|
<PropertyRow label={__("SDK Version")}>
|
||||||
<span className="font-mono text-sm">{record.sdkVersion}</span>
|
<span className="font-mono text-sm">{record.sdkVersion}</span>
|
||||||
</PropertyRow>
|
</PropertyRow>
|
||||||
|
<PropertyRow label={__("Regulation")}>
|
||||||
|
<span className="font-mono text-sm">
|
||||||
|
{record.regulation || "-"}
|
||||||
|
</span>
|
||||||
|
</PropertyRow>
|
||||||
<PropertyRow label={__("Date")}>
|
<PropertyRow label={__("Date")}>
|
||||||
<time dateTime={record.createdAt}>
|
<time dateTime={record.createdAt}>
|
||||||
{formatDate(record.createdAt)}
|
{formatDate(record.createdAt)}
|
||||||
|
|||||||
@@ -216,6 +216,7 @@ export default function CookieBannerConsentRecordsPage({
|
|||||||
<Th>{__("Banner Version")}</Th>
|
<Th>{__("Banner Version")}</Th>
|
||||||
<Th>{__("IP Address")}</Th>
|
<Th>{__("IP Address")}</Th>
|
||||||
<Th>{__("SDK Version")}</Th>
|
<Th>{__("SDK Version")}</Th>
|
||||||
|
<Th>{__("Regulation")}</Th>
|
||||||
<SortableTh field="CREATED_AT">{__("Date")}</SortableTh>
|
<SortableTh field="CREATED_AT">{__("Date")}</SortableTh>
|
||||||
</Tr>
|
</Tr>
|
||||||
</Thead>
|
</Thead>
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ const consentRecordFragment = graphql`
|
|||||||
}
|
}
|
||||||
ipAddress
|
ipAddress
|
||||||
sdkVersion
|
sdkVersion
|
||||||
|
regulation
|
||||||
createdAt
|
createdAt
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
@@ -74,6 +75,11 @@ export function ConsentRecordRow({ recordKey }: ConsentRecordRowProps) {
|
|||||||
<Td>
|
<Td>
|
||||||
<span className="font-mono text-sm">{record.sdkVersion}</span>
|
<span className="font-mono text-sm">{record.sdkVersion}</span>
|
||||||
</Td>
|
</Td>
|
||||||
|
<Td>
|
||||||
|
<span className="font-mono text-sm">
|
||||||
|
{record.regulation || "-"}
|
||||||
|
</span>
|
||||||
|
</Td>
|
||||||
<Td>
|
<Td>
|
||||||
<time dateTime={record.createdAt}>
|
<time dateTime={record.createdAt}>
|
||||||
{formatDate(record.createdAt)}
|
{formatDate(record.createdAt)}
|
||||||
|
|||||||
@@ -35,10 +35,9 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func run() error {
|
func run() error {
|
||||||
var (
|
const dataDir = "pkg/geoloc/data/country-ip-blocks"
|
||||||
pgDSN string
|
|
||||||
dataDir string
|
var pgDSN string
|
||||||
)
|
|
||||||
|
|
||||||
flag.StringVar(
|
flag.StringVar(
|
||||||
&pgDSN,
|
&pgDSN,
|
||||||
@@ -46,12 +45,6 @@ func run() error {
|
|||||||
os.Getenv("DATABASE_URL"),
|
os.Getenv("DATABASE_URL"),
|
||||||
"PostgreSQL connection URL (default: DATABASE_URL env)",
|
"PostgreSQL connection URL (default: DATABASE_URL env)",
|
||||||
)
|
)
|
||||||
flag.StringVar(
|
|
||||||
&dataDir,
|
|
||||||
"data-dir",
|
|
||||||
"pkg/geoloc/data/country-ip-blocks",
|
|
||||||
"path to ipverse country-ip-blocks checkout",
|
|
||||||
)
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if pgDSN == "" {
|
if pgDSN == "" {
|
||||||
|
|||||||
@@ -20,82 +20,30 @@ import { COOKIE_NAME, getConsentCookie, setConsentCookie } from "./cookie";
|
|||||||
import { CookieDetector } from "./detector";
|
import { CookieDetector } from "./detector";
|
||||||
import { NotFoundError } from "./errors";
|
import { NotFoundError } from "./errors";
|
||||||
import { fetchJSON } from "./http";
|
import { fetchJSON } from "./http";
|
||||||
import type { BannerTexts } from "./i18n";
|
|
||||||
import { detectLanguage } from "./i18n";
|
import { detectLanguage } from "./i18n";
|
||||||
import type { ConsentIntegration } from "./integrations";
|
import type { ConsentIntegration } from "./integrations";
|
||||||
import { createDefaultIntegrations } from "./integrations";
|
import { createDefaultIntegrations } from "./integrations";
|
||||||
import { enqueue, flush } from "./queue";
|
import { enqueue, flush } from "./queue";
|
||||||
|
import type {
|
||||||
|
BannerConfig,
|
||||||
|
ConsentAction,
|
||||||
|
ConsentRecord,
|
||||||
|
CookieBannerClientOptions,
|
||||||
|
Regulation,
|
||||||
|
VisitorConsent,
|
||||||
|
} from "./types";
|
||||||
import { getOrCreateVisitorId } from "./visitor";
|
import { getOrCreateVisitorId } from "./visitor";
|
||||||
|
|
||||||
export interface CookieItem {
|
export type {
|
||||||
name: string;
|
BannerConfig,
|
||||||
max_age_seconds: number | null;
|
Category,
|
||||||
description: string;
|
ConsentAction,
|
||||||
}
|
ConsentRecord,
|
||||||
|
CookieBannerClientOptions,
|
||||||
export interface Category {
|
CookieItem,
|
||||||
name: string;
|
Regulation,
|
||||||
slug: string;
|
VisitorConsent,
|
||||||
description: string;
|
} from "./types";
|
||||||
kind: string;
|
|
||||||
cookies: CookieItem[];
|
|
||||||
gcm_consent_types: string[];
|
|
||||||
posthog_consent: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Regulation =
|
|
||||||
| "GDPR"
|
|
||||||
| "UK_GDPR"
|
|
||||||
| "FADP"
|
|
||||||
| "CCPA"
|
|
||||||
| "PIPEDA"
|
|
||||||
| "LGPD"
|
|
||||||
| "LFPDPPP"
|
|
||||||
| "POPIA"
|
|
||||||
| "PDPA"
|
|
||||||
| "PIPL"
|
|
||||||
| "PIPA"
|
|
||||||
| "APPI"
|
|
||||||
| "DPDP"
|
|
||||||
| "PDPL";
|
|
||||||
|
|
||||||
export interface BannerConfig {
|
|
||||||
banner_id: string;
|
|
||||||
version: number;
|
|
||||||
language: string;
|
|
||||||
default_language: string;
|
|
||||||
privacy_policy_url?: string;
|
|
||||||
cookie_policy_url: string;
|
|
||||||
consent_expiry_days: number;
|
|
||||||
consent_mode: "OPT_IN" | "OPT_OUT";
|
|
||||||
regulation: Regulation | null;
|
|
||||||
show_branding: boolean;
|
|
||||||
categories: Category[];
|
|
||||||
texts: BannerTexts;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ConsentAction = "ACCEPT_ALL" | "REJECT_ALL" | "CUSTOMIZE" | "GPC";
|
|
||||||
|
|
||||||
export interface VisitorConsent {
|
|
||||||
visitor_id: string;
|
|
||||||
version: number;
|
|
||||||
action: ConsentAction;
|
|
||||||
consent_data: Record<string, boolean>;
|
|
||||||
created_at: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ConsentRecord {
|
|
||||||
id: string;
|
|
||||||
visitor_id: string;
|
|
||||||
action: string;
|
|
||||||
created_at: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CookieBannerClientOptions {
|
|
||||||
bannerId: string;
|
|
||||||
baseUrl: string;
|
|
||||||
lang?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CookieBannerClient {
|
export class CookieBannerClient {
|
||||||
private readonly baseUrl: URL;
|
private readonly baseUrl: URL;
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
// PERFORMANCE OF THIS SOFTWARE.
|
// PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
import type { CookieBannerClient, BannerConfig } from "../client";
|
import type { CookieBannerClient } from "../client";
|
||||||
|
import type { BannerConfig } from "../types";
|
||||||
|
|
||||||
export type ProboState = "loading" | "banner" | "panel" | "hidden";
|
export type ProboState = "loading" | "banner" | "panel" | "hidden";
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
// PERFORMANCE OF THIS SOFTWARE.
|
// PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
import type { Category } from "../client";
|
import type { Category } from "../types";
|
||||||
import { ProboElement } from "./base";
|
import { ProboElement } from "./base";
|
||||||
import type { ProboRootElement } from "./base";
|
import type { ProboRootElement } from "./base";
|
||||||
import type { ProboCookieBannerRoot } from "./cookie-banner-root";
|
import type { ProboCookieBannerRoot } from "./cookie-banner-root";
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
// PERFORMANCE OF THIS SOFTWARE.
|
// PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
import type { CookieItem } from "../client";
|
import type { CookieItem } from "../types";
|
||||||
import { ProboElement } from "./base";
|
import { ProboElement } from "./base";
|
||||||
|
|
||||||
export class ProboCategory extends ProboElement {
|
export class ProboCategory extends ProboElement {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
// PERFORMANCE OF THIS SOFTWARE.
|
// PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
import { CookieBannerClient } from "../client";
|
import { CookieBannerClient } from "../client";
|
||||||
import type { BannerConfig } from "../client";
|
import type { BannerConfig } from "../types";
|
||||||
import { ProboElement } from "./base";
|
import { ProboElement } from "./base";
|
||||||
import type { ProboState, ProboRootElement, ConsentDraft } from "./base";
|
import type { ProboState, ProboRootElement, ConsentDraft } from "./base";
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
// PERFORMANCE OF THIS SOFTWARE.
|
// PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
import type { CookieItem } from "../client";
|
import type { CookieItem } from "../types";
|
||||||
import { humanizeDuration } from "../cookie-utils";
|
import { humanizeDuration } from "../cookie-utils";
|
||||||
import { getCookieDetailLabels } from "../i18n";
|
import { getCookieDetailLabels } from "../i18n";
|
||||||
import { ProboElement } from "./base";
|
import { ProboElement } from "./base";
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
// PERFORMANCE OF THIS SOFTWARE.
|
// PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
import type { ConsentAction } from "./client";
|
import type { ConsentAction } from "./types";
|
||||||
|
|
||||||
export const COOKIE_NAME = "probo_consent";
|
export const COOKIE_NAME = "probo_consent";
|
||||||
const SECONDS_PER_DAY = 86400;
|
const SECONDS_PER_DAY = 86400;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
// PERFORMANCE OF THIS SOFTWARE.
|
// PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
import type { Category } from "../client";
|
import type { Category } from "../types";
|
||||||
import type { ConsentIntegration } from "./integration";
|
import type { ConsentIntegration } from "./integration";
|
||||||
|
|
||||||
export class GoogleConsentModeIntegration implements ConsentIntegration {
|
export class GoogleConsentModeIntegration implements ConsentIntegration {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
// PERFORMANCE OF THIS SOFTWARE.
|
// PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
import type { Category } from "../client";
|
import type { Category } from "../types";
|
||||||
|
|
||||||
export interface ConsentIntegration {
|
export interface ConsentIntegration {
|
||||||
/** Called once after config is loaded, before any consent is applied. */
|
/** Called once after config is loaded, before any consent is applied. */
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
// PERFORMANCE OF THIS SOFTWARE.
|
// PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
import type { Category } from "../client";
|
import type { Category } from "../types";
|
||||||
import type { ConsentIntegration } from "./integration";
|
import type { ConsentIntegration } from "./integration";
|
||||||
|
|
||||||
interface PostHogInstance {
|
interface PostHogInstance {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
import { registerHeadlessComponents } from "../components";
|
import { registerHeadlessComponents } from "../components";
|
||||||
import type { ProboCookieBannerRoot } from "../components/cookie-banner-root";
|
import type { ProboCookieBannerRoot } from "../components/cookie-banner-root";
|
||||||
import type { BannerConfig } from "../client";
|
import type { BannerConfig } from "../types";
|
||||||
import { getGpcLabel, interpolate } from "../i18n";
|
import { getGpcLabel, interpolate } from "../i18n";
|
||||||
import { BRANDING, CHEVRON_DOWN, CLOSE_ICON } from "../html";
|
import { BRANDING, CHEVRON_DOWN, CLOSE_ICON } from "../html";
|
||||||
import { THEMED_STYLES } from "./styles";
|
import { THEMED_STYLES } from "./styles";
|
||||||
|
|||||||
85
packages/cookie-banner/src/types.ts
Normal file
85
packages/cookie-banner/src/types.ts
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
// Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||||
|
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||||
|
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
// PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
import type { BannerTexts } from "./i18n";
|
||||||
|
|
||||||
|
export interface CookieItem {
|
||||||
|
name: string;
|
||||||
|
max_age_seconds: number | null;
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Category {
|
||||||
|
name: string;
|
||||||
|
slug: string;
|
||||||
|
description: string;
|
||||||
|
kind: string;
|
||||||
|
cookies: CookieItem[];
|
||||||
|
gcm_consent_types: string[];
|
||||||
|
posthog_consent: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Regulation =
|
||||||
|
| "GDPR"
|
||||||
|
| "UK_GDPR"
|
||||||
|
| "FADP"
|
||||||
|
| "CCPA"
|
||||||
|
| "PIPEDA"
|
||||||
|
| "LGPD"
|
||||||
|
| "LFPDPPP"
|
||||||
|
| "POPIA"
|
||||||
|
| "PDPA"
|
||||||
|
| "PIPL"
|
||||||
|
| "PIPA"
|
||||||
|
| "APPI"
|
||||||
|
| "DPDP"
|
||||||
|
| "PDPL";
|
||||||
|
|
||||||
|
export interface BannerConfig {
|
||||||
|
banner_id: string;
|
||||||
|
version: number;
|
||||||
|
language: string;
|
||||||
|
default_language: string;
|
||||||
|
privacy_policy_url?: string;
|
||||||
|
cookie_policy_url: string;
|
||||||
|
consent_expiry_days: number;
|
||||||
|
consent_mode: "OPT_IN" | "OPT_OUT";
|
||||||
|
regulation: Regulation | null;
|
||||||
|
show_branding: boolean;
|
||||||
|
categories: Category[];
|
||||||
|
texts: BannerTexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ConsentAction = "ACCEPT_ALL" | "REJECT_ALL" | "CUSTOMIZE" | "GPC";
|
||||||
|
|
||||||
|
export interface VisitorConsent {
|
||||||
|
visitor_id: string;
|
||||||
|
version: number;
|
||||||
|
action: ConsentAction;
|
||||||
|
consent_data: Record<string, boolean>;
|
||||||
|
created_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ConsentRecord {
|
||||||
|
id: string;
|
||||||
|
visitor_id: string;
|
||||||
|
action: string;
|
||||||
|
created_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CookieBannerClientOptions {
|
||||||
|
bannerId: string;
|
||||||
|
baseUrl: string;
|
||||||
|
lang?: string;
|
||||||
|
}
|
||||||
@@ -16,24 +16,24 @@ package cookiebanner
|
|||||||
|
|
||||||
import "go.probo.inc/probo/pkg/coredata"
|
import "go.probo.inc/probo/pkg/coredata"
|
||||||
|
|
||||||
type Regulation string
|
type Regulation = coredata.Regulation
|
||||||
|
|
||||||
const (
|
const (
|
||||||
RegulationNone Regulation = ""
|
RegulationNone = coredata.RegulationNone
|
||||||
RegulationGDPR Regulation = "GDPR"
|
RegulationGDPR = coredata.RegulationGDPR
|
||||||
RegulationUKGDPR Regulation = "UK_GDPR"
|
RegulationUKGDPR = coredata.RegulationUKGDPR
|
||||||
RegulationFADP Regulation = "FADP"
|
RegulationFADP = coredata.RegulationFADP
|
||||||
RegulationCCPA Regulation = "CCPA"
|
RegulationCCPA = coredata.RegulationCCPA
|
||||||
RegulationPIPEDA Regulation = "PIPEDA"
|
RegulationPIPEDA = coredata.RegulationPIPEDA
|
||||||
RegulationLGPD Regulation = "LGPD"
|
RegulationLGPD = coredata.RegulationLGPD
|
||||||
RegulationLFPDPPP Regulation = "LFPDPPP"
|
RegulationLFPDPPP = coredata.RegulationLFPDPPP
|
||||||
RegulationPOPIA Regulation = "POPIA"
|
RegulationPOPIA = coredata.RegulationPOPIA
|
||||||
RegulationPDPA Regulation = "PDPA"
|
RegulationPDPA = coredata.RegulationPDPA
|
||||||
RegulationPIPL Regulation = "PIPL"
|
RegulationPIPL = coredata.RegulationPIPL
|
||||||
RegulationPIPA Regulation = "PIPA"
|
RegulationPIPA = coredata.RegulationPIPA
|
||||||
RegulationAPPI Regulation = "APPI"
|
RegulationAPPI = coredata.RegulationAPPI
|
||||||
RegulationDPDP Regulation = "DPDP"
|
RegulationDPDP = coredata.RegulationDPDP
|
||||||
RegulationPDPL Regulation = "PDPL"
|
RegulationPDPL = coredata.RegulationPDPL
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -1856,7 +1856,7 @@ func (s *Service) RecordConsent(
|
|||||||
ConsentData: req.ConsentData,
|
ConsentData: req.ConsentData,
|
||||||
Action: req.Action,
|
Action: req.Action,
|
||||||
SdkVersion: req.SdkVersion,
|
SdkVersion: req.SdkVersion,
|
||||||
Regulation: string(req.Regulation),
|
Regulation: req.Regulation,
|
||||||
CreatedAt: time.Now(),
|
CreatedAt: time.Now(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ type (
|
|||||||
ConsentData json.RawMessage `db:"consent_data"`
|
ConsentData json.RawMessage `db:"consent_data"`
|
||||||
Action CookieConsentAction `db:"action"`
|
Action CookieConsentAction `db:"action"`
|
||||||
SdkVersion string `db:"sdk_version"`
|
SdkVersion string `db:"sdk_version"`
|
||||||
Regulation string `db:"regulation"`
|
Regulation Regulation `db:"regulation"`
|
||||||
CreatedAt time.Time `db:"created_at"`
|
CreatedAt time.Time `db:"created_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
152
pkg/coredata/regulation.go
Normal file
152
pkg/coredata/regulation.go
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
// Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||||
|
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||||
|
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
// PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
package coredata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql/driver"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Regulation string
|
||||||
|
|
||||||
|
const (
|
||||||
|
RegulationNone Regulation = ""
|
||||||
|
RegulationGDPR Regulation = "GDPR"
|
||||||
|
RegulationUKGDPR Regulation = "UK_GDPR"
|
||||||
|
RegulationFADP Regulation = "FADP"
|
||||||
|
RegulationCCPA Regulation = "CCPA"
|
||||||
|
RegulationPIPEDA Regulation = "PIPEDA"
|
||||||
|
RegulationLGPD Regulation = "LGPD"
|
||||||
|
RegulationLFPDPPP Regulation = "LFPDPPP"
|
||||||
|
RegulationPOPIA Regulation = "POPIA"
|
||||||
|
RegulationPDPA Regulation = "PDPA"
|
||||||
|
RegulationPIPL Regulation = "PIPL"
|
||||||
|
RegulationPIPA Regulation = "PIPA"
|
||||||
|
RegulationAPPI Regulation = "APPI"
|
||||||
|
RegulationDPDP Regulation = "DPDP"
|
||||||
|
RegulationPDPL Regulation = "PDPL"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Regulations() []Regulation {
|
||||||
|
return []Regulation{
|
||||||
|
RegulationGDPR,
|
||||||
|
RegulationUKGDPR,
|
||||||
|
RegulationFADP,
|
||||||
|
RegulationCCPA,
|
||||||
|
RegulationPIPEDA,
|
||||||
|
RegulationLGPD,
|
||||||
|
RegulationLFPDPPP,
|
||||||
|
RegulationPOPIA,
|
||||||
|
RegulationPDPA,
|
||||||
|
RegulationPIPL,
|
||||||
|
RegulationPIPA,
|
||||||
|
RegulationAPPI,
|
||||||
|
RegulationDPDP,
|
||||||
|
RegulationPDPL,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseRegulation(s string) (Regulation, error) {
|
||||||
|
switch Regulation(s) {
|
||||||
|
case RegulationNone:
|
||||||
|
return RegulationNone, nil
|
||||||
|
case RegulationGDPR:
|
||||||
|
return RegulationGDPR, nil
|
||||||
|
case RegulationUKGDPR:
|
||||||
|
return RegulationUKGDPR, nil
|
||||||
|
case RegulationFADP:
|
||||||
|
return RegulationFADP, nil
|
||||||
|
case RegulationCCPA:
|
||||||
|
return RegulationCCPA, nil
|
||||||
|
case RegulationPIPEDA:
|
||||||
|
return RegulationPIPEDA, nil
|
||||||
|
case RegulationLGPD:
|
||||||
|
return RegulationLGPD, nil
|
||||||
|
case RegulationLFPDPPP:
|
||||||
|
return RegulationLFPDPPP, nil
|
||||||
|
case RegulationPOPIA:
|
||||||
|
return RegulationPOPIA, nil
|
||||||
|
case RegulationPDPA:
|
||||||
|
return RegulationPDPA, nil
|
||||||
|
case RegulationPIPL:
|
||||||
|
return RegulationPIPL, nil
|
||||||
|
case RegulationPIPA:
|
||||||
|
return RegulationPIPA, nil
|
||||||
|
case RegulationAPPI:
|
||||||
|
return RegulationAPPI, nil
|
||||||
|
case RegulationDPDP:
|
||||||
|
return RegulationDPDP, nil
|
||||||
|
case RegulationPDPL:
|
||||||
|
return RegulationPDPL, nil
|
||||||
|
default:
|
||||||
|
return "", fmt.Errorf("invalid Regulation value: %q", s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r Regulation) String() string {
|
||||||
|
return string(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Regulation) Scan(value any) error {
|
||||||
|
var v string
|
||||||
|
switch val := value.(type) {
|
||||||
|
case string:
|
||||||
|
v = val
|
||||||
|
case []byte:
|
||||||
|
v = string(val)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unsupported type for Regulation: %T", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
parsed, err := ParseRegulation(v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*r = parsed
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r Regulation) Value() (driver.Value, error) {
|
||||||
|
if r == RegulationNone {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := ParseRegulation(string(r)); err != nil {
|
||||||
|
return nil, fmt.Errorf("invalid Regulation: %s", r)
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(r), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r Regulation) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(string(r))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Regulation) UnmarshalJSON(data []byte) error {
|
||||||
|
var s string
|
||||||
|
if err := json.Unmarshal(data, &s); err != nil {
|
||||||
|
return fmt.Errorf("cannot unmarshal Regulation: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
parsed, err := ParseRegulation(s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*r = parsed
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -100,9 +100,9 @@ func (s *Service) LookupCountry(ctx context.Context, ip string) (coredata.Countr
|
|||||||
err := s.pgClient.WithConn(
|
err := s.pgClient.WithConn(
|
||||||
ctx,
|
ctx,
|
||||||
func(ctx context.Context, conn pg.Querier) error {
|
func(ctx context.Context, conn pg.Querier) error {
|
||||||
var lookupErr error
|
var err error
|
||||||
cc, lookupErr = coredata.LookupCountryByIP(ctx, conn, ip)
|
cc, err = coredata.LookupCountryByIP(ctx, conn, ip)
|
||||||
return lookupErr
|
return err
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -118,9 +118,9 @@ func (s *Service) IsPopulated(ctx context.Context) (bool, error) {
|
|||||||
err := s.pgClient.WithConn(
|
err := s.pgClient.WithConn(
|
||||||
ctx,
|
ctx,
|
||||||
func(ctx context.Context, conn pg.Querier) error {
|
func(ctx context.Context, conn pg.Querier) error {
|
||||||
var lookupErr error
|
var err error
|
||||||
populated, lookupErr = coredata.IsIPCountryBlocksPopulated(ctx, conn)
|
populated, err = coredata.IsIPCountryBlocksPopulated(ctx, conn)
|
||||||
return lookupErr
|
return err
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ type CookieConsentRecord implements Node {
|
|||||||
consentData: String!
|
consentData: String!
|
||||||
action: CookieConsentAction!
|
action: CookieConsentAction!
|
||||||
sdkVersion: String!
|
sdkVersion: String!
|
||||||
|
regulation: String!
|
||||||
createdAt: Datetime!
|
createdAt: Datetime!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ func NewCookieConsentRecord(r *coredata.CookieConsentRecord) *CookieConsentRecor
|
|||||||
ConsentData: string(r.ConsentData),
|
ConsentData: string(r.ConsentData),
|
||||||
Action: r.Action,
|
Action: r.Action,
|
||||||
SdkVersion: r.SdkVersion,
|
SdkVersion: r.SdkVersion,
|
||||||
|
Regulation: r.Regulation.String(),
|
||||||
CreatedAt: r.CreatedAt,
|
CreatedAt: r.CreatedAt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user