getFile()).':'.$e->getLine().PHP_EOL); exit(1); }); $root=dirname(__DIR__);$private=$root.'/storage/app/private/investmoz-v2/portal-audit'; require $root.'/vendor/autoload.php'; $app=require $root.'/bootstrap/app.php'; (new Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables)->bootstrap($app); (new Illuminate\Foundation\Bootstrap\LoadConfiguration)->bootstrap($app); $c=config('database.connections.'.config('database.default')); throw_unless($c['driver']==='pgsql' && empty($c['url']) && $c['database']==='investemoz' && (int)$c['port']===5432 && in_array($c['host'],['127.0.0.1','localhost'],true),RuntimeException::class,'Unexpected active target'); $pdo=new PDO('pgsql:host='.$c['host'].';port=5432;dbname=investemoz',$c['username'],$c['password'],[PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION]); $pdo->exec('BEGIN 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); throw_unless((int)$identity['port']===5432 && $identity['read_only']==='on',RuntimeException::class); $counts=[];foreach(['users','portal_role_assignments','organizations','memberships','jobs','failed_jobs'] as $table){$counts[$table]=(int)$pdo->query('SELECT count(*) FROM "'.$table.'"')->fetchColumn();} $designations=[]; if (($argv[1]??'inspect')==='designations') { $lookup=$pdo->prepare('SELECT id, name, email, email_verified_at IS NOT NULL AS contact_verified, two_factor_confirmed_at IS NOT NULL AND two_factor_secret IS NOT NULL AS MFA_configured FROM users WHERE lower(email)=lower(:email)'); foreach ([ ['Aurora Chachuaio','Aurora.chachuaio@tempo.co.mz','promoter','Tempo'], ['Palmira Uamusse','Palmira.matsinhe@tempo.co.mz','validator','all_organizations'], ['Mario Melembe','mario.melembe@tempo.co.mz','publisher','all_organizations'], ] as [$name,$email,$role,$scope]) { $lookup->execute(['email'=>$email]); $designations[]=['designated_name'=>$name,'email'=>$email,'role'=>$role,'scope'=>$scope,'existing_accounts'=>$lookup->fetchAll(PDO::FETCH_ASSOC), 'categories'=>['investment_project','real_estate','land_rights','business_sale','business_partnership','franchise']]; } } $pdo->exec('ROLLBACK'); $mailer=config('mail.default');$mail=config('mail.mailers.'.$mailer,[]); $mailUrl=$mail['url']??null;$host=$mailUrl?parse_url($mailUrl,PHP_URL_HOST):($mail['host']??null); $port=(int)($mailUrl?(parse_url($mailUrl,PHP_URL_PORT)?:($mail['port']??2525)):($mail['port']??2525)); $local=in_array($host,['127.0.0.1','localhost','::1'],true);$listening=null;$smtpGreeting=null; // Local SMTP readiness, not delivery. No AUTH, recipient, message or secret is sent. if(($mail['transport']??null)==='smtp' && $local){ $errno=0;$error='';$socket=@stream_socket_client('tcp://'.$host.':'.$port,$errno,$error,3); $listening=is_resource($socket); if($listening){stream_set_timeout($socket,3);$line=fgets($socket,512);$smtpGreeting=is_string($line)&&str_starts_with($line,'220');fclose($socket);} } $proof=['at'=>gmdate('c'),'target'=>$identity,'providers_booted'=>false,'active_writes'=>0,'emails_sent'=>0, 'registration_enabled'=>in_array('registration',config('fortify.features',[]),true), 'email_verification_enabled'=>in_array('email-verification',config('fortify.features',[]),true), 'MFA_enabled'=>in_array('two-factor-authentication',config('fortify.features',[]),true), 'workflow_flags'=>['profiles'=>(bool)config('portal.profile_access_enabled'),'dashboard'=>(bool)config('portal.opportunity_dashboard_access_enabled'),'specialized_drafts'=>(bool)config('portal.opportunity_specialized_drafts_enabled')], 'COUNTRY02_enabled'=>(bool)config('portal.organization_country_enabled'),'counts'=>$counts, 'mail'=>['mailer'=>$mailer,'transport'=>$mail['transport']??null,'endpoint_is_loopback'=>$local,'port'=>$port, 'local_TCP_available'=>$listening,'SMTP_greeting_220'=>$smtpGreeting,'credentials_configured'=>!empty($mail['username'])&&!empty($mail['password']), 'from_is_default_example'=>in_array(config('mail.from.address'),['hello@example.com',null,''],true),'real_contact_delivery_demonstrated'=>false], 'registration_depends_on_workflow_flag'=>false]; if ($designations!==[]) {$proof['designations']=$designations;} if (($argv[1]??'inspect')==='smtp-check') { // Open/authenticate the configured TLS transport; never send MAIL FROM, RCPT or DATA. $proof['mail']['transport_test_attempted']=false; if (($mail['transport']??null)==='smtp' && is_string($host) && $host!=='') { $proof['mail']['transport_test_attempted']=true; $transport=null; try { $transport=new Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport($host,$port,($mail['scheme']??null)==='smtps'?true:null); $transport->getStream()->setTimeout(5); $transport->setRequireTls(true); $transport->setUsername((string)($mailUrl?rawurldecode(parse_url($mailUrl,PHP_URL_USER)??''):($mail['username']??''))); $transport->setPassword((string)($mailUrl?rawurldecode(parse_url($mailUrl,PHP_URL_PASS)??''):($mail['password']??''))); $transport->start(); $proof['mail']['TLS_required_handshake_completed']=true; $proof['mail']['TLS_mode']=$transport->getStream()->isTLS()?'implicit':'STARTTLS'; $proof['mail']['SMTP_AUTH_235']=preg_match('/\b235[ -]/',$transport->getStream()->getDebug())===1; $transport->stop(); } catch (Throwable $e) { $proof['mail']['TLS_required_handshake_completed']=false; $proof['mail']['transport_error_type']=$e::class; // Deliberately omit the message, debug transcript and exception arguments. } } } if(($argv[1]??'inspect')==='prepare-tests'){ $name='onboarding_20261011_'.gmdate('His').'_test'; throw_unless(preg_match('/^onboarding_20261011_\d{6}_test$/D',$name),RuntimeException::class); $qa=new PDO('pgsql:host=127.0.0.1;port=55441;dbname=postgres','postgres','',[PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION]); throw_unless((int)$qa->query('SELECT inet_server_port()')->fetchColumn()===55441,RuntimeException::class,'QA isolation required'); $qa->exec('CREATE DATABASE "'.$name.'" OWNER investmoz_test'); $proof['isolated_test_database']=['database'=>$name,'host'=>'127.0.0.1','port'=>55441,'role'=>'investmoz_test','created_empty'=>true]; $xml=file_get_contents($root.'/phpunit.xml'); $xml=str_replace('','',$xml); $xml=str_replace('','',$xml); $xml=str_replace('','',$xml); foreach(['DB_CONNECTION','DB_HOST','DB_PORT','DB_USERNAME','DB_PASSWORD','DB_URL','MAIL_MAILER','QUEUE_CONNECTION','SESSION_DRIVER'] as $environment){ $xml=preg_replace('/(/','$1 force="true"/>',$xml); } $prefix=str_replace('\\','/',$root).'/'; $xml=str_replace('bootstrap="vendor/autoload.php"','bootstrap="'.$prefix.'vendor/autoload.php"',$xml); $xml=str_replace('tests/',''.$prefix.'tests/',$xml); $xml=str_replace('app',''.$prefix.'app',$xml); file_put_contents($private.'/onboarding-qa-phpunit.xml',$xml); } $report=match($argv[1]??'inspect') {'designations'=>'onboarding-designations-readonly.json','smtp-check'=>'onboarding-smtp-preflight.json',default=>'onboarding-readiness.json'}; file_put_contents($private.'/'.$report,json_encode($proof,JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR)); echo json_encode($proof,JSON_THROW_ON_ERROR).PHP_EOL;