Save workspace changes
This commit is contained in:
86
app/Console/Commands/ExportLegacyPasswordsCommand.php
Normal file
86
app/Console/Commands/ExportLegacyPasswordsCommand.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class ExportLegacyPasswordsCommand extends Command
|
||||
{
|
||||
protected $signature = 'skinbase:export-legacy-passwords
|
||||
{--sql= : Path to write SQL update script (optional)}
|
||||
{--chunk=500 : Chunk size for processing}';
|
||||
|
||||
protected $description = 'Export legacy password hashes from legacy DB into a SQL file to update the new users table.';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$sqlPath = $this->option('sql') ?? base_path('scripts/legacy-passwords-export.sql');
|
||||
$chunk = (int) $this->option('chunk');
|
||||
|
||||
try {
|
||||
DB::connection('legacy')->getPdo();
|
||||
} catch (\Throwable $e) {
|
||||
$this->error('Legacy DB connection is not available: ' . $e->getMessage());
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$now = now()->format('Y-m-d H:i:s');
|
||||
|
||||
$lines = [];
|
||||
$lines[] = '-- Legacy password export';
|
||||
$lines[] = '-- Generated: ' . $now;
|
||||
$lines[] = '-- Source: legacy DB (read-only)';
|
||||
$lines[] = '';
|
||||
$lines[] = 'SET NAMES utf8mb4;';
|
||||
$lines[] = 'USE `' . DB::getDatabaseName() . '`;';
|
||||
$lines[] = 'START TRANSACTION;';
|
||||
$lines[] = '';
|
||||
|
||||
$exported = 0;
|
||||
|
||||
DB::connection('legacy')
|
||||
->table('users')
|
||||
->select(['user_id', 'password2', 'password'])
|
||||
->orderBy('user_id')
|
||||
->chunk($chunk, function ($rows) use (&$lines, &$exported, $now) {
|
||||
foreach ($rows as $r) {
|
||||
$id = (int) ($r->user_id ?? 0);
|
||||
$hash = trim((string) ($r->password2 ?: $r->password ?: ''));
|
||||
if ($id === 0 || $hash === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$algo = 'unknown';
|
||||
if (preg_match('/^\$2[aby]\$/', $hash)) {
|
||||
$algo = 'bcrypt';
|
||||
} elseif (preg_match('/^\$argon2/', $hash)) {
|
||||
$algo = 'argon2';
|
||||
}
|
||||
|
||||
$escaped = str_replace(['\\', "'"], ['\\\\', "\\'"], $hash);
|
||||
|
||||
$lines[] = "-- user_id={$id} legacy_algo={$algo}";
|
||||
$lines[] = "SAVEPOINT sp_{$id};";
|
||||
$lines[] = "UPDATE `users` SET `password` = '{$escaped}', `legacy_password_algo` = '{$algo}', `needs_password_reset` = 1, `updated_at` = '{$now}' WHERE `id` = {$id};";
|
||||
$lines[] = '';
|
||||
|
||||
$exported++;
|
||||
}
|
||||
});
|
||||
|
||||
$lines[] = 'COMMIT;';
|
||||
$lines[] = '';
|
||||
$lines[] = "-- Exported: {$exported} user(s)";
|
||||
|
||||
$sql = implode("\n", $lines) . "\n";
|
||||
|
||||
if (file_put_contents($sqlPath, $sql) === false) {
|
||||
$this->error('Could not write SQL file: ' . $sqlPath);
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$this->info('Wrote ' . $exported . ' rows to: ' . $sqlPath);
|
||||
return self::SUCCESS;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user