# DataFirefly Magic Link — Passwordless login

> Overview DataFirefly Magic Link adds passwordless sign-in to your PrestaShop 8 or 9 store. The customer enters their email address on the login page, receives a secure single-use link, clicks,…

- Page: <https://www.datafirefly.com/en/documentation/dfmagiclink/>
- Language: en
- Last updated: 2026-07-01
- Other languages: [fr](https://www.datafirefly.com/documentation/dfmagiclink/index.md), [es](https://www.datafirefly.com/es/documentation/dfmagiclink/index.md), [de](https://www.datafirefly.com/de/documentation/dfmagiclink/index.md), [it](https://www.datafirefly.com/it/documentation/dfmagiclink/index.md), [pl](https://www.datafirefly.com/pl/documentation/dfmagiclink/index.md), [nl](https://www.datafirefly.com/nl/documentation/dfmagiclink/index.md), [pt](https://www.datafirefly.com/pt/documentation/dfmagiclink/index.md)
- Index: <https://www.datafirefly.com/en/documentation/llms.txt>

## Overview

DataFirefly Magic Link adds passwordless sign-in to your PrestaShop 8 or 9 store. The customer enters their email address on the login page, receives a secure single-use link, clicks, confirms, and they are signed in. The classic username + password form stays available: the magic link adds to it, it does not replace it.

The module is fully self-contained: no Composer dependency, no external service, no CDN call. Everything runs on PrestaShop's native email system.

## Requirements

- PrestaShop 8.0 to 9.x
- PHP 8.1 or higher
- MySQL 5.7+ or MariaDB 10.3+
- Working email delivery (if your order confirmation emails go out, you are set)

## Installation

1. In the back office, open **Modules > Module Manager**.
2. Click **Upload a module** and select the `dfmagiclink.zip` file.
3. PrestaShop installs the module, creates the `ps_dfmagiclink_token` table and registers the hooks automatically.
4. Click **Configure** to open the settings page.

Right after installation, the magic link form shows below your store's standard login form, with default settings (links valid 15 minutes, rate limiting on).

## Configuration

All settings live under **Modules > Module Manager > DataFirefly Magic Link > Configure**.

### Enable Magic Link

Master switch. When _No_, the form disappears from the front office and existing links stop working (with an explicit message for the customer).

### Show on login page

Controls injecting the form below the standard login. You can turn the display off while keeping the module active, for instance if you embed the form elsewhere through your theme.

### Link validity (minutes)

How long a link stays usable after being issued. Default: **15 minutes**. Minimum 1, maximum 1440 (24 hours). We recommend staying between 15 and 60 minutes: long enough for email delivery, short enough to limit the exposure window.

### Max requests per IP / hour

Cap on link requests accepted from a single IP address over a rolling hour. Default: **5**. Protects against automated abuse.

### Max requests per email / hour

Cap on requests for a single customer account over a rolling hour. Default: **3**. Above the cap, requests are silently ignored (the on-screen message stays generic so account state is never disclosed).

During testing, remember to temporarily raise these caps or empty the `ps_dfmagiclink_token` table — otherwise you will quickly hit the 3-per-hour limit on your own account.

### Redirect after sign-in

Page the customer lands on after a successful sign-in: **My Account** (default), **Order History** or **Home page**.

### Statistics and purge

Three counters at the top of the configuration page: active tokens, sign-ins over the last 24 hours, links issued over 24 hours. The **Purge expired tokens** button removes stale tokens and consumed tokens older than 24 hours.

## Customer journey

1. The customer opens the login page and enters their email in the "Sign in without a password" block.
2. The module checks the account, generates a 256-bit token, stores its SHA-256 hash and sends the email. The on-screen response is intentionally generic ("If an account exists for this email...") to prevent account enumeration.
3. The customer clicks the button in the email and lands on a standalone **confirmation page** greeting them by first name.
4. They click "Sign me in": the token is consumed, the PrestaShop session opens, native authentication hooks fire, then redirect to the configured page.

**Why a confirmation page?** Outlook Safe Links, Gmail and corporate antivirus automatically visit links in received emails. Without this step, those scanners would consume the link before the customer. The token is only consumed on the real click (POST request), never on a plain visit (GET). Same pattern used by Slack, Notion and Vercel.

## Emails

Templates live in `modules/dfmagiclink/mails//` (fr, en, es, de), in HTML (`magiclink.html`) and plain text (`magiclink.txt`). The email language automatically follows the customer account language.

Available variables: `{firstname}`, `{lastname}`, `{email}`, `{magic_link}`, `{ttl}`, `{shop_name}`, `{ip}`.

To customise a template, copy it to your theme's mails folder (`themes/your-theme/modules/dfmagiclink/mails/`) so your changes survive module updates.

## Security

- **256-bit tokens** generated with `random_bytes()`, URL-safe base64 encoded.
- **SHA-256 hash in the database**: the raw token only exists in the email. A table leak yields no usable link.
- **Strict single use**: the token is marked consumed before the session opens.
- **Anti-enumeration**: identical response whether the account exists or not.
- **Dual rate limiting** by IP and by account.
- **CSRF**: the AJAX request is protected by PrestaShop's native security token.
- **noindex**: every module page carries the `X-Robots-Tag: noindex, nofollow, noarchive` header.

## Troubleshooting

### The email does not arrive

Check in order: the customer's spam folder (your domain's SPF/DKIM), the rate limit (the "links issued" counter in the config), and the customer account's active state. You can confirm server-side issuance in the `ps_dfmagiclink_token` table: a row with `used_at` at NULL should appear after each request.

### "This login link has expired or already been used"

The link passed its validity window, or was already used. The customer can simply request a new link from the login page.

### The form does not show on the login page

Check that "Show on login page" is enabled, then clear the cache (**Advanced Parameters > Performance > Clear cache**). Also confirm your theme executes the `displayCustomerLoginFormAfter` hook — Classic, Hummingbird and virtually every marketplace theme do.

## Uninstallation

Uninstalling drops the `ps_dfmagiclink_token` table and every configuration value. No customer account is modified, no password touched. Standard login keeps working normally.
