update rm deadcode
This commit is contained in:
@@ -40,7 +40,7 @@ class HostingMail extends Command
|
||||
|
||||
if ($Hosting)
|
||||
{
|
||||
$ServiceExpiry = Carbon::now()->diffInDays(Carbon::parse($Hosting->next_due_date),false);
|
||||
$ServiceExpiry = (int) Carbon::now()->diffInDays(Carbon::parse($Hosting->next_due_date), false);
|
||||
if ($ServiceExpiry <= 5 && $ServiceExpiry >= 0)
|
||||
{
|
||||
$jobs[] = new ExpiryMail($item->id,5,3);
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Http\Facade\SignRSA;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
class ReencryptSecrets extends Command
|
||||
{
|
||||
protected $signature = 'secrets:reencrypt {--dry-run}';
|
||||
|
||||
protected $description = 'Re-encrypt stored secrets with the current APP_KEY and RSA_KEY (old values are read via APP_PREVIOUS_KEYS / RSA_PREVIOUS_*)';
|
||||
|
||||
private const RSA_COLUMNS = [
|
||||
['module_vcenter', 'password'],
|
||||
['infra_management', 'password'],
|
||||
['module_hosting', 'password'],
|
||||
['module_hosting_server', 'password'],
|
||||
['module_dns_server', 'password'],
|
||||
['module_vmware', 'password'],
|
||||
['reinstall_logs', 'password'],
|
||||
];
|
||||
|
||||
private const APP_KEY_COLUMNS = [
|
||||
['dns_manager_servers', 'password'],
|
||||
['module_hosting_plesk_clients', 'password'],
|
||||
['module_vmware', 'plain_password'],
|
||||
['reinstall_logs', 'plain_password'],
|
||||
];
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$failed = 0;
|
||||
|
||||
foreach (self::RSA_COLUMNS as [$table, $column]) {
|
||||
$failed += $this->reencryptColumn($table, $column, fn (string $value) => SignRSA::EncryptFunc($this->decryptRsa($value)));
|
||||
}
|
||||
|
||||
foreach (self::APP_KEY_COLUMNS as [$table, $column]) {
|
||||
$failed += $this->reencryptColumn($table, $column, fn (string $value) => Crypt::encryptString(Crypt::decryptString($value)));
|
||||
}
|
||||
|
||||
$failed += $this->reencryptSmtpSetting();
|
||||
|
||||
return $failed === 0 ? self::SUCCESS : self::FAILURE;
|
||||
}
|
||||
|
||||
private function reencryptColumn(string $table, string $column, callable $reencrypt): int
|
||||
{
|
||||
if (!Schema::hasColumn($table, $column)) {
|
||||
$this->warn("{$table}.{$column}: column not found, skipped");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
$updated = 0;
|
||||
$failed = 0;
|
||||
|
||||
DB::table($table)
|
||||
->select(['id', $column])
|
||||
->whereNotNull($column)
|
||||
->where($column, '!=', '')
|
||||
->chunkById(200, function ($rows) use ($table, $column, $reencrypt, &$updated, &$failed) {
|
||||
foreach ($rows as $row) {
|
||||
try {
|
||||
$value = $reencrypt((string) $row->{$column});
|
||||
} catch (Throwable) {
|
||||
$failed++;
|
||||
$this->warn("{$table}#{$row->id}.{$column}: cannot decrypt with current or previous key");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$this->option('dry-run')) {
|
||||
DB::table($table)->where('id', $row->id)->update([$column => $value]);
|
||||
}
|
||||
$updated++;
|
||||
}
|
||||
});
|
||||
|
||||
$this->info("{$table}.{$column}: {$updated} re-encrypted, {$failed} failed");
|
||||
|
||||
return $failed;
|
||||
}
|
||||
|
||||
private function reencryptSmtpSetting(): int
|
||||
{
|
||||
$setting = DB::table('setting')->where('key', 'smtp')->first();
|
||||
$smtp = $setting ? json_decode((string) $setting->value, true) : null;
|
||||
|
||||
if (empty($smtp['password'])) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
try {
|
||||
$smtp['password'] = SignRSA::EncryptFunc($this->decryptRsa($smtp['password']));
|
||||
} catch (Throwable) {
|
||||
$this->warn('setting[smtp].password: cannot decrypt with current or previous key');
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!$this->option('dry-run')) {
|
||||
DB::table('setting')->where('key', 'smtp')->update(['value' => json_encode($smtp)]);
|
||||
}
|
||||
$this->info('setting[smtp].password: re-encrypted');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function decryptRsa(string $value): string
|
||||
{
|
||||
$plain = SignRSA::DecryptFunc($value);
|
||||
if ($plain === '') {
|
||||
throw new RuntimeException('RSA decrypt failed');
|
||||
}
|
||||
|
||||
return $plain;
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ use App\Repositories\Api\Service\ServiceRepository;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\InvoiceItem;
|
||||
use App\Models\Service;
|
||||
use App\Support\RenewalPricing;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
@@ -230,8 +231,10 @@ class ServiceExpiry extends Command
|
||||
return;
|
||||
}
|
||||
|
||||
$price = $this->renewalPrice($orderItem);
|
||||
$renewalPrice = $this->renewalPrice($orderItem);
|
||||
$months = $orderItem->months ?? 1;
|
||||
$addonTotal = RenewalPricing::addonTotal($service, 1);
|
||||
$price = $renewalPrice + $addonTotal;
|
||||
|
||||
if ($price <= 0) {
|
||||
Log::warning('service:expiry | Cannot create renewal invoice: zero price', ['service_id' => $service->id]);
|
||||
@@ -270,12 +273,16 @@ class ServiceExpiry extends Command
|
||||
'product_id' => $service->product_id,
|
||||
'type' => 'renewal',
|
||||
'description' => 'Gia hạn dịch vụ: ' . ($orderItem->product?->name ?? $service->server_name ?? ''),
|
||||
'months' => $orderItem->months ?? 1,
|
||||
'months' => $months,
|
||||
'quantity' => 1,
|
||||
'unit_price' => $price,
|
||||
'total_price' => $price,
|
||||
'unit_price' => $renewalPrice,
|
||||
'total_price' => $renewalPrice,
|
||||
]);
|
||||
|
||||
foreach (RenewalPricing::addonInvoiceItems($service, 1, $months) as $addonItem) {
|
||||
InvoiceItem::create($addonItem + ['invoice_id' => $invoice->id]);
|
||||
}
|
||||
|
||||
// Update service to point to the new renewal invoice
|
||||
$service->update(['invoice_id' => $invoice->id]);
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ class ServiceHosting extends Command
|
||||
$Hosting = ModuleHosting::with('Server')->where('customer_id',$item->id)->first();
|
||||
if ($Hosting)
|
||||
{
|
||||
$ServiceExpiry = Carbon::now()->diffInDays(Carbon::parse($Hosting->next_due_date),false);
|
||||
$ServiceExpiry = (int) Carbon::now()->diffInDays(Carbon::parse($Hosting->next_due_date), false);
|
||||
if ($ServiceExpiry <= 0)
|
||||
{
|
||||
$jobs[] = new HostingJobs($item->id,'Suspend');
|
||||
|
||||
@@ -42,7 +42,7 @@ class ServiceVPS extends Command
|
||||
{
|
||||
foreach ($allService as $service)
|
||||
{
|
||||
$ServiceExpiry = Carbon::now()->diffInDays(Carbon::parse($service->next_due_date),false);
|
||||
$ServiceExpiry = (int) Carbon::now()->diffInDays(Carbon::parse($service->next_due_date), false);
|
||||
|
||||
if ($ServiceExpiry <= 0)
|
||||
{
|
||||
|
||||
@@ -39,7 +39,7 @@ class VPSMail extends Command
|
||||
$vps = ModuleVmware::where('customer_id',$item->id)->first();
|
||||
if ($vps)
|
||||
{
|
||||
$ServiceExpiry = Carbon::now()->diffInDays(Carbon::parse($vps->next_due_date),false);
|
||||
$ServiceExpiry = (int) Carbon::now()->diffInDays(Carbon::parse($vps->next_due_date), false);
|
||||
if ($ServiceExpiry <= 5 && $ServiceExpiry > 0)
|
||||
{
|
||||
$jobs[] = new ExpiryMail($vps->id,5,4);
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands\Whmcs;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class SyncAllCommand extends Command
|
||||
{
|
||||
protected $signature = 'whmcs:sync-all {--with-domain-sync : Also run domain:sync before whmcs:sync-domains}';
|
||||
|
||||
protected $description = 'Run every whmcs:sync-* command in dependency order (clients, products, orders, order-items, invoices, services, domains)';
|
||||
|
||||
private const STEPS = [
|
||||
['command' => 'whmcs:sync-clients', 'forceSync' => true],
|
||||
['command' => 'whmcs:sync-products', 'forceSync' => false],
|
||||
['command' => 'whmcs:sync-orders', 'forceSync' => true],
|
||||
['command' => 'whmcs:sync-order-items', 'forceSync' => false],
|
||||
['command' => 'whmcs:sync-invoices', 'forceSync' => true],
|
||||
['command' => 'whmcs:sync-services', 'forceSync' => false],
|
||||
['command' => 'whmcs:sync-domains', 'forceSync' => false],
|
||||
];
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
if ($this->option('with-domain-sync')) {
|
||||
$exitCode = $this->runStep('domain:sync', []);
|
||||
if ($exitCode !== self::SUCCESS) {
|
||||
return $exitCode;
|
||||
}
|
||||
} else {
|
||||
$this->warn('Skipping domain:sync — whmcs:sync-domains expects it to already be up to date. Pass --with-domain-sync to run it here.');
|
||||
}
|
||||
|
||||
foreach (self::STEPS as $step) {
|
||||
$arguments = $step['forceSync'] ? ['--sync' => true] : [];
|
||||
$exitCode = $this->runStep($step['command'], $arguments);
|
||||
|
||||
if ($exitCode !== self::SUCCESS) {
|
||||
return $exitCode;
|
||||
}
|
||||
}
|
||||
|
||||
$this->info('whmcs:sync-all completed successfully.');
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
private function runStep(string $command, array $arguments): int
|
||||
{
|
||||
$this->newLine();
|
||||
$this->info("==> {$command}");
|
||||
|
||||
$exitCode = $this->call($command, $arguments);
|
||||
|
||||
if ($exitCode !== self::SUCCESS) {
|
||||
$this->error("{$command} failed with exit code {$exitCode}; stopping.");
|
||||
}
|
||||
|
||||
return $exitCode;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user