Hi everyone,
I built a small plugin to solve a spam registration problem I was having, and I wanted to share it with the community.
The problem
Q2A's built-in email confirmation still creates a user ID immediately when someone registers. Spam bots that never confirm still pile up as real rows in your database. After a while your user list is full of junk.
What this plugin does
It intercepts registration at the core level using a Q2A event module hooked into `u_register`. The moment a new user is created, the plugin:
1. Reads the bcrypt password hash Q2A just stored
2. Saves everything to a `qa_pending_users` table
3. Deletes the Q2A user immediately
4. Sends a confirmation email with a secure token
5. Redirects the visitor to a "check your inbox" page
The real user ID is only generated when the visitor clicks the confirmation link. Spam bots that never confirm leave **zero trace** in the database.
Why an event module and not a page override?
I originally tried overriding the `/register` page with a page module, but Q2A's built-in routing gives its own pages priority — the classic form kept showing regardless. The event module approach bypasses that entirely and works with any theme or registration page out of the box.
Details
- Works with Q2A 1.8.x, PHP 7.2+
- Admin-created accounts are not affected
- Pending rows expire after 24 hours and are purged automatically
- Tokens are 64-character cryptographically secure strings (`random_bytes(32)`)
- No core Q2A files modified
GitHub
https://github.com/q2aio/qa-plugin-preconfirm/tree/main
Feedback, bug reports, and pull requests are very welcome. Hope it's useful to someone else dealing with the same issue!