48 lines
3.7 KiB
PHP
48 lines
3.7 KiB
PHP
<?php
|
|
// Copied to the isolated QA tree. Never run against the project served by Apache.
|
|
ini_set('zend.exception_ignore_args', '1');
|
|
set_exception_handler(static function (Throwable $e): void { fwrite(STDERR, 'QA onboarding stopped: '.$e::class.' at '.basename($e->getFile()).':'.$e->getLine().PHP_EOL); exit(1); });
|
|
$root=dirname(__DIR__);
|
|
if (!str_contains($root, 'onboarding-qa-')) { throw new RuntimeException('Separate QA source required.'); }
|
|
require $root.'/qa-autoload.php';
|
|
$app=require $root.'/bootstrap/app.php';
|
|
(new Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables)->bootstrap($app);
|
|
(new Illuminate\Foundation\Bootstrap\LoadConfiguration)->bootstrap($app);
|
|
$connection=config('database.connections.'.config('database.default'));
|
|
throw_unless($connection['driver']==='pgsql' && (int)$connection['port']===55441 && str_starts_with($connection['database'],'onboarding_')
|
|
&& str_ends_with($connection['database'],'_test') && in_array($connection['host'],['127.0.0.1','localhost'],true) && empty($connection['url']), RuntimeException::class);
|
|
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
|
|
throw_unless((int)Illuminate\Support\Facades\DB::selectOne('SELECT inet_server_port() AS port')->port===55441, RuntimeException::class);
|
|
$private=$root.'/storage/app/private/onboarding-actors-local.json';
|
|
$action=$argv[1]??'seed';
|
|
if($action==='otp') {
|
|
$actors=json_decode(file_get_contents($private),true,512,JSON_THROW_ON_ERROR);
|
|
$actor=$actors[$argv[2]??'holder'];
|
|
$user=App\Models\User::findOrFail($actor['id']);
|
|
$secret=Laravel\Fortify\Fortify::currentEncrypter()->decrypt($user->two_factor_secret);
|
|
// The caller consumes the code in memory; it is never part of evidence or logs.
|
|
echo app(PragmaRX\Google2FA\Google2FA::class)->getCurrentOtp($secret);
|
|
exit;
|
|
}
|
|
if($action==='verify') {
|
|
$db=Illuminate\Support\Facades\DB::class;
|
|
$proof=['QA_only'=>true,'port'=>55441,'database'=>$connection['database'],'assignments'=>$db::table('portal_role_assignments')->get(['user_id','role','organization_id','opportunity_types'])->all(),
|
|
'opportunities'=>$db::table('opportunities')->count(),'audit_role_granted'=>$db::table('audit_events')->where('action','role_granted')->count(),
|
|
'operational_enabled'=>(bool)config('portal.profile_access_enabled'),'administration_enabled'=>(bool)config('portal.profile_administration_enabled')];
|
|
echo json_encode($proof,JSON_THROW_ON_ERROR).PHP_EOL; exit;
|
|
}
|
|
throw_unless($action==='seed' && !is_file($private), RuntimeException::class, 'Fixture already present');
|
|
$actors=[];
|
|
foreach(['holder','other_holder','validator'] as $role) {
|
|
$password='QA-'.bin2hex(random_bytes(20));
|
|
$user=App\Models\User::factory()->create(['name'=>'Synthetic onboarding QA '.$role,'email'=>'onboarding-'.$role.'@example.invalid','password'=>$password]);
|
|
app(Laravel\Fortify\Actions\EnableTwoFactorAuthentication::class)($user);
|
|
$user->refresh();
|
|
$secret=Laravel\Fortify\Fortify::currentEncrypter()->decrypt($user->two_factor_secret);
|
|
app(Laravel\Fortify\Actions\ConfirmTwoFactorAuthentication::class)($user,app(PragmaRX\Google2FA\Google2FA::class)->getCurrentOtp($secret));
|
|
$actors[$role]=['id'=>$user->id,'email'=>$user->email,'password'=>$password];
|
|
}
|
|
Illuminate\Support\Facades\DB::table('portal_superuser_pair')->insert(['id'=>1,'first_user_id'=>$actors['holder']['id'],'second_user_id'=>$actors['other_holder']['id'],'approved_by'=>$actors['other_holder']['id']]);
|
|
file_put_contents($private,json_encode($actors,JSON_THROW_ON_ERROR));
|
|
echo json_encode(['result'=>'synthetic_QA_identity_fixtures_prepared','normal_Fortify_enrollment'=>true,'verified_contact'=>'synthetic_factory_fixture_only','port'=>55441,'emails_sent'=>0,'active_writes'=>0],JSON_THROW_ON_ERROR).PHP_EOL;
|