Skip to content

Commit bb87f30

Browse files
committed
docs: Update README with new configurable channel classes and challenge generation features
- Add documentation for custom channel class configuration - Add examples for extending Email and SMS channels via config - Add documentation for challenge generation without sending - Add programmatic channel registration examples - Update API overview with new methods - Add environment variable examples for custom channels - Maintain existing documentation structure and clarity
1 parent 32c08ef commit bb87f30

File tree

1 file changed

+82
-3
lines changed

1 file changed

+82
-3
lines changed

README.md

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ php artisan migrate
2020

2121
Features
2222
- **Email** and **SMS** one-time code challenges with pluggable channels
23+
- **Configurable channel classes** - extend Email and SMS channels via configuration
24+
- **Challenge generation without sending** - generate codes without automatic delivery
2325
- Google Authenticator compatible **TOTP** (RFC 6238) setup and verification
2426
- Built-in QR code generation to display TOTP provisioning URI (uses bacon/bacon-qr-code)
2527
- Remember device support via secure, hashed tokens stored in `mfa_remembered_devices`
@@ -42,11 +44,17 @@ Usage
4244
```php
4345
use CodingLibs\MFA\Facades\MFA;
4446

45-
// Email/SMS
47+
// Email/SMS - Generate and send automatically
4648
$challenge = MFA::issueChallenge(auth()->user(), 'email');
4749
// then later
4850
$ok = MFA::verifyChallenge(auth()->user(), 'email', '123456');
4951

52+
// Generate challenge without sending
53+
$challenge = MFA::generateChallenge(auth()->user(), 'email');
54+
// or
55+
$challenge = MFA::issueChallenge(auth()->user(), 'email', false);
56+
// Now handle sending manually
57+
5058
// TOTP
5159
$setup = MFA::setupTotp(auth()->user());
5260
// $setup['otpauth_url'] -> QR code; then verify
@@ -129,10 +137,12 @@ Configuration
129137
- **email**:
130138
- enabled (bool)
131139
- from_address, from_name, subject
140+
- channel: custom channel class (default: EmailChannel)
132141
- **sms**:
133142
- enabled (bool)
134143
- driver: `log` (default) or custom integration
135144
- from: optional sender id/number
145+
- channel: custom channel class (default: SmsChannel)
136146
- **totp**:
137147
- issuer: defaults to `config('app.name')`
138148
- digits: 6 by default
@@ -155,9 +165,11 @@ Environment variables (examples)
155165
MFA_EMAIL_FROM_ADDRESS="no-reply@example.com"
156166
MFA_EMAIL_FROM_NAME="Example App"
157167
MFA_EMAIL_SUBJECT="Your verification code"
168+
MFA_EMAIL_CHANNEL="App\Channels\CustomEmailChannel"
158169
159170
MFA_SMS_DRIVER=log
160171
MFA_SMS_FROM="ExampleApp"
172+
MFA_SMS_CHANNEL="App\Channels\CustomSmsChannel"
161173
162174
MFA_TOTP_ISSUER="Example App"
163175
MFA_TOTP_DIGITS=6
@@ -188,7 +200,8 @@ Database
188200
- `mfa_recovery_codes`: stores hashed recovery codes and usage timestamp
189201

190202
API Overview (Facade `MFA`)
191-
- **issueChallenge(Authenticatable $user, string $method): ?MfaChallenge**
203+
- **issueChallenge(Authenticatable $user, string $method, bool $send = true): ?MfaChallenge**
204+
- **generateChallenge(Authenticatable $user, string $method): ?MfaChallenge** - Generate without sending
192205
- **verifyChallenge(Authenticatable $user, string $method, string $code): bool**
193206
- **setupTotp(Authenticatable $user, ?string $issuer = null, ?string $label = null): array** returns `['secret','otpauth_url']`
194207
- **verifyTotp(Authenticatable $user, string $code): bool**
@@ -210,7 +223,73 @@ API Overview (Facade `MFA`)
210223
- **getRemainingRecoveryCodesCount(Authenticatable $user): int**
211224
- **clearRecoveryCodes(Authenticatable $user): int**
212225

213-
Creating a Custom MFA Channel
226+
## Custom Channel Classes
227+
228+
### Configuration-Based Custom Channels
229+
230+
You can extend the built-in Email and SMS channels by configuring custom channel classes:
231+
232+
```php
233+
// config/mfa.php
234+
'email' => [
235+
'enabled' => true,
236+
'channel' => \App\Channels\CustomEmailChannel::class,
237+
'from_address' => 'noreply@example.com',
238+
// ... other config
239+
],
240+
241+
'sms' => [
242+
'enabled' => true,
243+
'channel' => \App\Channels\CustomSmsChannel::class,
244+
'driver' => 'custom',
245+
// ... other config
246+
],
247+
```
248+
249+
```php
250+
// app/Channels/CustomEmailChannel.php
251+
use CodingLibs\MFA\Channels\EmailChannel;
252+
253+
class CustomEmailChannel extends EmailChannel
254+
{
255+
public function send(Authenticatable $user, string $code, array $options = []): void
256+
{
257+
// Custom sending logic
258+
Mail::to($user->email)->send(new CustomMfaMail($code, $this->config));
259+
}
260+
}
261+
```
262+
263+
### Programmatic Channel Registration
264+
265+
```php
266+
// In a service provider
267+
MFA::registerChannelFromConfig('custom_channel', [
268+
'channel' => CustomChannel::class,
269+
'channel_name' => 'custom_channel',
270+
'custom_setting' => 'value'
271+
]);
272+
```
273+
274+
## Challenge Generation Without Sending
275+
276+
Generate challenge codes without automatic delivery:
277+
278+
```php
279+
// Generate challenge without sending
280+
$challenge = MFA::generateChallenge(auth()->user(), 'email');
281+
echo $challenge->code; // Use the code as needed
282+
283+
// Or use issueChallenge with send=false
284+
$challenge = MFA::issueChallenge(auth()->user(), 'email', false);
285+
286+
// Manual sending
287+
$channel = MFA::getChannel('email');
288+
$channel->send(auth()->user(), $challenge->code, ['subject' => 'Custom Subject']);
289+
```
290+
291+
## Creating a Custom MFA Channel
292+
214293
Steps
215294
1. Implement `CodingLibs\MFA\Contracts\MfaChannel` with a unique `getName()` and a `send(...)` method
216295
2. Register your channel during app boot (e.g., in a service provider) via `MFA::registerChannel(...)`

0 commit comments

Comments
 (0)