init web ems all

This commit is contained in:
agtuser
2024-09-27 17:13:36 +08:00
parent 81c97acbe9
commit 5cc56f8078
4263 changed files with 798779 additions and 0 deletions

View File

@@ -0,0 +1,135 @@
<?php
namespace PragmaRX\Google2FA\Support;
use ParagonIE\ConstantTime\Base32 as ParagonieBase32;
use PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException;
use PragmaRX\Google2FA\Exceptions\InvalidCharactersException;
trait Base32
{
/**
* Enforce Google Authenticator compatibility.
*/
protected $enforceGoogleAuthenticatorCompatibility = true;
/**
* Generate a digit secret key in base32 format.
*
* @param int $length
*
* @return string
*/
public function generateBase32RandomKey($length = 16, $prefix = '')
{
$secret = $prefix ? $this->toBase32($prefix) : '';
$secret = $this->strPadBase32($secret, $length);
$this->validateSecret($secret);
return $secret;
}
/**
* Decodes a base32 string into a binary string.
*
* @param string $b32
*
* @throws InvalidCharactersException
*
* @return int
*/
public function base32Decode($b32)
{
$b32 = strtoupper($b32);
$this->validateSecret($b32);
return ParagonieBase32::decodeUpper($b32);
}
/**
* Pad string with random base 32 chars.
*
* @param $string
* @param $length
*
* @return string
*/
private function strPadBase32($string, $length)
{
for ($i = 0; $i < $length; $i++) {
$string .= substr(Constants::VALID_FOR_B32_SCRAMBLED, $this->getRandomNumber(), 1);
}
return $string;
}
/**
* Encode a string to Base32.
*
* @param $string
*
* @return mixed
*/
public function toBase32($string)
{
$encoded = ParagonieBase32::encodeUpper($string);
return str_replace('=', '', $encoded);
}
/**
* Get a random number.
*
* @param $from
* @param $to
*
* @return int
*/
protected function getRandomNumber($from = 0, $to = 31)
{
return random_int($from, $to);
}
/**
* Validate the secret.
*
* @param $b32
*/
protected function validateSecret($b32)
{
$this->checkForValidCharacters($b32);
$this->checkGoogleAuthenticatorCompatibility($b32);
}
/**
* Check if the secret key is compatible with Google Authenticator.
*
* @param $b32
*
* @throws IncompatibleWithGoogleAuthenticatorException
*/
protected function checkGoogleAuthenticatorCompatibility($b32)
{
if ($this->enforceGoogleAuthenticatorCompatibility && ((strlen($b32) & (strlen($b32) - 1)) !== 0)) {
throw new IncompatibleWithGoogleAuthenticatorException();
}
}
/**
* Check if all secret key characters are valid.
*
* @param $b32
*
* @throws InvalidCharactersException
*/
protected function checkForValidCharacters($b32)
{
if (preg_replace('/[^'.Constants::VALID_FOR_B32.']/', '', $b32) !== $b32) {
throw new InvalidCharactersException();
}
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace PragmaRX\Google2FA\Support;
class Constants
{
/**
* Characters valid for Base 32.
*/
const VALID_FOR_B32 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
/**
* Characters valid for Base 32, scrambled.
*/
const VALID_FOR_B32_SCRAMBLED = '234567QWERTYUIOPASDFGHJKLZXCVBNM';
/**
* Argument not set constant.
*/
const ARGUMENT_NOT_SET = '__not_set__';
}

View File

@@ -0,0 +1,91 @@
<?php
namespace PragmaRX\Google2FA\Support;
use BaconQrCode\Renderer\Image\Png;
use BaconQrCode\Writer as BaconQrCodeWriter;
use PragmaRX\Google2FA\Exceptions\InsecureCallException;
trait QRCode
{
/**
* Sending your secret key to Google API is a security issue. Developer must explicitly allow it.
*/
protected $allowInsecureCallToGoogleApis = false;
/**
* Creates a Google QR code url.
*
* @param string $company
* @param string $holder
* @param string $secret
* @param int $size
*
* @throws InsecureCallException
*
* @return string
*/
public function getQRCodeGoogleUrl($company, $holder, $secret, $size = 200)
{
if (!$this->allowInsecureCallToGoogleApis) {
throw new InsecureCallException('It\'s not secure to send secret keys to Google Apis, you have to explicitly allow it by calling $google2fa->setAllowInsecureCallToGoogleApis(true).');
}
$url = $this->getQRCodeUrl($company, $holder, $secret);
return Url::generateGoogleQRCodeUrl('https://chart.googleapis.com/', 'chart', 'chs='.$size.'x'.$size.'&chld=M|0&cht=qr&chl=', $url);
}
/**
* Generates a QR code data url to display inline.
*
* @param string $company
* @param string $holder
* @param string $secret
* @param int $size
* @param string $encoding Default to UTF-8
*
* @return string
*/
public function getQRCodeInline($company, $holder, $secret, $size = 200, $encoding = 'utf-8')
{
$url = $this->getQRCodeUrl($company, $holder, $secret);
$renderer = new Png();
$renderer->setWidth($size);
$renderer->setHeight($size);
$bacon = new BaconQrCodeWriter($renderer);
$data = $bacon->writeString($url, $encoding);
return 'data:image/png;base64,'.base64_encode($data);
}
/**
* Creates a QR code url.
*
* @param $company
* @param $holder
* @param $secret
*
* @return string
*/
public function getQRCodeUrl($company, $holder, $secret)
{
return 'otpauth://totp/'.rawurlencode($company).':'.rawurlencode($holder).'?secret='.$secret.'&issuer='.rawurlencode($company).'';
}
/**
* AllowInsecureCallToGoogleApis setter.
*
* @param mixed $allowInsecureCallToGoogleApis
*
* @return QRCode
*/
public function setAllowInsecureCallToGoogleApis($allowInsecureCallToGoogleApis)
{
$this->allowInsecureCallToGoogleApis = $allowInsecureCallToGoogleApis;
return $this;
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace PragmaRX\Google2FA\Support;
class Url
{
public static function generateGoogleQRCodeUrl($domain, $page, $queryParameters, $qrCodeUrl)
{
$url = $domain.
rawurlencode($page).
'?'.$queryParameters.
urlencode($qrCodeUrl);
return $url;
}
}