Files
firefrost-services/services/modpack-version-checker/blueprint-extension/admin/view.blade.php
Claude (Chronicler #83 - The Compiler) b0aa52c2c8 fix(blueprint): Review fixes — API key lookup, tier enforcement, safety
Fixes 10 issues from Blueprint extension code review:
- CurseForge API key now reads via Blueprint dbGet() matching admin save
- PRO-tier fields (webhook, interval) enforced server-side, not just UI
- json_decode results validated before accessing parsed data
- Null user guard on getStatus() endpoint
- 429 response uses consistent error key format
- Modrinth slug derivation strips special chars, documented as fallback
- Check interval dropdown reflects saved value
- API key input changed to password type
- TypeScript error typing narrowed from any to unknown
- Removed unused DB import from ModpackApiService

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 13:53:37 -05:00

217 lines
9.9 KiB
PHP

<form id="config-form" action="" method="POST">
<script>
document.addEventListener("DOMContentLoaded", function() {
showSaveButton();
});
function showSaveButton() {
const configForm = document.getElementById("config-form");
const saveOverlay = document.getElementById("save-overlay");
configForm.addEventListener("change", function() {
saveOverlay.style.display = "inline";
setTimeout(() => {
saveOverlay.style.bottom = "10px";
}, 100);
});
configForm.addEventListener("input", function() {
saveOverlay.style.display = "inline";
setTimeout(() => {
saveOverlay.style.bottom = "10px";
}, 100);
});
}
</script>
<!-- Save button overlay -->
<div id="save-overlay">
{{ csrf_field() }}
<button type="submit" name="_method" value="PATCH" class="btn btn-primary btn-sm">
Save Changes
</button>
</div>
<style>
#save-overlay {
display: none;
position: fixed;
transition: bottom 0.3s;
bottom: -200px;
right: 20px;
z-index: 500;
padding: 15px;
background: #1a1a2e;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}
</style>
<!-- Header -->
<div class="row" style="margin-bottom: 20px;">
<div class="col-xs-12">
<div style="display: flex; align-items: center; gap: 15px;">
<div style="width: 50px; height: 50px; background: linear-gradient(135deg, #FF6B35, #4ECDC4); border-radius: 10px; display: flex; align-items: center; justify-content: center;">
<i class="fa fa-cube" style="font-size: 24px; color: white;"></i>
</div>
<div>
<h2 style="margin: 0; color: #fff;">ModpackChecker</h2>
<p style="margin: 0; color: #888;">4-Platform Modpack Version Monitoring</p>
</div>
</div>
</div>
</div>
<div class="row">
<!-- CurseForge API Key -->
<div class="col-xs-12 col-md-6">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">
<i class="fa fa-key"></i> CurseForge API Key
</h3>
</div>
<div class="box-body">
<div class="form-group">
<label class="control-label">API Key (BYOK)</label>
<input
type="password"
name="curseforge_api_key"
id="curseforge_api_key"
value="{{ $curseforge_api_key }}"
placeholder="$2a$10$..."
class="form-control"
autocomplete="off"
/>
<p class="text-muted small" style="margin-top: 8px;">
Get your free API key from
<a href="https://console.curseforge.com/" target="_blank">console.curseforge.com</a>.
Required for CurseForge modpack detection.
</p>
</div>
</div>
</div>
</div>
<!-- Check Interval (PRO TIER) -->
<div class="col-xs-12 col-md-6">
<div class="box box-info">
<div class="box-header with-border">
<h3 class="box-title">
<i class="fa fa-clock-o"></i> Check Interval
<span class="label label-warning" style="margin-left: 10px;">PRO TIER</span>
</h3>
</div>
<div class="box-body">
<div class="form-group">
<label class="control-label">Automatic Check Frequency</label>
<select class="form-control" name="check_interval" id="check_interval" disabled>
<option value="daily" {{ $check_interval === 'daily' ? 'selected' : '' }}>Daily (24 Hours)</option>
<option value="12h" {{ $check_interval === '12h' ? 'selected' : '' }}>Every 12 Hours</option>
<option value="6h" {{ $check_interval === '6h' ? 'selected' : '' }}>Every 6 Hours</option>
</select>
<p class="text-muted small" style="margin-top: 8px;">
Standard tier is locked to daily cron checks.
Upgrade to Professional for more frequent automated checks.
</p>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<!-- Discord Webhook (PRO TIER) -->
<div class="col-xs-12 col-md-6">
<div class="box box-success">
<div class="box-header with-border">
<h3 class="box-title">
<i class="fa fa-bell"></i> Discord Notifications
<span class="label label-warning" style="margin-left: 10px;">PRO TIER</span>
</h3>
</div>
<div class="box-body">
<div class="form-group">
<label class="control-label">Webhook URL</label>
<input
type="url"
name="discord_webhook_url"
id="discord_webhook_url"
value="{{ $discord_webhook_url }}"
placeholder="https://discord.com/api/webhooks/..."
class="form-control"
disabled
/>
<p class="text-muted small" style="margin-top: 8px;">
Upgrade to Professional to receive automated update alerts in your Discord server.
</p>
</div>
</div>
</div>
</div>
<!-- Supported Platforms -->
<div class="col-xs-12 col-md-6">
<div class="box box-default">
<div class="box-header with-border">
<h3 class="box-title">
<i class="fa fa-check-circle"></i> Supported Platforms
</h3>
</div>
<div class="box-body">
<ul style="list-style: none; padding: 0; margin: 0;">
<li style="padding: 8px 0; border-bottom: 1px solid #333;">
<i class="fa fa-fire" style="color: #f16436; width: 20px;"></i>
<strong>CurseForge</strong>
<span class="text-muted small">(Requires API Key)</span>
</li>
<li style="padding: 8px 0; border-bottom: 1px solid #333;">
<i class="fa fa-leaf" style="color: #1bd96a; width: 20px;"></i>
<strong>Modrinth</strong>
<span class="text-muted small">(No key required)</span>
</li>
<li style="padding: 8px 0; border-bottom: 1px solid #333;">
<i class="fa fa-cogs" style="color: #4a90d9; width: 20px;"></i>
<strong>Technic</strong>
<span class="text-muted small">(No key required)</span>
</li>
<li style="padding: 8px 0;">
<i class="fa fa-cube" style="color: #e04e39; width: 20px;"></i>
<strong>FTB (modpacks.ch)</strong>
<span class="text-muted small">(No key required)</span>
</li>
</ul>
</div>
</div>
</div>
</div>
<!-- Footer Info -->
<div class="row">
<div class="col-xs-12">
<div style="background: #1a1a2e; border-left: 4px solid #4ECDC4; border-radius: 4px; padding: 15px; margin-bottom: 15px;">
<h4 style="margin: 0 0 10px 0; color: #fff;"><i class="fa fa-info-circle" style="color: #4ECDC4;"></i> How It Works</h4>
<p style="margin-bottom: 0; color: #ccc;">
ModpackChecker automatically detects modpacks via Egg Variables or file fingerprinting.
Set <code style="background: #2a2a3e; padding: 2px 6px; border-radius: 3px;">MODPACK_PLATFORM</code> and
<code style="background: #2a2a3e; padding: 2px 6px; border-radius: 3px;">MODPACK_ID</code> in your server's startup variables
for the most reliable detection, or let the extension scan for
<code style="background: #2a2a3e; padding: 2px 6px; border-radius: 3px;">manifest.json</code> /
<code style="background: #2a2a3e; padding: 2px 6px; border-radius: 3px;">modrinth.index.json</code> files.
</p>
</div>
</div>
</div>
<!-- Support -->
<div class="row">
<div class="col-xs-12">
<div style="background: #1a1a2e; border-left: 4px solid #FF6B35; border-radius: 4px; padding: 15px;">
<h4 style="margin: 0 0 10px 0; color: #fff;"><i class="fa fa-life-ring" style="color: #FF6B35;"></i> Need Help?</h4>
<p style="margin-bottom: 0; color: #ccc;">
Join our Discord for support: <a href="https://firefrostgaming.com/discord" target="_blank" style="color: #4ECDC4;">firefrostgaming.com/discord</a>
</p>
</div>
</div>
</div>
</form>