generated from jric11/baseProject
28 lines
1.6 KiB
PHP
28 lines
1.6 KiB
PHP
|
|
<?php
|
||
|
|
if(PHP_SAPI!=='cli')exit;
|
||
|
|
require __DIR__.'/../classes/Base.php';
|
||
|
|
if(!preg_match('/\Ahcr_http_test_[a-f0-9]{12}\z/',getenv('HCR_DB_NAME')?:''))throw new RuntimeException('Disposable database required.');
|
||
|
|
ob_start();session_start();
|
||
|
|
class SilentRaceMfa extends MfaService {protected function notify(array $account,string $event):void {}}
|
||
|
|
$mfa=new SilentRaceMfa();$password='Admin test password 123!';
|
||
|
|
if(($argv[1]??'')==='seed'){
|
||
|
|
(new AuthService())->login('admin@example.test',$password);
|
||
|
|
$secret=OTPHP\TOTP::generate(new MfaClock())->getSecret();
|
||
|
|
$_SESSION['mfa_pending']=['user'=>1,'secret'=>$secret,'expires'=>time()+600];
|
||
|
|
$codes=$mfa->enroll(1,$secret,OTPHP\TOTP::createFromSecret($secret,new MfaClock())->now(),$password);
|
||
|
|
$base=$_SESSION;$states=[];
|
||
|
|
foreach([$codes[0],$codes[1]] as $code){$_SESSION=$base;$mfa->beginReplacement(1,$code,$password);$states[]=$_SESSION;}
|
||
|
|
ob_clean();echo json_encode(['states'=>$states,'recovery'=>$codes[2]]);ob_end_flush();exit;
|
||
|
|
}
|
||
|
|
$payload=json_decode(trim(fgets(STDIN)),true,512,JSON_THROW_ON_ERROR);$_SESSION=$payload['state'];
|
||
|
|
ob_clean();fwrite(STDOUT,"READY\n");fflush(STDOUT);fgets(STDIN);
|
||
|
|
try{
|
||
|
|
if($argv[1]==='replace'){
|
||
|
|
$secret=$_SESSION['mfa_replacement']['secret'];
|
||
|
|
$codes=$mfa->completeReplacement(1,OTPHP\TOTP::createFromSecret($secret,new MfaClock())->now(),$password);
|
||
|
|
$ok=count($codes)===10;
|
||
|
|
}else $ok=$mfa->verify(1,$payload['recovery'],$password);
|
||
|
|
$result=['ok'=>$ok];
|
||
|
|
}catch(AppException $error){$result=['ok'=>false,'status'=>$error->status];}
|
||
|
|
ob_clean();echo json_encode($result);ob_end_flush();
|