make(Kernel::class)->bootstrap(); portalQaAssertTarget($target); $connection = DB::connection(); $connection->statement('BEGIN ISOLATION LEVEL REPEATABLE READ READ ONLY'); try { $account = (int) ($argv[1] ?? 18); abort_unless(in_array($account, [18, 21], true), 403); $name = $account === 18 ? 'investor-mfa-qa' : 'promoter-qa21'; $local = json_decode(file_get_contents(storage_path('app/private/investmoz-v2/portal-audit/'.($account === 18 ? 'investor-mfa-qa-private.json' : 'profiles-v1-actors-private.json'))), true, 512, JSON_THROW_ON_ERROR); if ($account === 21) { $local = $local['promoter']; } $actor = User::findOrFail($account); abort_unless($actor->email === $local['email'] && str_ends_with($actor->email, '@example.invalid') && $actor->two_factor_confirmed_at, 403); abort_unless(hash_equals(app('encrypter')->decrypt($actor->two_factor_secret), $local['totp_secret']) && Hash::check($local['password'], $actor->password), 409); $label = 'QA'.$account; $email = htmlspecialchars($actor->email, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); $svg = $actor->twoFactorQrCodeSvg(); $file = storage_path('app/private/investmoz-v2/portal-audit/'.$name.'-2fas-local.html'); $html = ''.$label.' — configuração local 2FAS' .'' .'

Conta '.$label.' no 2FAS Auth

'.$email.' · servidor QA 127.0.0.1:18097

' .'

Este QR recupera a configuração MFA existente. Não altera a conta, o segredo nem a base ativa.

' .$svg.'

No 2FAS: adicionar serviço → ler este QR → identificar a entrada como InvestMoz '.$label.'.

' .'

Ative a data e hora automáticas do telefone. Use o código desta entrada em /two-factor-challenge.

' .'

Ficheiro privado: não o anexe, fotografe ou partilhe nesta conversa. Não remova as entradas antigas do portal.

'; file_put_contents($file, $html); chmod($file, 0600); unset($actor, $svg, $html, $local); } finally { $connection->statement('ROLLBACK'); } echo json_encode(['prepared' => true, 'local_file' => $file, 'account_id' => $account, 'target' => $target, 'mfa_changed' => false, 'database_writes' => 0, 'active_writes' => 0, 'qr_or_secret_exported' => false], JSON_THROW_ON_ERROR);