=== MemberMagix ===
Contributors: surfstyk
Tags: membership, magic link, content protection, passwordless login, paywall
Requires at least: 6.0
Tested up to: 6.9
Stable tag: 4.0.4
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

A lightweight membership plugin with passwordless magic-link authentication, server-side content protection, and elegant subscriber onboarding.

== Description ==

MemberMagix is a secure, lightweight WordPress membership plugin that replaces traditional password-based login with **passwordless magic-link authentication**. Protect any post or page with server-side content gating — unauthorized visitors see only a teaser preview, while authenticated members get the full content.

**Key Features:**

* **Passwordless Magic Links** — Members log in by clicking a secure link sent to their email. No passwords to forget, leak, or manage.
* **Server-Side Content Protection** — Protected content is never sent to unauthorized users. A teaser is extracted server-side with a blur overlay and membership panel.
* **Author-Controlled Teasers** — Use the `[mmax_cutoff]` shortcode to control exactly where the teaser ends, or let MemberMagix auto-extract from your first paragraphs.
* **Custom Overlays** — Design your protection panel using the WordPress block editor. Full creative control over what visitors see.
* **Member Management** — View, search, and export members. Track terms acceptance and login history.
* **Brand Customization** — Match membership forms and overlays to your site's brand colors via the Style settings tab.

**Premium Features (via MemberMagix Pro add-on):**

* Multiple custom overlays with per-post assignment
* Bulk content protection tools
* Remove free-tier branding
* **Stripe Premium Content** — Monetize posts with Stripe Checkout, subscription management, and automatic magic-link delivery after payment

== Installation ==

**Option A — Install from WordPress admin:**

1. In your WordPress admin, go to **Plugins > Add New Plugin**.
2. Search for **"MemberMagix"** and click **Install Now**, then **Activate**.

**Option B — Upload manually:**

