Legal module for PhoenixKit - GDPR/CCPA compliant legal pages and consent management.
Phase 1: Legal Pages Generation
- Compliance framework selection (GDPR, CCPA, etc.)
- Company information management
- Legal page generation (Privacy Policy, Terms, Cookie Policy)
- Integration with Publishing module for page storage (optional, via phoenix_kit_publishing)
Phase 2: Cookie Consent Widget (prepared infrastructure)
- Cookie consent banner
- Consent logging to phoenix_kit_consent_logs table
- Google Consent Mode v2 integration
Dependencies
- Publishing module (phoenix_kit_publishing) must be installed and enabled
Usage
# Enable the module (requires Publishing to be enabled)
PhoenixKit.Modules.Legal.enable_system()
# Check if enabled
PhoenixKit.Modules.Legal.enabled?()
# Get configuration
PhoenixKit.Modules.Legal.get_config()
# Generate legal pages
PhoenixKit.Modules.Legal.generate_all_pages()
Summary
Functions
Check if all required legal pages are published.
Get available compliance frameworks.
Get available page types.
Check if consent widget is enabled (Phase 2 feature).
Diagnose problems with legal pages.
Disable consent widget.
Disable Google Consent Mode v2.
Disable the Legal module.
Enable consent widget.
Enable Google Consent Mode v2.
Enable the Legal module.
Check if Legal module is enabled.
Generate all required pages for selected frameworks.
Generate a legal page from template.
Get all pages (required + optional) for given frameworks.
Get auto-calculated policy version based on legal page updates.
Get company information.
Get the full configuration of the Legal module.
Get consent mode.
Get full consent widget configuration for the component.
Get cookie banner/icon position. Options: "bottom-left", "bottom-right", "top-left", "top-right"
Get Data Protection Officer contact.
Alias for get_cookie_banner_position/0.
Get policy version for consent tracking. Changing this version will prompt users to re-consent.
Returns a list of all published legal pages as link maps.
Get pages required for given frameworks.
Get selected compliance frameworks.
Check if there are unpublished legal pages that are required.
Check if Google Consent Mode v2 is enabled.
Check if any opt-in framework is selected.
Returns true if the cookie consent widget should be hidden for authenticated users.
List generated legal pages.
Publish a legal page by slug.
Reset legal pages by removing the "legal" group and all its posts. Only works when diagnose_legal_pages() returns :needs_reset.
Set compliance frameworks.
Check if consent icon should be shown.
Update company information.
Update consent mode.
Update DPO contact information.
Update hide for authenticated setting.
Update cookie banner/icon position.
Update policy version.
Functions
@spec all_required_pages_published?() :: boolean()
Check if all required legal pages are published.
@spec available_frameworks() :: %{ required(String.t()) => PhoenixKit.Modules.Legal.LegalFramework.t() }
Get available compliance frameworks.
@spec available_page_types() :: %{ required(String.t()) => PhoenixKit.Modules.Legal.PageType.t() }
Get available page types.
@spec consent_widget_enabled?() :: boolean()
Check if consent widget is enabled (Phase 2 feature).
@spec diagnose_legal_pages() :: map()
Diagnose problems with legal pages.
Returns a map with:
:status — :ok | :needs_reset
- :issues — list of detected problems
- :trashed_count — number of trashed legal posts
- :orphaned_slugs — slugs that exist as trashed but conflict with generation
Disable consent widget.
Disable Google Consent Mode v2.
Disable the Legal module.
Enable consent widget.
Enable Google Consent Mode v2.
@spec enable_system() :: {:ok, :enabled} | {:error, :publishing_required | term()}
Enable the Legal module.
Requires Publishing module to be enabled first. Creates the "legal" publishing group if it doesn't exist.
Returns
{:ok, :enabled}- Successfully enabled{:error, :publishing_required}- Publishing module must be enabled first
@spec enabled?() :: boolean()
Check if Legal module is enabled.
Generate all required pages for selected frameworks.
Parameters
- opts: Keyword options
- :language - Language code (default: "en")
- :scope - User scope for audit trail
- :include_optional - Include optional pages (default: false)
Returns
{:ok, results}- Map of page_type => result
Generate a legal page from template.
Parameters
- page_type: Page type slug (e.g., "privacy-policy")
- opts: Keyword options
- :language - Language code (default: "en")
- :scope - User scope for audit trail
Returns
{:ok, post}on success{:error, reason}on failure
Get all pages (required + optional) for given frameworks.
@spec get_auto_policy_version() :: String.t()
Get auto-calculated policy version based on legal page updates.
Uses the latest updated_at from cookie-policy or privacy-policy pages. Falls back to manual version if no pages exist.
@spec get_company_info() :: map()
Get company information.
Reads from consolidated company_info key with fallback to legacy legal_company_info.
@spec get_config() :: map()
Get the full configuration of the Legal module.
Returns a map with:
- enabled: boolean
- frameworks: list of selected framework IDs
- company_info: map with company details
- dpo_contact: map with DPO contact info
- generated_pages: list of generated page slugs
- consent_widget_enabled: boolean (Phase 2)
@spec get_consent_mode() :: String.t()
Get consent mode.
Modes:
- "strict" - Full compliance: icon, script blocking, re-consent on policy change
- "notice" - Simple notice: banner once, no blocking, no icon
Default: "strict" for opt-in frameworks, "notice" otherwise.
@spec get_consent_widget_config() :: map()
Get full consent widget configuration for the component.
Returns a map with all settings needed by the cookie_consent component:
- enabled: boolean
consent_mode: "strict" | "notice"
- show_icon: boolean
- icon_position: string
- policy_version: string
- google_consent_mode: boolean
- frameworks: list of framework IDs
- cookie_policy_url: string (backward compat, derived from published pages)
- privacy_policy_url: string (backward compat, derived from published pages)
- legal_links: list of %{title: string, url: string} for all published legal pages
- legal_index_url: string
@spec get_cookie_banner_position() :: String.t()
Get cookie banner/icon position. Options: "bottom-left", "bottom-right", "top-left", "top-right"
@spec get_dpo_contact() :: map()
Get Data Protection Officer contact.
@spec get_icon_position() :: String.t()
Alias for get_cookie_banner_position/0.
@spec get_policy_version() :: String.t()
Get policy version for consent tracking. Changing this version will prompt users to re-consent.
Returns a list of all published legal pages as link maps.
Each map has :title and :url keys. Used by the cookie consent widget
to render dynamic links to all published legal pages.
Get pages required for given frameworks.
@spec get_selected_frameworks() :: [String.t()]
Get selected compliance frameworks.
@spec get_unpublished_required_pages() :: [String.t()]
Check if there are unpublished legal pages that are required.
Returns a list of unpublished page slugs (e.g., ["cookie-policy", "privacy-policy"]).
@spec google_consent_mode_enabled?() :: boolean()
Check if Google Consent Mode v2 is enabled.
@spec has_opt_in_framework?() :: boolean()
Check if any opt-in framework is selected.
@spec hide_for_authenticated?() :: boolean()
Returns true if the cookie consent widget should be hidden for authenticated users.
When true, the cookie_consent/1 component renders nothing for authenticated users
(both strict and notice modes). Requires phoenix_kit_current_scope to be passed
to the component — without it, this setting has no effect.
Default: true.
@spec list_generated_pages() :: [map()]
List generated legal pages.
Publish a legal page by slug.
Parameters
- page_slug: The slug of the page to publish (e.g., "cookie-policy")
- opts: Keyword options
- :scope - User scope for audit trail
Returns
{:ok, post}on success{:error, reason}on failure
@spec reset_legal_pages() :: {:ok, :reset_complete} | {:error, term()}
Reset legal pages by removing the "legal" group and all its posts. Only works when diagnose_legal_pages() returns :needs_reset.
After reset, call ensure_legal_blog() + generate_all_pages() to recreate.
Set compliance frameworks.
Parameters
- framework_ids: List of framework IDs to enable
Returns
{:ok, setting}on success{:error, reason}on failure
@spec should_show_consent_icon?() :: boolean()
Check if consent icon should be shown.
Returns true only if:
- Legal module is enabled
- Consent widget is enabled
- Consent mode is "strict"
- At least one opt-in framework is selected (GDPR, UK GDPR, LGPD, PIPEDA)
Update company information.
Update consent mode.
Update DPO contact information.
Update hide for authenticated setting.
Update cookie banner/icon position.
Update policy version.