PHPackages                             cinghie/yii2-user-extended - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. cinghie/yii2-user-extended

ActiveYii2-extension[Authentication &amp; Authorization](/categories/authentication)

cinghie/yii2-user-extended
==========================

Module to extend functionalities of Yii2 User by Dektrium.

0.6.4(1mo ago)74.0k3[3 issues](https://github.com/cinghie/yii2-user-extended/issues)[1 PRs](https://github.com/cinghie/yii2-user-extended/pulls)2BSD-3-ClausePHPPHP &gt;=7.4.0

Since Sep 8Pushed 3w ago5 watchersCompare

[ Source](https://github.com/cinghie/yii2-user-extended)[ Packagist](https://packagist.org/packages/cinghie/yii2-user-extended)[ Docs](https://github.com/cinghie/yii2-user-extended)[ RSS](/packages/cinghie-yii2-user-extended/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (10)Dependencies (10)Versions (34)Used By (2)

Yii2 User Extended
==================

[](#yii2-user-extended)

[![License](https://camo.githubusercontent.com/041c537d5dd3e8db3f75cd226fd45055bd85076cce25499ee29a2d98fcd6f9a6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f63696e676869652f796969322d757365722d657874656e6465642e737667)](https://camo.githubusercontent.com/041c537d5dd3e8db3f75cd226fd45055bd85076cce25499ee29a2d98fcd6f9a6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f63696e676869652f796969322d757365722d657874656e6465642e737667)[![Latest Stable Version](https://camo.githubusercontent.com/7369871c5c52e5a4611caa9c813ef01bce2688abb1b2e7959e611e0797a35f9b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652f63696e676869652f796969322d757365722d657874656e6465642e737667)](https://camo.githubusercontent.com/7369871c5c52e5a4611caa9c813ef01bce2688abb1b2e7959e611e0797a35f9b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652f63696e676869652f796969322d757365722d657874656e6465642e737667)[![Latest Release Date](https://camo.githubusercontent.com/96d4e9650ce15b3e148193181fc111eb485191944c0a67b731faff4cb5a03efd/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652d646174652f63696e676869652f796969322d757365722d657874656e6465642e737667)](https://camo.githubusercontent.com/96d4e9650ce15b3e148193181fc111eb485191944c0a67b731faff4cb5a03efd/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652d646174652f63696e676869652f796969322d757365722d657874656e6465642e737667)[![Latest Commit](https://camo.githubusercontent.com/6756339e530d2f1fedd8d1491065f3d45850dbf8b202730618bf9281d40dc8fd/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f63696e676869652f796969322d757365722d657874656e6465642e737667)](https://camo.githubusercontent.com/6756339e530d2f1fedd8d1491065f3d45850dbf8b202730618bf9281d40dc8fd/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f63696e676869652f796969322d757365722d657874656e6465642e737667)[![Total Downloads](https://camo.githubusercontent.com/e98343566a21c756d24445eed653ce2e2b45290c6e5c1aed37e46032ecc9fe3f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f63696e676869652f796969322d757365722d657874656e6465642e737667)](https://packagist.org/packages/cinghie/yii2-user-extended)

Yii2 User Extended to extend Yii2 User by Dektrium:

This is not an standalone module to manage users but a module to extend Yii2 User extension.

Current package version: **0.6.4** (see `CHANGELOG.md`).

Installation
------------

[](#installation)

The preferred way to install this extension is through [composer](http://getcomposer.org/download/).

Either run

```
php composer.phar require cinghie/yii2-user-extended "*"

```

or add this line to the require section of your `composer.json` file.

```
"cinghie/yii2-user-extended": "*"

```

Configuration
-------------

[](#configuration)

### 1. Images folder

[](#1-images-folder)

Copy img folder to your webroot

### 2. Update yii2 user database schema

[](#2-update-yii2-user-database-schema)

Make sure that you have properly configured `db` application component and run the following command:

```
$ php yii migrate/up --migrationPath=@vendor/dektrium/yii2-user/migrations

```

### 3. Add Yii2 RBAC migrations

[](#3-add-yii2-rbac-migrations)

Add to common config file

```
'components' => [
    'authManager' => [
        'class' => 'yii\rbac\DbManager',
    ],
]

'modules' => [
    'rbac' => 'dektrium\rbac\RbacWebModule',
],

```

and run migration

```
$ php yii migrate/up --migrationPath=@yii/rbac/migrations

```

### 4. Update yii2 user extended database schema

[](#4-update-yii2-user-extended-database-schema)

```
$ php yii migrate/up --migrationPath=@vendor/cinghie/yii2-user-extended/migrations

```

If the app already lists that path in `console` `controllerMap.migrate.migrationPath` (as CorimaCRM does), plain `php yii migrate` is enough.

This applies (among others):

- profile / user extended schema updates
- admin grid indexes (e.g. `user.last_login_at`)
- `user.password_changed_at` (password rotation / `passwordMaxAgeDays`)
- **`userextended_rate_limit`** — DB-backed login/registration lockout (default `rateLimitStorage=db`). **Required on every environment** after upgrading; without it the module falls back to cache and logs a warning.

### 5. Set configuration file

[](#5-set-configuration-file)

Set on your configuration file, in modules section

```
'modules' =>  [
    // Yii2 RBAC
    'rbac' => [
        'class' => 'dektrium\rbac\RbacWebModule',
        // Invalidate cached role list after role CRUD
        'controllerMap' => [
            'role' => 'cinghie\userextended\controllers\RoleController',
            'permission' => 'cinghie\userextended\controllers\PermissionController',
        ],
    ],
    // Yii2 User
    'user' => [
        'class' => 'dektrium\user\Module',
        // Disable user impersonation (recommended)
        'enableImpersonateUser' => false,
        // Yii2 User Controllers Overrides
        'controllerMap' => [
            'admin' => 'cinghie\userextended\controllers\AdminController',
            'security' => 'cinghie\userextended\controllers\SecurityController',
            'settings' => 'cinghie\userextended\controllers\SettingsController',
        ],
        // Yii2 User Models Overrides
        'modelMap' => [
            'LoginForm' => 'cinghie\userextended\models\LoginForm',
            'RecoveryForm' => 'cinghie\userextended\models\RecoveryForm',
            'RegistrationForm' => 'cinghie\userextended\models\RegistrationForm',
            'Profile' => 'cinghie\userextended\models\Profile',
            'SettingsForm' => 'cinghie\userextended\models\SettingsForm',
            'User' => 'cinghie\userextended\models\User',
        ],
    ],
    // Yii2 User Extended
    'userextended' => [
        'class' => 'cinghie\userextended\Module',

        // Paths
        'avatarPath' => '@webroot/img/users/',
        'avatarURL' => '@web/img/users/',

        // Profile fields
        'defaultRole' => '', // example 'registered'
        'account' => false,
        'avatar' => true,
        'bio' => false,
        'captcha' => true,
        'birthday' => true,
        'contact' => false,
        'firstname' => true,
        'gravatarEmail' => false,
        'lastname' => true,
        'location' => false,
        'onlyEmail' => false,
        'publicEmail' => false,
        'signature' => true,
        'terms' => true,
        'website' => false,

        // Templates / UI
        'templateLogin' => 'login_prestashop', // login or login_prestashop
        'templateLogoURL' => '@web/logo.png',
        'templateRegister' => '_two_column', // _one_column or _two_column
        'showAlert' => true,
        'showTitles' => true, // Set false in adminLTE
        'socialLogin' => false,

        // Avatar upload hardening
        'avatarAllowedExtensions' => ['jpg', 'jpeg', 'png', 'webp'],
        'avatarMaxSize' => 2097152, // 2MB

        // XSS / signature
        'signatureAllowHtml' => false, // plain text by default; true = HtmlPurifier whitelist
        'signatureAllowedHtml' => 'p,br,strong,b,em,i,ul,ol,li,a[href|title|target|rel],span',

        // Password policy
        'enablePasswordPolicy' => true,
        'passwordMinLength' => 8,
        'passwordMaxLength' => 72,
        'passwordRequireUppercase' => true,
        'passwordRequireLowercase' => true,
        'passwordRequireDigit' => true,
        'passwordRequireSpecial' => false,
        'passwordBanCommon' => true,
        'passwordCommonList' => [], // extra banned passwords
        'passwordMaxAgeDays' => 0, // 0 = disabled; e.g. 90 forces periodic change
        'passwordHashCost' => 13, // bcrypt 12–15 (default 13); old hashes still verify
        'rehashPasswordOnLogin' => true, // upgrade-only rehash after successful login

        // Session expire / auth hardening
        'sessionTimeout' => 3600, // seconds; 0 disables module session handling
        'useAbsoluteAuthTimeout' => false, // if true and absoluteAuthTimeout=0, use sessionTimeout
        'absoluteAuthTimeout' => 0, // max login duration in seconds (0 = off unless useAbsoluteAuthTimeout)
        'enableClientSessionExpireRedirect' => true,
        'clientWarningBeforeExpire' => 60, // 0 disables warning
        'clientWarningOnce' => true,
        'clientSessionHeartbeatInterval' => 0, // e.g. 300 to ping every 5 minutes
        'clientSessionHeartbeatUrl' => null, // null = current page
        'disableAutoLogin' => true, // CRM recommended: no remember-me
        'hardenSessionCookies' => true,
        'sessionCookieSecure' => null, // null = auto (HTTPS or prod), true/false = force
        'sessionSameSite' => null, // null = Lax when not already set
        'regenerateSessionId' => true,
        'invalidateRememberMeOnAuthTimeout' => true,

        // Login rate limit / brute-force
        'enableLoginRateLimit' => true,
        'rateLimitStorage' => 'db', // db | cache | auto — db survives cache flush
        'loginMaxAttempts' => 5,
        'loginAttemptWindow' => 900,
        'loginLockoutDuration' => 900,
        'loginProgressiveDelay' => true,
        'loginDelayBaseSeconds' => 1,
        'loginDelayMaxSeconds' => 5,
        'loginCaptchaAfterAttempts' => 3, // 0 disables
        'loginCaptchaAction' => ['/site/captcha'],

        // RBAC role list cache (admin filters)
        'enableRbacRoleCache' => true,
        'rbacRoleCacheDuration' => 3600,

        // Cloudflare Turnstile (optional; keep secret in web-local / env)
        'enableCloudflareTurnstile' => false,
        'cloudflareSiteKey' => '',
        'cloudflareSecretKey' => '', // never commit real secrets
        'cloudflareTurnstileTheme' => 'auto', // auto|light|dark
        'cloudflareTurnstileOnRegistration' => false,
    ],
]

```

Put secrets and environment-specific overrides in `web-local.php` (example):

```
'modules' => [
    'userextended' => [
        'enableCloudflareTurnstile' => true,
        'cloudflareSiteKey' => 'your-site-key',
        'cloudflareSecretKey' => 'your-secret-key',
        'cloudflareTurnstileTheme' => 'auto',
        'cloudflareTurnstileOnRegistration' => false,
        // 'sessionTimeout' => 3600,
        // 'disableAutoLogin' => true,
    ],
],

```

and in components section

```
'components' =>  [
    'cache' => [
        'class' => 'yii\caching\FileCache', // required for rate limit + RBAC role cache
    ],
    'view' => [
        'theme' => [
            'pathMap' => [
                '@dektrium/rbac/views/permission' => '@vendor/cinghie/yii2-user-extended/views/permission',
                '@dektrium/rbac/views/role' => '@vendor/cinghie/yii2-user-extended/views/role',
                '@dektrium/rbac/views/rule' => '@vendor/cinghie/yii2-user-extended/views/rule',
                '@dektrium/user/views/admin' => '@vendor/cinghie/yii2-user-extended/views/admin',
                '@dektrium/user/views/profile' => '@vendor/cinghie/yii2-user-extended/views/profile',
                '@dektrium/user/views/role' => '@vendor/cinghie/yii2-user-extended/views/role',
                '@dektrium/user/views/security' => '@vendor/cinghie/yii2-user-extended/views/adminlte/security',
                '@dektrium/user/views/settings' => '@vendor/cinghie/yii2-user-extended/views/settings',
            ],
        ],
    ],
]

```

If you have a Yii2 App Advanced **or a CRM that must not expose public signup/password recovery**, attach the userextended filter on the `user` module:

```
'modules' =>  [

    'user' => [
        'class' => 'dektrium\user\Module',
        // 404 on /user/registration/* and /user/recovery/*
        // (unlike dektrium BackendFilter, profile + settings stay available)
        'as backend' => [
            'class' => 'cinghie\userextended\filters\BackendFilter',
            // 'controllers' => ['registration', 'recovery'],
        ],
        'enableRegistration' => false,
        'enablePasswordRecovery' => false,
        'enableImpersonateUser' => false,
        'controllerMap' => [
            'registration' => 'cinghie\userextended\controllers\RegistrationController',
        ],
    ],

],

```

Alternative: set `userextended.blockRegistrationAndRecovery = true` (Bootstrap attaches the same filter if `as backend` is not already set).

Dektrium’s own filter also blocks `profile` and `settings` — prefer userextended on backend/CRM:

```
'as backend' => 'dektrium\user\filters\BackendFilter',

```

### 6. Set captcha in Controller

[](#6-set-captcha-in-controller)

Required when registration captcha is enabled and/or login rate-limit captcha (`loginCaptchaAfterAttempts`) is used.

In your `SiteController` set in `actions()`:

```
'captcha' => [
    'class' => 'yii\captcha\CaptchaAction',
    'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
    'minLength' => 6,
    'maxLength' => 6,
],

```

Allow guests to reach the captcha action in `AccessControl` (`actions` =&gt; `['error', 'captcha']`).

Module parameters (0.6.4)
-------------------------

[](#module-parameters-064)

Parameters are validated in `Module::init()` (ranges clamped; invalid Turnstile/SameSite/password lengths throw `InvalidConfigException`).

### Security presets (`dev` / `prod`)

[](#security-presets-dev--prod)

OptionDescription`securityPreset``null` (off), `auto`, `dev`, or `prod`. Soft-applies recommended defaults only where values are still at factory defaults (explicit config wins). `auto` → `prod` when `YII_ENV_PROD`.```
use cinghie\userextended\Module;

'userextended' => array_merge(Module::securityPreset('prod'), [
    'class' => Module::class,
    // overrides / secrets
    'cloudflareSiteKey' => '...',
    'cloudflareSecretKey' => '...',
]),
```

Or set `'securityPreset' => 'auto'` on the module and override only what you need.

**prod** highlights: `sessionTimeout=1800`, `useAbsoluteAuthTimeout=true`, rate limits + progressive delay on, captcha after 3 failures, password policy on, self-role block + audit on.
**dev** highlights: `sessionTimeout=7200`, no progressive delay / login captcha-after-attempts, Turnstile off, still keeps rate limit + password policy + audit.

### Session expire

[](#session-expire)

ParameterDefaultDescription`sessionTimeout``3600`Idle session/auth timeout in seconds. `0` disables module session handling.`useAbsoluteAuthTimeout``false`If `absoluteAuthTimeout` is `0`, also set `user.absoluteAuthTimeout` to `sessionTimeout`.`absoluteAuthTimeout``0`Max login duration in seconds (`0` = off unless `useAbsoluteAuthTimeout`).`enableClientSessionExpireRedirect``true`Client JS redirects to login with `?expired=1`.`clientWarningBeforeExpire``60`Warning seconds before expire (`0` = off). Capped below `sessionTimeout`.**Docker / YII\_DEBUG note:** the Yii debug toolbar (and Gii) poll via AJAX. Those URLs are ignored for idle renewal (server + client). Still set an explicit `sessionTimeout` in `web-local.php` so `securityPreset=auto` (dev → 7200) does not diverge from your `session.timeout`. Prefer `cookieParams.lifetime = 0` (session cookie) and let `authTimeout` own idle logout. | `clientWarningOnce` | `true` | Show toast at most once per idle cycle. | | `clientSessionHeartbeatInterval` | `0` | Optional heartbeat seconds (`0` = off). While it succeeds, client + server idle timers renew. | | `clientSessionHeartbeatUrl` | `null` | Heartbeat URL; when null and interval &gt; 0, uses `/user/security/session-ping` (204). | | `disableAutoLogin` | `true` | Disable remember-me so idle `authTimeout` works (CRM recommended). | | `hardenSessionCookies` | `true` | Apply HttpOnly / Secure / SameSite on session (and identity) cookies when missing. | | `sessionCookieSecure` | `null` | `null` = auto (HTTPS or prod); `true`/`false` force Secure. | | `sessionSameSite` | `null` | SameSite when unset (`null` → `Lax`). Must be `Lax`/`Strict`/`None` if set. | | `regenerateSessionId` | `true` | Extra session ID regenerate after login (logout uses Yii `logout(true)`). | | `invalidateRememberMeOnAuthTimeout` | `true` | Use `WebUser` so timeout clears remember-me without cookie re-login. |

### Profile / registration UI flags

[](#profile--registration-ui-flags)

ParameterDefaultDescription`avatar``true`Enable avatar field / upload.`avatarPath``@webroot/img/users/`Storage path alias.`avatarURL``@web/img/users/`Public URL alias.`firstname` / `lastname` / `birthday` / `signature``true`Profile fields.`bio` / `contact` / `account` / `location` / `website` / `publicEmail` / `gravatarEmail``false`Optional profile fields.`captcha``true`Yii captcha on registration form.`terms``true`Terms checkbox on registration.`defaultRole``''`Role name assigned after register (empty = none).`onlyEmail``false`Registration email-only mode (Dektrium).`templateLogin``login`Login view name (`login` / `login_prestashop`).`templateRegister``_two_column`Register layout partial.`templateLogoURL``@web/logo.png`Logo for Prestashop-style login.`showAlert` / `showTitles``true`View chrome flags.`socialLogin``false`Social auth UI hooks.`blockRegistrationAndRecovery``false`Bootstrap attaches `BackendFilter` on `user` if missing.### i18n

[](#i18n)

Category `userextended` (`messages/en`, `messages/it`, `sourceLanguage=en`). Covers session expire, login/registration security, password policy, avatar errors, and admin UI labels.

### Assets

[](#assets)

`SessionExpireAsset` publishes from `assets/static/` (`realpath`, not `@vendor/...`). PHP asset classes stay outside `sourcePath`, so they are not web-exposed even when `assetManager.linkAssets` is enabled. In production (`YII_ENV_PROD` or `!YII_DEBUG`) it loads `session-expire.min.js` / `.min.css`; URLs append `?v=` for cache busting. Debug sets `forceCopy` so local edits appear without flushing `web/assets`. Optional app-wide: `assetManager.appendTimestamp = true`.

### Tests

[](#tests)

From the package directory (with the host app’s Composer autoload):

```
vendor/bin/phpunit -c tests/phpunit.xml
```

Covers login rate limit lock/clear, **DB-backed lockout survives cache flush** (`DbRateLimitStoreTest`), UserSearch role SQL-injection rejection, avatar upload validation rejects, admin `switch` forbidden, session `?expired=1` smoke (via `SecurityController::actionLogin`), Turnstile missing/invalid/valid (mock `siteVerifyHandler`), password policy, `ModuleSettings` validation/presets, i18n-safe login lock counting, and **Yii2 best-practice checks** (`Yii2BestPracticesTest`: AccessControl/VerbFilter/CSRF, AssetBundle `sourcePath` + `appendTimestamp`, Assignment `safeAttributes`, BootstrapInterface, parameterized UserSearch SQL, SafeHtml encoding).

### CSRF / HTTP verbs

[](#csrf--http-verbs)

Mutating admin actions (`block`, `confirm`, `delete`, bulk activate/deactivate/delete, `resend-password`) and RBAC role/permission `delete` require **POST**. CSRF is enforced by the controller (`enableCsrfValidation`, default on); ActiveForm emits the token field automatically. Bulk user AJAX posts include the CSRF token explicitly.

### XSS output

[](#xss-output)

ParameterDefaultDescription`signatureAllowHtml``false`If `false`, signature is stored/shown as plain text. If `true`, HtmlPurifier whitelist applies.`signatureAllowedHtml``p,br,strong,...`HtmlPurifier `HTML.Allowed` when HTML is enabled.Bio and name fields are always stripped to plain text on save. Views encode usernames, roles, and attributes; use `Profile::getBioHtml()` / `getSignatureHtml()` for display.

### Password policy

[](#password-policy)

ParameterDefaultDescription`enablePasswordPolicy``true`Enforce complexity rules on new passwords.`passwordMinLength``8`Minimum length (`>= 1`, `= 1`).Uploads are renamed randomly, MIME/`getimagesize` checked, double extensions blocked, path confined under `avatarPath`.

### Login rate limit

[](#login-rate-limit)

ParameterDefaultDescription`enableLoginRateLimit``true`Enable IP + username/email counters.`rateLimitStorage``db`Where counters live: `db` (`{{%userextended_rate_limit}}`, survives cache flush), `cache` (Yii cache/session), `auto` (DB if table exists else cache). **Run userextended migrations** so the table exists when using `db` (default).`loginMaxAttempts``5`Failures before lock.`loginAttemptWindow``900`Counter TTL / window (seconds).`loginLockoutDuration``900`Lock duration (seconds).`loginProgressiveDelay``true`Sleep after failed login.`loginDelayBaseSeconds``1`Delay = min(base × attempts, max).`loginDelayMaxSeconds``5`Max delay.`loginCaptchaAfterAttempts``3`Show Yii captcha after N failures (`0` disables).`loginCaptchaAction``['/site/captcha']`Captcha route.Failed login messages are generic (anti user enumeration).

### Registration (when `user.enableRegistration` is true)

[](#registration-when-userenableregistration-is-true)

Remove `BackendFilter` / set `blockRegistrationAndRecovery` to `false`, then enable:

SettingWhereNotes`enableRegistration``user`Required`enableConfirmation``user`Recommended (email confirm)`captcha``userextended`Yii captcha on register form`terms``userextended`Terms checkbox`enableCloudflareTurnstile` + `cloudflareTurnstileOnRegistration``userextended`Optional Turnstile`enableRegistrationRateLimit``userextended`IP + email throttle (default on)Map `registration` → `cinghie\userextended\controllers\RegistrationController` for throttle on register/resend.

### Password recovery (when `user.enablePasswordRecovery` is true)

[](#password-recovery-when-userenablepasswordrecovery-is-true)

Hardened defaults are applied by Bootstrap via `UserModuleHardening` even while recovery stays disabled in CRM:

SettingDefaultNotes`recoverWithin``3600`Recovery token TTL (1h; Dektrium was 6h) → `user.recoverWithin``confirmWithin``21600`Confirmation token TTL (6h; Dektrium was 24h) → `user.confirmWithin``enableSecureEmailChange``true`Sets `user.emailChangeStrategy = STRATEGY_SECURE``mailPlaintextPasswords``false`No plaintext passwords in welcome/resend mail; admin resend sends a **recovery link** (mail first, then password rotation — no lockout if mail fails)`enableRecoveryRateLimit``true`IP + email throttle on recovery requestMap `recovery` → `cinghie\userextended\controllers\RecoveryController`.

ParameterDefaultDescription`blockRegistrationAndRecovery``false`Bootstrap attaches `BackendFilter` on `user` if no `as backend` yet.`enableRegistrationRateLimit``true`Enable IP + email counters (same `rateLimitStorage` as login).`registrationMaxAttempts``5`Attempts before lock.`registrationAttemptWindow``900`Counter TTL (seconds).`registrationLockoutDuration``900`Lock duration (seconds).`registrationProgressiveDelay``true`Sleep after failed attempt.`registrationDelayBaseSeconds``1`Delay = min(base × attempts, max).`registrationDelayMaxSeconds``5`Max delay.### Cloudflare Turnstile (optional)

[](#cloudflare-turnstile-optional)

ParameterDefaultDescription`enableCloudflareTurnstile``false`Show/validate Turnstile on login. Requires both keys when `true`.`cloudflareSiteKey``''`Public site key.`cloudflareSecretKey``''`Secret key (**web-local / env only**).`cloudflareTurnstileTheme``auto``auto` / `light` / `dark`.`cloudflareTurnstileOnRegistration``false`Also require Turnstile on registration (needs `enableCloudflareTurnstile`).Fail closed: missing/invalid token denies login. Script is loaded only when enabled and configured. Use together with rate limit (Turnstile first, rate limit second).

### Caching / performance

[](#caching--performance)

ParameterDefaultDescription`enableRbacRoleCache``true`Cache role name list for admin filters.`rbacRoleCacheDuration``3600`Cache TTL (seconds).Map `rbac` `RoleController` / `PermissionController` / `AssignmentController` to the userextended controllers so role-list cache is invalidated, deletes are POST-only, and assignments use the secured model.

### RBAC assignment security

[](#rbac-assignment-security)

ParameterDefaultDescription`blockSelfRoleAssignment``true`Deny adding new roles/permissions to your own user.`enableRbacAssignmentAudit``true`Log assignment changes (requires `enableSecurityAudit`).`enableSecurityAudit``true`Structured security events (login, block/delete, Turnstile, session, RBAC) via logger or `Yii::info` (`userextended.security`). Never logs passwords/tokens.Assignment updates go through `AdminController::actionAssignments` (and `/rbac/assignment/assign`) with admin AccessControl, CSRF, and VerbFilter. Self-escalation attempts are blocked and audited.

Admin user grid uses eager loading for `profile` / `roles`. Impersonation (`user/admin/switch`) is disabled in this package (`AdminController` + `enableImpersonateUser => false`).

Overrides
---------

[](#overrides)

Override controller example, on modules config

```
'modules' => [

	'userextended' => [
		'class' => 'cinghie\userextended\Module',
		'controllerMap' => [
			'items' => 'app\controllers\AdminController',
			'items' => 'app\controllers\SecurityController',
			'items' => 'app\controllers\SettingsController',
		]
	]

],

```

Override models example, on modules config

```
'modules' => [

	'userextended' => [
		'class' => 'cinghie\userextended\Module',
		'modelMap' => [
			'Account' => 'app\models\Account',
			'Assignment' => 'app\models\Assignment',
			'LoginForm' => 'app\models\LoginForm',
			'Permission' => 'app\models\Permission',
			'Profile' => 'app\models\Profile',
			'RegistrationForm' => 'app\models\RegistrationForm',
			'SettingsForm' => 'app\models\SettingsForm',
			'User' => 'app\models\User',
		]
	]

],

```

Override view example, on components config

```
'components' => [

	'view' => [
		'theme' => [
			'pathMap' => [
				'@cinghie/userextended/views/admin' => '@app/views/userextended/admin',
			],
		],
	],

],

```

Features
--------

[](#features)

1. Add new fields to user profile (optional params)
    - avatar:
        1. The avatar can be uploaded
        2. The avatar can be updated
        3. On update avatar old image was deleted
        4. Hardened upload (MIME/extension whitelist, max size, safe rename, path confinement)
    - birthday
    - captcha
    - firstname
    - lastname
    - name (firstname + lastname)
    - signature
    - terms
2. Add yii2-user fields to user profile like optional params
    - bio
    - gravatar email
    - location
    - public email
    - website
3. Add default Role on User Registration
4. Session timeout with optional client redirect / warning
5. Login brute-force protection (rate limit, lockout, progressive delay, captcha after N failures)
6. Registration throttle (IP + email) + BackendFilter for CRM/backend (blocks registration/recovery)
7. RBAC assignment hardening (CSRF, admin-only, block self-escalation, audit)
8. Structured security audit (login, block/delete, Turnstile, session expire; no secrets)
9. Optional Cloudflare Turnstile on login (and registration)
10. Admin users grid performance (eager loading, role cache, DB indexes)
11. User impersonation disabled by default

###  Health Score

51

—

FairBetter than 95% of packages

Maintenance85

Actively maintained with recent releases

Popularity28

Limited adoption so far

Community17

Small or concentrated contributor base

Maturity64

Established project with proven stability

 Bus Factor1

Top contributor holds 99.6% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~124 days

Recently: every ~842 days

Total

33

Last Release

30d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/cfedb99c8fcbaf668c4f9779d341997b84029673eda224241b11732981cbc8b2?d=identicon)[cinghie](/maintainers/cinghie)

---

Top Contributors

[![cinghie](https://avatars.githubusercontent.com/u/2445152?v=4)](https://github.com/cinghie "cinghie (277 commits)")[![valexus1](https://avatars.githubusercontent.com/u/7592441?v=4)](https://github.com/valexus1 "valexus1 (1 commits)")

---

Tags

yii2-useryii2 user managementyii2 user fieldyii2 user extended

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/cinghie-yii2-user-extended/health.svg)

```
[![Health](https://phpackages.com/badges/cinghie-yii2-user-extended/health.svg)](https://phpackages.com/packages/cinghie-yii2-user-extended)
```

###  Alternatives

[skeeks/cms

SkeekS CMS — control panel and tools based on php framework Yii2

13926.0k66](/packages/skeeks-cms)[craftcms/cms

Craft CMS

3.6k3.7M3.4k](/packages/craftcms-cms)[dektrium/yii2-user

Flexible user registration and authentication module for Yii2

911824.4k39](/packages/dektrium-yii2-user)[yii2mod/yii2-user

User module

2817.6k1](/packages/yii2mod-yii2-user)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
