Search by

magenxcommerce / module-gdpr-graph-ql

magenxcommerce

GraphQL surface for the GDPR cookie registry, consent logging and data-subject request tracking.

Package info

github.com/magenxcommerce/module-gdpr-graph-ql

Type:magento2-module

pkg:composer/magenxcommerce/module-gdpr-graph-ql

Statistics

Installs: 0

Dependents: 1

Suggesters: 0

Stars: 1

Open Issues: 0

v1.0.2 2026-10-07 07:33 UTC

This package is auto-updated.

Last update: 2026-10-24 19:38:45 UTC


README

Built with AI assistance. This module is built with significant use of Claude Code, under active human review and guidance. It is open source and in active development. AI assistance does not lower the engineering bar: every change must meet the same correctness, security, documentation and maintainability requirements as any other contribution.

No warranty. We are not responsible for any incompatibility. By installing this software, you accept responsibility for its security, upgrades, patches and monitoring.

Companion GraphQL module for Magenx_Gdpr (composer package magenxcommerce/module-gdpr-graph-ql).

Magenx_Gdpr owns the cookie registry, consent log and data-subject-request data, admin UI and cron - it has no GraphQL surface of its own. This module adds that surface, the same split Magento uses for Catalog vs CatalogGraphQl, so the core module stays installable (and testable) without pulling in Magento_GraphQl, and the GraphQL layer can version independently of the data layer it sits on.

What it adds

All resolvers delegate to the models/resource models in magenxcommerce/module-gdpr - no business logic lives here beyond DB-row → GraphQL-shape mapping (Model/DsrRequestMapper).

GraphQL Resolver Notes
Query.gdprCookieGroups CookieGroups Public, store-wide cookie categories/cookies for the cookie policy page. Cacheable.
Query.myGdprRequests MyGdprRequests Signed-in customer's own request history.
Query.myPersonalDataExport PersonalDataExport Customer's own profile/addresses/orders/consent history; logs a completed export_data request.
Mutation.submitCookieConsent SubmitCookieConsent Guest or customer; records a cookie-banner decision.
Mutation.requestGdprAction RequestGdprAction Customer-only; anonymize_data runs immediately, erase_data is queued for admin approval.

Every entry point above is gated on magenx_gdpr/general/enabled for the store being queried (Model/GdprAccess). With it off, gdprCookieGroups returns an empty list - a cookie policy page with nothing declared beats an error in every visitor's cached response - and the rest return an error.

What the export covers

myPersonalDataExport returns the personal data held by this module and by Magento's core customer/sales tables: profile, addresses, an order summary and cookie-consent history. It does not reach into third-party modules' tables. A store running additional extensions that hold personal data has to extend the resolver for its Article 15 response to be complete.

It is a query that writes (it logs the access request). That is deliberate - the storefront is wired to it as a query and the access itself has to be recorded - so it is marked @cache(cacheable: false) and the log write is deduplicated within a five-minute window.

Abuse and audit notes

submitCookieConsent is callable without authenticating, by design: most consent decisions happen before sign-in. Two consequences worth knowing about:

  • Duplicate suppression. For a signed-in customer a submission that repeats their current consent state is not written again - the audit trail is the sequence of changes. Guest submissions are never deduplicated, because behind a proxy they cannot be told apart (see below), and discarding a real consent decision would be worse than an extra row. Rate limiting for guests belongs in front of Magento - at the deployment's own nginx proxy or CDN, where the real client address is still visible and the ceiling is shared across app instances rather than counted per replica.

  • The recorded IP is the connecting peer. Behind a CDN or load balancer that is the proxy, not the visitor, which makes the ip_address column useless as evidence. Fixing it is deployment configuration, not something this module can do safely on its own: point Magento's Magento\Framework\HTTP\PhpEnvironment\RemoteAddress at your real proxy list via di.xml in your project, e.g.

    <type name="Magento\Framework\HTTP\PhpEnvironment\RemoteAddress">
        <arguments>
            <argument name="alternativeHeaders" xsi:type="array">
                <item name="forwarded_for" xsi:type="string">HTTP_X_FORWARDED_FOR</item>
            </argument>
            <argument name="trustedProxies" xsi:type="array">
                <item name="0" xsi:type="string">10.0.0.0/8</item>
            </argument>
        </arguments>
    </type>

    Set trustedProxies to the addresses your own load balancers actually use. Enabling the header without that list lets any client forge the address recorded against its own consent.

See etc/schema.graphqls for the full type surface (root Query/Mutation fields, not nested under Customer).

Install

composer require magenxcommerce/module-gdpr-graph-ql
bin/magento module:enable Magenx_GdprGraphQl
bin/magento setup:upgrade
bin/magento cache:clean

Verification status

Checked without a Magento installation available: every PHP file passes php -l, every XML file parses, etc/schema.graphqls parses, and composer.json is valid JSON. Not yet verified: setup:upgrade against a real database and a live GraphQL round-trip for each query/mutation above. Do that before shipping to production.