PHPackages                             ninjaportal/portal-mfa - 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. ninjaportal/portal-mfa

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

ninjaportal/portal-mfa
======================

Configurable MFA package for NinjaPortal actors (admin + consumer)

0.1(2mo ago)00MITPHPPHP ^8.2

Since Feb 28Pushed 2mo agoCompare

[ Source](https://github.com/ninjaportal/portal-mfa)[ Packagist](https://packagist.org/packages/ninjaportal/portal-mfa)[ RSS](/packages/ninjaportal-portal-mfa/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (1)Dependencies (9)Versions (2)Used By (0)

NinjaPortal Portal MFA
======================

[](#ninjaportal-portal-mfa)

Configurable multi-factor authentication package for NinjaPortal (`portal` + `portal-api`).

Features
--------

[](#features)

- MFA for all actors (`consumer`, `admin`) with per-actor config
- Drivers:
    - Authenticator app (TOTP)
    - Email OTP
- Per-user MFA settings and factor management endpoints
- Extensible driver registry for custom MFA drivers
- Integrates with `portal-api` auth flow through `AuthFlowInterface`

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

[](#installation)

```
composer require ninjaportal/portal-mfa
php artisan migrate
```

The package auto-discovers its service provider and overrides `portal-api`'s `AuthFlowInterface`binding to insert an MFA challenge step before token issuance.

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

[](#configuration)

Publish config (optional):

```
php artisan vendor:publish --tag=portal-mfa-config
```

Main config file: `config/portal-mfa.php`

Key areas:

- `enabled`: enable/disable MFA package globally
- `actors.*`: per-actor MFA policy (`enabled`, `required`, allowed drivers)
- `drivers.map`: register built-in or custom drivers
- `drivers.authenticator`: TOTP issuer/window/period/digits
- `drivers.email_otp`: OTP TTL/resend/attempt/notification settings
- `challenge.*`: challenge token length and pruning retention

Extending Drivers
-----------------

[](#extending-drivers)

Register custom driver classes in `portal-mfa.drivers.map`. Each driver must implement `NinjaPortal\Mfa\Contracts\Drivers\MfaDriverInterface`. Drivers that support factor setup flows should also implement `NinjaPortal\Mfa\Contracts\Drivers\EnrollsMfaFactorInterface`.

Login Flow (MFA Challenge)
--------------------------

[](#login-flow-mfa-challenge)

1. Password is validated by the MFA auth-flow decorator.
2. If MFA is not required/enabled for the actor/account, tokens are issued normally.
3. If MFA is required/enabled, login returns HTTP `202` with an MFA challenge payload.
4. Client verifies the challenge using the package endpoint.
5. Tokens are issued after successful MFA verification.

Example `202` challenge response:

```
{
  "success": true,
  "status": 202,
  "message": "MFA challenge required.",
  "data": {
    "mfa_required": true,
    "challenge_type": "login",
    "challenge_token": "",
    "driver": "email_otp",
    "context": "consumer",
    "purpose": "login",
    "expires_at": "2026-02-24T20:30:00Z",
    "can_resend": true,
    "masked_destination": "j***e@example.com"
  },
  "meta": null
}
```

API Endpoints (provided by this package)
----------------------------------------

[](#api-endpoints-provided-by-this-package)

- Consumer login challenge verify/resend
- Admin login challenge verify/resend
- Consumer `/me/mfa/*` settings and factor management
- Admin `/admin/me/mfa/*` settings and factor management

Commands
--------

[](#commands)

- `php artisan portal-mfa:challenges:prune`

###  Health Score

33

—

LowBetter than 75% of packages

Maintenance86

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity36

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% 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

Unknown

Total

1

Last Release

73d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/572472a15d795bd58c160445f6e9298cd82b756bf4355e860491785b5398d6f7?d=identicon)[Youssef20](/maintainers/Youssef20)

---

Top Contributors

[![lordjoo](https://avatars.githubusercontent.com/u/11289152?v=4)](https://github.com/lordjoo "lordjoo (2 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/ninjaportal-portal-mfa/health.svg)

```
[![Health](https://phpackages.com/badges/ninjaportal-portal-mfa/health.svg)](https://phpackages.com/packages/ninjaportal-portal-mfa)
```

###  Alternatives

[spatie/laravel-permission

Permission handling for Laravel 12 and up

12.9k89.8M1.0k](/packages/spatie-laravel-permission)[bezhansalleh/filament-shield

Filament support for `spatie/laravel-permission`.

2.8k2.9M88](/packages/bezhansalleh-filament-shield)[php-open-source-saver/jwt-auth

JSON Web Token Authentication for Laravel and Lumen

8359.8M53](/packages/php-open-source-saver-jwt-auth)[illuminate/auth

The Illuminate Auth package.

9327.3M1.0k](/packages/illuminate-auth)[spatie/laravel-login-link

Quickly login to your local environment

4381.2M1](/packages/spatie-laravel-login-link)[ryangjchandler/laravel-cloudflare-turnstile

A simple package to help integrate Cloudflare Turnstile.

438896.6k2](/packages/ryangjchandler-laravel-cloudflare-turnstile)

PHPackages © 2026

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