Low priority fixes: debug comments, Fortify cleanup, badge cost setting, profile query merge, User model fixes, VPN constructor cleanup, PayPal POST, PII removal, Dutch→English translations, duplicate rank check, CHANGELOG

This commit is contained in:
root
2026-06-04 19:57:01 +02:00
parent 66cbd46f37
commit 4b6872e5e0
13 changed files with 82 additions and 61 deletions
+37
View File
@@ -0,0 +1,37 @@
# Changelog
## V3 — 2026-06-04
### Added
- Commandocentrum with Nitro V3 one-click updater
- Configurable paths (9 settings) stored in DB via HK UI
- Emulator start/stop/restart from admin panel
- Live monitoring (online users, DB status, server load)
- Hotel alert system
- Emulator logs viewer
- Clothing sync from FigureMap
- Social login (Google, Discord, GitHub)
- Staff activity log
- Notification settings (email & Discord)
- PHP 8.5 + Ubuntu 26.04 support
- Dual .env system (Linux + Windows)
- Bulletproof 12-step installation guide
### Changed
- Complete README rewrite with badges, tables, quick start
- All Dutch comments translated to English
- XAMPP support removed (security warning added)
- `.env.example``.env.install` with step-by-step guide
- `.env.standard``.env.example.linux` + `.env.example.windows`
### Fixed
- Removed debug comments from config/app.php
- Removed commented Fortify features
- Badge cost now configurable via `setting('badge_cost', 150)`
- ProfileController: merged 2 setting queries into 1
- User model: removed `save()` override that broke Eloquent expectations
- User model: removed `id` from `$hidden` (was inconsistent with API exposure)
- VPNCheckerMiddleware: removed empty constructor argument
- PayPal process route: GET → POST
- Discord webhook: no longer sends PII (email/IP)
- API purchase: added rank duplicate check
+1 -3
View File
@@ -171,13 +171,11 @@ class CreateNewUser implements CreatesNewUsers
try {
Http::asJson()->post(is_string($discordWebhookUrl) ? $discordWebhookUrl : '', [
'username' => sprintf('%s Bot', is_string($hotelNameSetting) ? $hotelNameSetting : 'Hotel'),
'content' => "User: {$username} has just registered, with the IP: {$ip} and E-mail: {$email}",
'content' => "User: {$username} has just registered.",
]);
} catch (\Exception $e) {
Log::error('Failed to send Discord webhook notification', [
'username' => $username,
'ip' => $ip,
'email' => $email,
'error' => $e->getMessage(),
]);
}
@@ -317,6 +317,10 @@ class HotelApiController extends Controller
$user = $request->user();
if ($package->give_rank && $user->rank >= $package->give_rank) {
return response()->json(['error' => 'You already have this or a higher rank'], 400);
}
$cost = $package->costs;
if ($user->credits < $cost) {
@@ -12,7 +12,7 @@ class BadgeController extends Controller
{
public function show(): View
{
$cost = 150;
$cost = (int) setting('badge_cost', 150);
$currencyType = 'credits';
$folderError = false;
$errorMessage = '';
@@ -60,7 +60,7 @@ class BadgeController extends Controller
return redirect()->route('login')->with('error', 'You must be logged in to purchase badges.');
}
$cost = 150;
$cost = (int) setting('badge_cost', 150);
if (property_exists($user, 'credits') && $user->credits !== null && $user->credits < $cost) {
return redirect()->back()->with('error', 'You don\'t have enough credits to purchase a badge.');
@@ -20,8 +20,10 @@ class ProfileController extends Controller
'badges',
]);
$showStats = (bool) (WebsiteSetting::where('key', 'profile_show_stats')->first()?->value ?? '1');
$showOnline = (bool) (WebsiteSetting::where('key', 'profile_show_online_status')->first()?->value ?? '1');
$settings = WebsiteSetting::whereIn('key', ['profile_show_stats', 'profile_show_online_status'])
->pluck('value', 'key');
$showStats = (bool) ($settings['profile_show_stats'] ?? '1');
$showOnline = (bool) ($settings['profile_show_online_status'] ?? '1');
return view('user.profile', [
'user' => $user,
+4 -4
View File
@@ -17,7 +17,7 @@ class RadioApiKey
if (empty($key)) {
return response()->json([
'error' => 'API key is verplicht. Gebruik Authorization: Bearer <key> of ?api_key=<key>',
'error' => 'API key is required. Use Authorization: Bearer <key> or ?api_key=<key>',
], 401);
}
@@ -25,19 +25,19 @@ class RadioApiKey
if (! $apiKey) {
return response()->json([
'error' => 'API key is ongeldig of verlopen',
'error' => 'API key is invalid or expired',
], 401);
}
if (! $apiKey->isAllowedIp($request->ip())) {
return response()->json([
'error' => 'IP-adres niet toegestaan voor deze API key',
'error' => 'IP address not allowed for this API key',
], 403);
}
if (! $apiKey->hasPermission($permission)) {
return response()->json([
'error' => 'Geen toestemming voor deze actie',
'error' => 'No permission for this action',
], 403);
}
+1 -1
View File
@@ -34,7 +34,7 @@ class VPNCheckerMiddleware
return $this->denyAccess($request);
}
$ipService = new IpLookupService('');
$ipService = new IpLookupService;
$countryInfo = $ipService->getCountryInfo($userIp);
+1 -14
View File
@@ -128,7 +128,7 @@ class User extends Authenticatable implements FilamentUser, HasName
protected $fillable = ['username', 'mail', 'password', 'account_created', 'last_login', 'motto', 'look', 'credits', 'last_username_change', 'auth_ticket', 'home_room', 'ip_register', 'ip_current', 'referral_code', 'preferences', 'team_id', 'avatar_background', 'home_background', 'pincode', 'secret_key', 'extra_rank', 'is_hidden', 'background_id', 'background_stand_id', 'background_overlay_id', 'radio_points', 'pixels', 'points', 'online', 'gender', 'rank', 'mail_verified', 'two_factor_secret', 'two_factor_recovery_codes', 'two_factor_confirmed_at'];
#[\Override]
protected $hidden = ['id', 'password', 'remember_token'];
protected $hidden = ['password', 'remember_token'];
/**
* @return array<string, string>
@@ -394,19 +394,6 @@ class User extends Authenticatable implements FilamentUser, HasName
->logOnlyDirty();
}
/**
* @param array<string, mixed> $options
*/
#[\Override]
public function save(array $options = []): bool
{
if (! $this->isDirty()) {
return false;
}
return parent::save($options);
}
public function hasAppliedForTeam(int $teamId): bool
{
if ($teamId === 0) {
+1 -3
View File
@@ -2,7 +2,6 @@
declare(strict_types=1);
// Auto-push test
use App\Providers\AppServiceProvider;
use App\Providers\EventServiceProvider;
use App\Providers\Filament\AdminFilamentPanelProvider;
@@ -247,5 +246,4 @@ return [
// 'ExampleClass' => App\Example\ExampleClass::class,
])->toArray(),
];
// test
]
-5
View File
@@ -147,14 +147,9 @@ return [
'features' => [
Features::registration(),
// Features::resetPasswords(),
// Features::emailVerification(),
// Features::updateProfileInformation(),
// Features::updatePasswords(),
Features::twoFactorAuthentication([
'confirm' => true,
'confirmPassword' => true,
// 'window' => 0,
]),
],
+13 -13
View File
@@ -1,4 +1,4 @@
# Uitgebreide PHP locatie detector voor IIS web.config
# Extended PHP location detector for IIS web.config
$searchPaths = @(
"C:\PHP",
@@ -19,11 +19,11 @@ $searchPaths = @(
$phpPath = $null
# Methode 1: Check of php-cgi.exe in PATH staat
Write-Host "Zoeken naar php-cgi.exe..." -ForegroundColor Cyan
# Method 1: Check if php-cgi.exe is in PATH
Write-Host "Searching for php-cgi.exe..." -ForegroundColor Cyan
$phpPath = (Get-Command php-cgi.exe -ErrorAction SilentlyContinue).Source
# Methode 2: Zoek in standaard locaties
# Method 2: Search in default locations
if (-not $phpPath) {
foreach ($basePath in $searchPaths) {
if (Test-Path $basePath) {
@@ -37,9 +37,9 @@ if (-not $phpPath) {
}
}
# Methode 3: Zoek in alle C: schijf (alleen top-level folders voor snelheid)
# Method 3: Search entire C: drive (top-level folders only for speed)
if (-not $phpPath) {
Write-Host "Zoeken in C:\ schijf..." -ForegroundColor Yellow
Write-Host "Searching C:\ drive..." -ForegroundColor Yellow
$rootFolders = Get-ChildItem -Path "C:\" -Directory -ErrorAction SilentlyContinue |
Where-Object { $_.Name -match 'php|wamp|laragon|inetpub' }
foreach ($folder in $rootFolders) {
@@ -52,7 +52,7 @@ if (-not $phpPath) {
}
}
# Methode 4: Check Windows Registry voor PHP installaties
# Method 4: Check Windows Registry for PHP installations
if (-not $phpPath) {
$regPaths = @(
"HKLM:\SOFTWARE\PHP",
@@ -73,7 +73,7 @@ if (-not $phpPath) {
}
if ($phpPath) {
Write-Host "`nGevonden: $phpPath" -ForegroundColor Green
Write-Host "`nFound: $phpPath" -ForegroundColor Green
$webConfigPath = ".\web.config"
if (Test-Path $webConfigPath) {
@@ -82,14 +82,14 @@ if ($phpPath) {
if ($content -ne $newContent) {
$newContent | Set-Content $webConfigPath -NoNewline
Write-Host "Handler succesvol geupdate in web.config!" -ForegroundColor Green
Write-Host "Handler successfully updated in web.config!" -ForegroundColor Green
} else {
Write-Host "Handler was al correct ingesteld." -ForegroundColor Yellow
Write-Host "Handler was already set correctly." -ForegroundColor Yellow
}
} else {
Write-Host "web.config niet gevonden in huidige directory!" -ForegroundColor Red
Write-Host "web.config not found in current directory!" -ForegroundColor Red
}
} else {
Write-Host "`nKon php-cgi.exe niet vinden." -ForegroundColor Red
Write-Host "Controleer of PHP correct is geinstalleerd." -ForegroundColor Red
Write-Host "`nCould not find php-cgi.exe." -ForegroundColor Red
Write-Host "Check if PHP is installed correctly." -ForegroundColor Red
}
+1 -1
View File
@@ -14,7 +14,7 @@ Route::prefix('shop')->group(function () {
// PayPal routes
Route::controller(PayPalController::class)->prefix('paypal')->group(function () {
Route::get('/process-transaction', 'process')->name('paypal.process-transaction');
Route::post('/process-transaction', 'process')->name('paypal.process-transaction');
Route::get('/successful-transaction', 'successful')->name('paypal.successful-transaction');
Route::get('/cancelled-transaction', 'cancelled')->name('paypal.cancelled-transaction');
});
+13 -13
View File
@@ -3,7 +3,7 @@
# Exit immediately if a command exits with a non-zero status
set -e
# --- CONFIGURATION (overschrijfbaar via omgevingsvariabelen) ---
# --- CONFIGURATION (overridable via environment variables) ---
DB_NAME="${NITRO_DB_NAME:-habbo}"
DB_HOST="${NITRO_DB_HOST:-127.0.0.1}"
DB_PORT="${NITRO_DB_PORT:-3306}"
@@ -44,7 +44,7 @@ echo "--> Checking for new SQL files..."
if [ -d "$SQL_DIR" ]; then
find "$SQL_DIR" -name "*.sql" -mmin -10 -print0 | while IFS= read -r -d '' sql_file; do
echo "--> Importing new SQL file: $(basename "$sql_file")"
mariadb $MYSQL_CRED --force "$DB_NAME" < "$sql_file" || echo "--> Opmerking: Sommige SQL-regels overgeslagen (bestonden waarschijnlijk al)."
mariadb $MYSQL_CRED --force "$DB_NAME" < "$sql_file" || echo "--> Note: Some SQL rules skipped (probably already exist)."
done
else
echo "--> SQL directory not found, skipping SQL import."
@@ -156,25 +156,25 @@ fi
# ----------------------------------------
echo "--> Starting automated cleanup..."
# 1. Verwijder emulator logs ouder dan 14 dagen
# 1. Remove emulator logs older than 14 days
echo "--> Removing emulator logs older than 14 days..."
find "$EMULATOR_DIR/" -name "*.log" -mtime +14 -exec rm -f {} \;
# 2. Hou maximaal de 5 nieuwste database backups, gooi oudere weg
# 2. Keep max 5 newest database backups, delete older ones
echo "--> Managing update backups (keeping max 5)..."
if [ -d "$BACKUP_DIR" ]; then
# Zoekt alle .sql bestanden in de backup map, sorteert op datum (nieuwste eerst),
# slaat de eerste 5 over (tail -n +6) en verwijdert de rest.
# Find all .sql files in backup dir, sort by date (newest first),
# skip the first 5 (tail -n +6) and delete the rest.
ls -t "$BACKUP_DIR"/*.sql 2>/dev/null | tail -n +6 | xargs -r rm -f || true
fi
# 3. Clean Yarn cache om SSD ruimte te besparen
# 3. Clean Yarn cache to save SSD space
echo "--> Cleaning Yarn cache..."
yarn cache clean
# ----------------------------------------
# 6. Fix Permissions (www-data) — alleen als sudo beschikbaar is
# 6. Fix Permissions (www-data) — only if sudo is available
# ----------------------------------------
if command -v sudo &> /dev/null; then
echo "--> Setting permissions to www-data:www-data..."
@@ -183,7 +183,7 @@ if command -v sudo &> /dev/null; then
sudo chown -R www-data:www-data "$EMULATOR_DIR" 2>/dev/null || echo "--> chown voor EMULATOR_DIR overgeslagen"
sudo chown -R www-data:www-data "$GAMEDATA_CONF_DIR" 2>/dev/null || echo "--> chown voor GAMEDATA_CONF_DIR overgeslagen"
else
echo "--> Sudo niet beschikbaar, overslaan van chown."
echo "--> Sudo not available, skipping chown."
fi
@@ -193,14 +193,14 @@ fi
if systemctl list-units --type=service --all | grep -q "$EMULATOR_SERVICE.service"; then
echo "--> Restarting $EMULATOR_SERVICE service..."
if command -v sudo &> /dev/null; then
sudo systemctl restart $EMULATOR_SERVICE 2>/dev/null || echo "--> Service restart via sudo mislukt (mogelijk geen sudo rechten)"
sudo systemctl restart $EMULATOR_SERVICE 2>/dev/null || echo "--> Service restart via sudo failed (possible insufficient sudo rights)"
sudo systemctl status $EMULATOR_SERVICE --no-pager -n 5 2>/dev/null || true
else
echo "--> Sudo niet beschikbaar. Herstart de service handmatig: sudo systemctl restart $EMULATOR_SERVICE"
echo "--> Sudo not available. Restart the service manually: sudo systemctl restart $EMULATOR_SERVICE"
fi
else
echo "--> Waarschuwing: Service '$EMULATOR_SERVICE' niet gevonden in systemd."
echo "--> Als je PM2 gebruikt, herstart je processen dan handmatig met: pm2 restart all"
echo "--> Warning: Service '$EMULATOR_SERVICE' not found in systemd."
echo "--> If you use PM2, restart your processes manually: pm2 restart all"
fi
echo "=== Update successfully completed! ==="