1. Download the plugin zip from [wordpress.org/plugins/membermagix](https://wordpress.org/plugins/membermagix/).
2. In your WordPress admin, go to **Plugins > Add New Plugin > Upload Plugin**.
3. Upload the zip file and click **Activate**.

**Getting Started:**

3. Find **MemberMagix** in the admin sidebar (look for the groups icon). Open **Settings > General** to configure your terms page, sender email, sender name, and button text.
4. Use **Send Test Email** to verify that email delivery is working reliably on your host.
5. Edit any post or page in the block editor. Open the block inserter and add a **Shortcode** block where you want the teaser to end. Set its value to `[mmax_cutoff]`. Everything below this shortcode will be hidden from non-members.
6. In the same editor, scroll down in the right-hand **Settings panel** (below Categories and Tags) to the **Content Protection** meta box. Switch from **Public** to **Protected**.

That's it — visitors will see the teaser and membership form, and members who click their magic link get the full content.

**Recommended:** Install an SMTP plugin (e.g., WP Mail SMTP) for reliable magic link delivery.

== Frequently Asked Questions ==

= How do members log in? =

Members enter their email address in the membership form. MemberMagix sends them a secure, one-time magic link. Clicking the link logs them in instantly — no password required.

= Is the protected content secure? =

Yes. MemberMagix uses server-side content protection. The full content is never sent to unauthorized browsers. Only a teaser preview is delivered, with the rest replaced before the page reaches the visitor.

= Can I control what appears in the teaser? =

Yes. Place the `[mmax_cutoff]` shortcode anywhere in your post to define the exact split point. Everything above the shortcode becomes the teaser. If no cutoff is set, MemberMagix auto-extracts the first few paragraphs.

= Magic link emails are delayed or never arrive — what's wrong? =

The most common cause is WordPress's "pseudo-cron" (`wp-cron.php`). By default, WordPress only runs scheduled tasks — including sending emails — when someone visits the site via HTTP. On low-traffic or staging sites, this means magic link emails can be silently delayed for hours.

**Symptoms:** You submit the form, the plugin reports success, but the email doesn't arrive for a long time (or until someone else visits the site).

**Fix:** Disable WP pseudo-cron and set up a real system crontab:

1. Add to `wp-config.php`: `define('DISABLE_WP_CRON', true);`
2. Add a system cron job: `*/5 * * * * cd /path/to/wordpress && php wp-cron.php`

Also recommended: install an SMTP plugin (e.g., WP Mail SMTP) for reliable email delivery.

= Does MemberMagix require any external services? =

No. MemberMagix runs entirely on your own WordPress install — no third-party APIs, no external services, no data leaving your server. We recommend an SMTP plugin (like WP Mail SMTP) for reliable magic-link email delivery, which is a WordPress best practice independent of this plugin.

= What happens when the plugin is uninstalled? =

All plugin data (custom tables, options, user meta, post meta, overlays, cron jobs, and transients) is fully removed when you delete the plugin through WordPress admin.

== Third-Party Libraries ==

This plugin bundles the following open-source library:

= Alpine.js =

Alpine.js v3.15.10 by Caleb Porzio is used for lightweight reactive UI in the membership form.

* License: MIT (GPL-compatible)
* Source code: [https://github.com/alpinejs/alpine](https://github.com/alpinejs/alpine)
* Release: [https://github.com/alpinejs/alpine/releases/tag/v3.15.10](https://github.com/alpinejs/alpine/releases/tag/v3.15.10)
* Bundled file: `assets/js/alpine.min.js`

No build tools are required. The minified file (`alpine.min.js`) was downloaded directly from the Alpine.js CDN for v3.15.10. The full unminified source is available at the GitHub repository and release page linked above.

== Screenshots ==

1. Membership form with magic link signup
2. Content protection with blur overlay and teaser preview
3. Admin settings dashboard
4. Bulk content protection interface
5. Member management table

== Changelog ==

= 4.0.4 =
* Content protection meta box now available on all public post types (was restricted to post/page, flagged as trialware)
* Removed check-email REST endpoint that leaked account existence (signup vs login mode)
* Simplified membership form: single-step email + terms flow, no account enumeration possible
* Terms acceptance now required for all magic link requests (new and returning users)
* Updated Alpine.js from 3.13.10 to 3.15.10
* Fixed register_setting sanitize_callback: use rest_sanitize_boolean instead of raw bool cast

= 4.0.3 =
* Overlay CPT now visible in admin menu (was hidden, flagged as locked feature)
* Applied kses sanitization to teaser and overlay content in the_content filter and REST responses
* Removed dead Pro-only methods (inject/remove cutoff shortcode) and helper meta reads
* Removed Pro-only table drops from uninstall.php (base only creates mmax_tokens)
* Added SVG stroke attributes to kses allowlist for success checkmark icon
* Added specific Alpine.js release URL to Third-Party Libraries documentation

= 4.0.2 =
* Fixed membership form not rendering on protected posts (wp_kses_post was stripping form HTML and Alpine.js attributes)
* Removed user ID from check-email REST response to prevent user enumeration
* Added Alpine.js x-cloak support to prevent flash of unstyled form steps

= 4.0.1 =
* Fixed auto-submit magic link for returning users (skip intermediate "Welcome back" step)
* Refined HTML sanitization: overlay content no longer passed through wp_kses_post
* Added escaping throughout for WP.org compliance (round 2 review feedback)
* Added Alpine.js third-party library attribution in readme.txt

= 4.0.0 =
* Freemium architecture: prefix rename mmx to mmax for WP.org uniqueness
* Plugin split: commercial features extracted to MemberMagix Pro add-on
* 18 extension points (filters and actions) for Pro add-on integration
* Database migration from mmx_ and ssm_ prefixes to mmax_
* All inline scripts and styles moved to enqueued files for WP.org compliance
* GPL license headers added to all files

= 3.4.1 =
* Email template restyled to match overlay/form brand palette (amber CTA, teal accents, warm neutrals)
* Email colors now read from Style tab settings with brand defaults
* Extracted email template to dedicated file for maintainability
* Configurable email button text (default: "View Blog") in General tab settings
* Send Test Email button on General tab for delivery verification
* Fixed email expiry notice: removed incorrect "single use" claim, respects token expiry filter with proper pluralization

= 3.4.0 =
* Reusable magic link tokens: both login and portal links in emails now work regardless of click order
* One-session-at-a-time: each magic link login destroys all previous sessions, enforcing single-device access
* Session replacement notification: dismissible toast informs users when a prior session was replaced
* Token usage analytics: new used_count column tracks how many times each token is used within its TTL
* Passwordless subscriber role: all password functionality disabled for subscribers (profile fields, password reset, wp-login.php password auth, REST API, users list reset action)
* Subscribers authenticate exclusively via magic links — role change to editor/admin restores password functionality

= 3.3.1 =
* Removed "Coming Soon" badges from Stripe Integration and Paid Subscriptions in feature table
* Moved blur settings from per-post meta box to Style tab (global Overlay Blur section)
* Added Membership Level and Subscription Status columns to CSV export
* Added Membership Level column and Edit Tier action to Members admin table
* Manual tier override: admins can assign membership levels independent of Stripe subscriptions
* License activation now redirects to Dashboard tab so newly unlocked tabs are immediately visible
* License notices display via admin_notices (visible on any tab)
* Left-aligned post-upgrade welcome screen to match admin panel layout
* Hardened Stripe settings fields against browser autofill (autocomplete, data-lpignore, data-1p-ignore)
* Added debug logging to Stripe portal redirect for troubleshooting broken email links

= 3.3.0 =
* REST protocol unification: all frontend API calls now use REST endpoints with wp_rest nonce
* New REST endpoint: POST /mmax/v1/check-email (email check for progressive form flow)
* Full implementation of POST /mmax/v1/magic-link (honeypot, bot detection, rate limiting, user creation, token, email)
* Removed legacy AJAX handlers (mmax_magic_link_request, mmax_check_email) — single protocol, single nonce
* Simplified frontend JS: removed AJAX FormData helpers, added restPost() utility

= 3.2.0 =
* Stripe-first checkout: removed identity step from premium flow — Stripe Checkout handles email + payment in one screen
* User creation moved to webhook handler — eliminates orphan users from abandoned checkouts
* Removed mmax_premium_create_user AJAX endpoint (no longer needed)
* Terms acceptance moved to pricing step with "By subscribing" consent pattern
* Subscription status polling now supports session_id for anonymous checkout tracking
* Premium flow reduced from 6 screens to 3: pricing → checkout → success

= 3.1.0 =
* Cleanup: removed dead templates (membership-form.php, overlay.php, overlay-css.php)
* Cleanup: replaced inline style attributes in premium panel with CSS classes
* Cleanup: moved payment warning hardcoded colors to CSS variables
* Updated health check file list to reflect current template structure

= 3.0.0 =
* Premium content: three-state content model (Public / Protected / Premium) with per-post access control
* Stripe Embedded Checkout: in-page subscription flow — visitors never leave the article
* Premium overlay panel with pricing toggle (monthly/annual), identity step, and checkout state machine
* Automatic magic-link email after payment via webhook — seamless onboarding for new subscribers
* Subscription status polling endpoint for real-time checkout confirmation
* Subscriber footer on premium posts: plan status, renewal date, and "Manage subscription" portal link
* Past-due payment banner: non-blocking warning with "Update payment method" link, content remains accessible
* [mmax_manage_billing] shortcode for site owners who want a dedicated billing page
* Magic-link emails now include "Manage your subscription" link for paid subscribers
* Stripe tab: Premium Content section with level name, Price ID configuration, and verify button
* Bulk protection supports Premium access level alongside Public and Protected
* Dashboard shows active subscriber count
* New AJAX handler for premium user creation (email + Stripe Customer in one step)
* Active subscription short-circuit: returning subscribers skip checkout, get a login link instead

= 2.1.0 =
* Extracted MMAX_Admin class: admin menu, tab shell, enqueue logic, and Dashboard tab now owned by dedicated module
* Modules register admin tabs via mmax_admin_tabs filter with priority sorting and conditional visibility
* Bulk Protection moved from submenu to tab (gated behind Personal+ tier)
* Removed duplicate Settings submenu entry
* Stripe tab now self-registered by MMAX_Stripe module
* License and Upgrade tabs now self-registered by MMAX_License module

= 2.0.1 =
* Fixed license tier detection: Business licenses were incorrectly displayed as Personal
* Added policy inclusion in Keygen API validation requests
* Added policy ID fallback for tier resolution

= 2.0.0 =
* In-plugin checkout: purchase a license directly from the Upgrade tab using Stripe Embedded Checkout
* Auto-activation: license key is automatically retrieved and activated after payment — zero redirects, zero copy-paste
* New Upgrade tab with pricing table, billing toggle (monthly/annual), and inline checkout
* Welcome screen with license key display, copy-to-clipboard, and email confirmation
* Graceful error handling: payment success always preserved, manual activation fallback
* Updated third-party services disclosure for Stripe and bridge service

= 1.0.5 =
* Migrated plugin licensing from Lemon Squeezy to Keygen CE (self-hosted)
* Updated third-party services disclosure for Keygen
* License key format updated to match Keygen key structure

= 1.0.4 =
* Removed external Google Fonts CDN dependency — uses system font stack
* Added Third-Party Services disclosure section (Lemon Squeezy, Stripe)
* Dashboard redesign: onboarding-focused "Get Started" steps replace feature cards
* WordPress.org submission release

= 1.0.3 =
* Email-first progressive form: email step determines signup vs login flow
* Returning users skip nickname and terms — just email and one click
* Resend magic link with 60-second cooldown on success screen
* Logged-in users without access see upgrade panel instead of signup form
* Removed redundant "Already a member?" overlay footer

= 1.0.2 =
* Rebranded icon from lock to groups — community over restriction
* Updated admin menu, dashboard header, feature cards, and free-tier branding footer

= 1.0.1 =
* Improved WordPress.org plugin check compliance
* Added readme.txt for WordPress.org submission
* Fixed escaping and sanitization throughout
* Added translator comments for all translatable strings with placeholders
* Added sanitize_callback to all register_setting calls

= 1.0.0 =
* Tier restructure: 3 tiers (free, personal, business)
* Bulk protection gated behind personal tier
* CPT protection gated behind business tier
* WordPress.org submission preparation

= 0.9.7 =
* Bulk cutoff shortcode injection and removal
* Protect & Add Cutoff / Unprotect & Remove Cutoff bulk actions

= 0.9.6 =
* Content protection v2: inline blur and panel overlay system
* Author-controlled teasers via [mmax_cutoff] shortcode

= 0.9.5 =
* Unified admin hub with tabbed settings
* Brand customization via Style tab
* Official lock icon logo

= 0.9.0 =
* Initial beta release
* Passwordless magic-link authentication
* Server-side content protection with teaser extraction
* Member management with CSV export
* Stripe integration wiring
* Lemon Squeezy plugin licensing

== Upgrade Notice ==

= 4.0.0 =
Major architecture update for WordPress.org. Plugin prefix renamed from mmx_ to mmax_. Commercial features moved to MemberMagix Pro add-on. Database tables migrate automatically on activation.

= 3.0.0 =
Premium content monetization! Charge for articles with Stripe Embedded Checkout — visitors subscribe without leaving the page. Requires Business tier license and Stripe connection.

= 2.0.0 =
New in-plugin checkout! Upgrade to Personal or Business directly from the settings page — no external site, no email waiting, instant activation.

= 1.0.5 =
Plugin licensing migrated to Keygen CE. Existing Lemon Squeezy keys will no longer work — contact support for a new key.

= 1.0.4 =
WordPress.org submission release. Removes external font loading, adds service disclosures.

= 1.0.3 =
Email-first progressive form: smoother login for returning users, upgrade panel for logged-in members.

= 1.0.2 =
Brand icon updated from lock to groups. Visual-only change.

= 1.0.1 =
Improved WordPress.org compliance. Recommended update for all users.
