Files
Investidor-V2/tools/portal-country-https-persistence.php
T
nala 287e991486
tests / ci (push) Waiting to run
oportunidades 7
2026-10-13 11:40:29 +02:00

50 lines
7.1 KiB
PHP

<?php
// READ ONLY SQL proof on the exact browser clone; no original data or key emitted.
$root=dirname(__DIR__);$dir=$root.'/storage/app/private/investmoz-v2/portal-audit';
$link=json_decode(file_get_contents($dir.'/country-https-backup-latest.json'),true,512,JSON_THROW_ON_ERROR);
$backup=json_decode(file_get_contents($link['path']),true,512,JSON_THROW_ON_ERROR);
$browser=json_decode(file_get_contents($dir.'/country-https-chromium-20261011.json'),true,512,JSON_THROW_ON_ERROR);$target=$backup['restored_target'];
if((int)$target['port']!==55441||!preg_match('/^country_candidate_\d{8}_\d{6}_test$/D',$target['database'])||$browser['result']!=='passed'||$browser['code_hash']!==$backup['code_hash']||$browser['target']!==$target)throw new RuntimeException('Exact passed HTTPS clone required');
$pdo=new PDO('pgsql:host=127.0.0.1;port=55441;dbname='.$target['database'],'postgres','',[PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION]);$pdo->exec('BEGIN ISOLATION LEVEL REPEATABLE READ READ ONLY');
$identity=$pdo->query("SELECT current_database() AS database,inet_server_port() AS port,current_setting('transaction_read_only') AS read_only")->fetch(PDO::FETCH_ASSOC);
if($identity['database']!==$target['database']||(int)$identity['port']!==55441||$identity['read_only']!=='on')throw new RuntimeException('Identity refused');
$tables=$pdo->query("SELECT schemaname,tablename FROM pg_tables WHERE schemaname NOT IN ('pg_catalog','information_schema') ORDER BY schemaname,tablename")->fetchAll(PDO::FETCH_ASSOC);
if(count($tables)!==count($backup['tables']))throw new RuntimeException('Unexpected new table');
$originalChanges=[];
foreach($tables as $t){
$name='"'.str_replace('"','""',$t['schemaname']).'"."'.str_replace('"','""',$t['tablename']).'"';
$filter=match($name){
'"public"."users"'=>" WHERE email <> 'country-production-installer@example.invalid'",
'"public"."organizations"'=>" WHERE source_system IS DISTINCT FROM 'candidate-browser-qa-only'",
'"public"."memberships"'=>" WHERE organization_id NOT IN (SELECT id FROM organizations WHERE source_system='candidate-browser-qa-only')",
'"public"."audit_events"'=>" WHERE source_system NOT IN ('organization-country-installation','organization-country') OR source_system IS NULL",
'"public"."migrations"'=>" WHERE migration <> '2026_10_10_050000_extend_organization_country'",default=>''};
$rows=$pdo->query('SELECT row_to_json(t)::text FROM '.$name.' t'.$filter.' ORDER BY row_to_json(t)::text')->fetchAll(PDO::FETCH_COLUMN);
if(['count'=>count($rows),'sha256'=>hash('sha256',implode("\n",$rows))]!==$backup['tables'][$name])$originalChanges[]=$name;
}
if(array_diff($originalChanges,['"public"."sessions"'])!==[])throw new RuntimeException('Original business data changed');
$stmt=$pdo->prepare("SELECT * FROM organizations WHERE id=:id AND source_system='candidate-browser-qa-only'");$stmt->execute(['id'=>$browser['organization_id']]);$org=$stmt->fetch(PDO::FETCH_ASSOC);
if(!$org||$org['incorporation_country_code']!=='MZ'||(int)$org['version_no']!==3)throw new RuntimeException('Stored UI result differs');
$provenance=json_decode($org['incorporation_country_provenance'],true,512,JSON_THROW_ON_ERROR);
if($provenance['reference']!=='Synthetic HTTPS QA country declaration update'||$provenance['kind']!=='representative_declaration')throw new RuntimeException('Provenance differs');
$installs=$pdo->query("SELECT correlation_id,after_data FROM audit_events WHERE source_system='organization-country-installation'")->fetchAll(PDO::FETCH_ASSOC);
if(count($installs)!==1||$installs[0]['correlation_id']!==$browser['operation_key'])throw new RuntimeException('Installation audit differs');
$result=json_decode($installs[0]['after_data'],true,512,JSON_THROW_ON_ERROR);
if($result['code_hash']!==$backup['code_hash']||$result['result']['new_columns']!==2||$result['result']['new_tables']!==0)throw new RuntimeException('Installation receipt differs');
$edits=$pdo->query("SELECT before_data,after_data FROM audit_events WHERE source_system='organization-country' ORDER BY id")->fetchAll(PDO::FETCH_ASSOC);
if(count($edits)!==2)throw new RuntimeException('Expected two UI edits');
require $root.'/vendor/autoload.php';
$runtime=json_decode(file_get_contents($link['directory'].'/files-restored/runtime/effective-runtime.json'),true,512,JSON_THROW_ON_ERROR);
$key=$runtime['app_key'];if(str_starts_with($key,'base64:'))$key=base64_decode(substr($key,7),true);
$encrypter=new Illuminate\Encryption\Encrypter($key,$runtime['cipher']);$states=[];
foreach($edits as $edit){$before=json_decode($edit['before_data'],true,512,JSON_THROW_ON_ERROR);$after=json_decode($edit['after_data'],true,512,JSON_THROW_ON_ERROR);$plain=json_decode($encrypter->decryptString($after['snapshot']),true,512,JSON_THROW_ON_ERROR);$old=json_decode($encrypter->decryptString($before['snapshot']),true,512,JSON_THROW_ON_ERROR);$states[]=['before_country'=>$old['incorporation_country_code'],'after_country'=>$plain['country'],'version'=>$after['version']];}
if($states!==[['before_country'=>null,'after_country'=>'PT','version'=>2],['before_country'=>'PT','after_country'=>'MZ','version'=>3]])throw new RuntimeException('Encrypted audit history differs');
$mfaRecovered=0;$originalIds=$backup['original_mfa_user_ids'];foreach($originalIds as $id){$s=$pdo->prepare('SELECT two_factor_secret,two_factor_recovery_codes FROM users WHERE id=:id');$s->execute(['id'=>$id]);$u=$s->fetch(PDO::FETCH_ASSOC);$secret=$encrypter->decrypt($u['two_factor_secret']);if(!is_string($secret)||!preg_match('/^[A-Z2-7]+$/D',$secret))throw new RuntimeException('Original MFA envelope invalid');if($u['two_factor_recovery_codes']!==null)$encrypter->decrypt($u['two_factor_recovery_codes']);$mfaRecovered++;}
$migrations=$pdo->query("SELECT migration FROM migrations WHERE migration IN ('2026_10_09_030000_extend_opportunity_resources','2026_10_10_040000_create_portal_profile_authorization','2026_10_09_190000_prepare_investor_path','2026_10_10_050000_extend_organization_country') ORDER BY migration")->fetchAll(PDO::FETCH_COLUMN);
if($migrations!==['2026_10_10_050000_extend_organization_country'])throw new RuntimeException('Another package installed');
$columns=$pdo->query("SELECT column_name,is_nullable,data_type FROM information_schema.columns WHERE table_name='organizations' AND column_name IN ('incorporation_country_code','incorporation_country_provenance') ORDER BY column_name")->fetchAll(PDO::FETCH_ASSOC);
if(count($columns)!==2||array_column($columns,'is_nullable')!==['YES','YES'])throw new RuntimeException('Columns differ');
$pdo->exec('ROLLBACK');
$proof=['result'=>'passed','at'=>gmdate('c'),'target'=>$identity,'code_hash'=>$backup['code_hash'],'tables'=>count($tables),'new_tables'=>0,'columns'=>$columns,'installation_audits'=>1,'organization_edit_audits'=>2,'encrypted_audit_recovery'=>$states,'master_version'=>3,'master_country'=>'MZ','original_business_rows_preserved'=>true,'synthetic_QA_only_org_membership'=>true,'other_packages_installed'=>false,'original_mfa_envelopes_recovered'=>$mfaRecovered,'active_writes'=>0];
file_put_contents($dir.'/country-https-persistence-20261011.json',json_encode($proof,JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR));echo json_encode($proof,JSON_THROW_ON_ERROR).PHP_EOL;