Routes, settings, layout
Routes and their names
Build links by name, not by address: {route 'pageProfile'} in a template, route('pageProfile') in PHP. Then they will not break if the address changes.
| Address | Page name (GET) | Form submission name (POST) | Access |
|---|---|---|---|
/login | pageLogin | login | guest |
/register | pageRegister | register | guest |
/forgot-password | pageForgotPassword | forgotPassword | guest |
/reset-password/{token} | pageResetPassword | resetPassword (the form is sent to /reset-password) | guest |
/resend-verification | pageResendVerification | resendVerification | guest |
/two-factor | pageTwoFactorChallenge | twoFactorChallenge | guest |
/confirm-password | pageConfirmPassword | confirmPassword | signed in |
/profile | pageProfile | updateProfile | signed in |
/profile/password | pageChangePassword | changePassword | signed in |
/profile/two-factor | pageTwoFactorSettings | twoFactorEnable | signed in |
/profile/two-factor/disable | — | twoFactorDisable | signed in |
/profile/two-factor/backup-codes | — | twoFactorBackupCodes | signed in |
/logout | logout | — | signed in |
/verify-email/{token} | verifyEmail | — | anyone |
/auth/{provider} | socialRedirect | — | anyone |
/auth/{provider}/callback | socialCallback | socialCallbackPost | anyone |
/auth-email | pageSocialEmail | socialEmail | guest |
/profile/social/{provider}/unlink | — | socialUnlink | signed in |
/impersonate/{id} | impersonate | — | manager with sudo |
Why social networks have no guest
The same addresses are used to link a network to an already open account, and the controller itself works out whether this is a sign-in or a link. /impersonate/{id} has no auth for the opposite reason: on the site the visitor may be anonymous, while rights are checked against the manager session.
Settings in the admin area
System → System Settings, section pbauth:
| Setting | Default value | What for |
|---|---|---|
pbauth_user_page | users/{id} | address of the public user page, {id} and {username}. Empty — there is no "View on site" button |
pbauth_recaptcha_service | Google reCAPTCHA | which anti-spam is used |
pbauth_recaptcha_public_key | empty | Site key from Google reCAPTCHA v3 |
pbauth_recaptcha_secret_key | empty | Secret key. While it is empty, reCAPTCHA is not checked |
The keys are taken from the Google reCAPTCHA panel.
PageBlocks settings without which the component does not work:
| Setting | Required value |
|---|---|
pageblocks_routing | Route Only or Full API |
pageblocks_load_scripts | enabled — forms without a reload and error highlighting |
pageblocks_elements_path | where file: is taken from (by default {core_path}App/elements/) |
Plugin events
The pbAuth plugin must be attached to two system events. The package does this itself; by hand — only if the component was laid out as files.
| Event | Priority | What for |
|---|---|---|
OnHandleRequest | -10 | the "one session per account" mode |
OnManagerPageBeforeRender | — | the user buttons in the manager |
Priority -10 is not cosmetic: the session check must run before PageBlocks starts parsing the request.
What lies where
core/components/pbauth/ THE COMPONENT — do not touch, will be overwritten
src/ code
routes/ page addresses
config/defaults.php shipped settings (look, don't edit)
plugins/pbauth.php plugin source for the MODX system events
lexicon/ captions for settings and buttons in the admin area
docs/ the guide and a settings sample
src/Database/migrations/ the social account links table
assets/components/pbauth/ THE COMPONENT — do not touch
js/mgr/user.js the user buttons in the manager
core/App/ YOURS — edit freely
config/pbauth.php your component settings
elements/auth/templates/ page wrappers
elements/auth/chunks/ forms and e-mails
lang/{ru,en,uk,de}/auth.php captions
Events/Auth/ your event classes
Http/Controllers/Auth/ your controllers (if you need any)
routes/ your addresses (the file must NOT be named auth.php)
.pbauth-installed.json the installer manifest, no need to touch itWhat is stored where in the database
| What | Where |
|---|---|
| social account links | its own table pba_social_accounts |
| the two-factor secret and the backup code hashes | profile extended, key pbauth |
| the e-mail confirmation key and the password reset key | the stock MODX field remote_key |
| avatar | profile photo, the file under avatar_path |
| your own fields with no columns | profile extended — by a class on USER_SAVING |
Both one-time keys live in the same remote_key — that is a MODX limitation, and it is what the split into two forms follows from.
Upgrading and uninstalling
On install and upgrade the component puts into core/App/ only those files that are not there yet. An existing file is never overwritten.
Exactly what was put there is recorded with hashes in core/App/.pbauth-installed.json. When the component is uninstalled, only the files that have not changed since are erased; everything edited stays with the site.
A file that matches the shipped one byte for byte is considered its own by the component even without a manifest record — that is how installations made before the manifest appeared get picked up.
Moving from versions before 1.1.0
Before 1.1.0 routes and controllers were laid out in core/App/. The upgrade deletes App/routes/auth.php if it matches the shipped one byte for byte; an edited one stays, and then the component serves none of its own addresses — what live are your routes and your controllers in App/Http/Controllers/Auth/.
To move to the component's scheme, carry your edits over to App/config/pbauth.php and delete App/routes/auth.php by hand. Details are in core/components/pbauth/docs/changelog.txt, the Upgrading section.
If something does not work
/login opens as "page not found". Check pageblocks_routing — it must be Route Only or Full API. Then: whether there is a file named auth.php in core/App/routes/ — it switches off the component's addresses entirely. After that clear the cache.
A field from the form is not saved. Most likely it is not declared in rules — everything not there is discarded. If it is declared and still not saved, then it has no column in the database: you need a class on USER_SAVING, see "Your own fields".
Registration lets identical logins or e-mails through. The rule says unique:modUser instead of unique:users. The check expects a table name, not a MODX class, and against a non-existent table it silently finds nothing.
A login made of digits only does not pass max:30. The rule has no string, and the length is measured as the magnitude of the number.
Form errors are not shown. The field must have {$errors.name} and data-error="name". And the pageblocks_load_scripts setting must be enabled.
An edit in a template is not visible. Clear the MODX cache and refresh the page with Ctrl+F5.
An edit disappeared after a component upgrade. You edited a file inside core/components/pbauth/ — everything there is overwritten. Carry the edit over to core/App/: as a setting, an event or your own controller.
The social network buttons did not appear. Only configured providers are shown — check client_id and client_secret (for Telegram — bot_name and bot_token) in social.providers, and clear the cache. If they are configured and there are still no buttons — the pba_social_accounts migration has not been applied.
The provider answers "invalid return address". In the application settings at the provider it must be exactly https://your-site/auth/<provider>/callback, with the same protocol and without a stray slash at the end.
"Sign-in did not complete" after returning from the provider. The session was lost: it has to survive between the jump to the provider and the return. Usually this is different site addresses (with www and without) or too short a session lifetime.
The app shows the wrong code. Almost always the clocks on the phone and on the server have drifted apart. The app has a "synchronise time" item; if that does not help, raise two_factor_window to 2. If it will not let you in at all — sign in with a backup code.
My event class is not called. Check: the method is named exactly handle; the class is listed in listeners in core/App/config/pbauth.php; the file path matches the namespace (PageBlocks\App\Events\Auth\X → core/App/Events/Auth/X.php). Errors inside the class do not bring the page down — look for them in the MODX log (core/cache/logs/error.log).
There are no buttons in the manager. Under System → Plugins there must be a pbAuth plugin with OnManagerPageBeforeRender attached.
single_session does not evict.OnHandleRequest is not attached to the plugin, or its priority is later than PageBlocks. -10 is required.