diff --git a/README.md b/README.md index 547e019..35899d5 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ For a secure installation you have to make sure that used codes cannot be reused - Built-in validation methods. - Secret key generation for TOTP. - Compatible with Google Authenticator and similar apps. +- Generate QR code payloads for easy integration with TOTP applications. ## Installation @@ -67,6 +68,18 @@ $secret = $ga->createSecret(); echo "Your secret key is: " . $secret; ``` +### Generating a QR Code Payload + +To generate a QR code payload for a TOTP secret, use the `getQrCodePayload` function: + +```php +$label = 'user@example.com'; // The user's email or username +$issuer = 'MyApp'; // Optional issuer name + +$qrcodePayload = $totp->getQrCodePayload($secret, $label, $issuer); +echo "QR Code Payload: " . $qrcodePayload . "\n"; +``` + ### Validating a TOTP Code You can validate a TOTP code using the `verifyCode` method: diff --git a/src/Base32.php b/src/Base32.php index ce4d255..1b156a6 100644 --- a/src/Base32.php +++ b/src/Base32.php @@ -70,40 +70,12 @@ public function _base32Decode($secret) */ public function _getBase32LookupTable() { - return array( - 'A', - 'B', - 'C', - 'D', - 'E', - 'F', - 'G', - 'H', // 7 - 'I', - 'J', - 'K', - 'L', - 'M', - 'N', - 'O', - 'P', // 15 - 'Q', - 'R', - 'S', - 'T', - 'U', - 'V', - 'W', - 'X', // 23 - 'Y', - 'Z', - '2', - '3', - '4', - '5', - '6', - '7', // 31 + return [ + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 7 + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15 + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23 + 'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31 '=', // padding char - ); + ]; } } diff --git a/src/Totp.php b/src/Totp.php index efe46c2..a96d686 100644 --- a/src/Totp.php +++ b/src/Totp.php @@ -45,6 +45,26 @@ public function createSecret(int $secretLength = 16): string return $secret; } + /** + * Generate a QR code payload for the given secret. + * + * @param string $secret The TOTP secret. + * @param string $label The label for the account (e.g., email, username). + * @param string|null $issuer Optional issuer name for the TOTP app. + * + * @return string The QR code payload. + */ + public function getQrCodePayload(string $secret, string $label, ?string $issuer = null): string + { + $payload = 'otpauth://totp/' . $label . '?secret=' . $secret; + + if ($issuer) { + $payload .= '&issuer=' . $issuer; + } + + return $payload; + } + /** * Calculate the code, with given secret and point in time. * diff --git a/tests/TotpTest.php b/tests/TotpTest.php index 1fc1996..1f4867a 100644 --- a/tests/TotpTest.php +++ b/tests/TotpTest.php @@ -36,6 +36,20 @@ public function testCreateSecretInvalidLengthThrowsException() $this->totp->createSecret(10); // Invalid length less than 16 } + public function testGetQrCodePayload() + { + $secret = $this->totp->createSecret(); + $label = 'user@example.com'; + $issuer = 'MyApp'; + + $payload = $this->totp->getQrCodePayload($secret, $label, $issuer); + + $this->assertStringStartsWith('otpauth://totp/', $payload); + $this->assertStringContainsString('totp/' . $label, $payload); + $this->assertStringContainsString('issuer=' . $issuer, $payload); + $this->assertStringContainsString('secret=' . $secret, $payload); + } + public function testGetCode() { $secret = $this->totp->createSecret();