mirror of
https://github.com/tiennm99/coolify.git
synced 2026-10-19 00:15:01 +00:00
feat: harden auth flows and server mobile navigation
Add normalized email identity rate limiting for registration and forgot-password requests, and refresh Sentinel status from restart broadcasts. Rework server sidebars and navbar for mobile menus and active status visibility.
This commit is contained in:
1 parent
94079c90f2
commit
b0f0f7d8d0
42 files changed
+1064
-128
No files matched your search
@@ -3,7 +3,7 @@
|
||||
{{ data_get_str($server, 'name')->limit(10) }} > Advanced | Coolify
|
||||
</x-slot>
|
||||
<livewire:server.navbar :server="$server" />
|
||||
<div x-data="{ activeTab: window.location.hash ? window.location.hash.substring(1) : 'general' }" class="flex flex-col h-full gap-8 sm:flex-row">
|
||||
<div x-data="{ activeTab: window.location.hash ? window.location.hash.substring(1) : 'general' }" class="flex flex-col h-full gap-2 md:gap-8 md:flex-row">
|
||||
<x-server.sidebar :server="$server" activeMenu="advanced" />
|
||||
<form wire:submit='submit' class="w-full">
|
||||
<div>
|
||||
@@ -37,7 +37,7 @@
|
||||
helper="You can specify the number of simultaneous build processes/deployments that should run concurrently." />
|
||||
<x-forms.input canGate="update" :canResource="$server" id="dynamicTimeout"
|
||||
type="number" min="1"
|
||||
label="Deployment timeout (seconds)" required
|
||||
label="Deployment timeout (sec)" required
|
||||
helper="You can define the maximum duration for a deployment to run before timing it out." />
|
||||
<x-forms.input canGate="update" :canResource="$server" id="deploymentQueueLimit"
|
||||
type="number" min="1"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{{ data_get_str($server, 'name')->limit(10) }} > CA Certificate | Coolify
|
||||
</x-slot>
|
||||
<livewire:server.navbar :server="$server" />
|
||||
<div class="flex flex-col h-full gap-8 sm:flex-row">
|
||||
<div class="flex flex-col h-full gap-2 md:gap-8 md:flex-row">
|
||||
<x-server.sidebar :server="$server" activeMenu="ca-certificate" />
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex items-center gap-2">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{{ data_get_str($server, 'name')->limit(10) }} > Metrics | Coolify
|
||||
</x-slot>
|
||||
<livewire:server.navbar :server="$server" />
|
||||
<div class="flex flex-col h-full gap-8 sm:flex-row">
|
||||
<div class="flex flex-col h-full gap-2 md:gap-8 md:flex-row">
|
||||
<x-server.sidebar :server="$server" activeMenu="metrics" />
|
||||
<div class="w-full">
|
||||
<div class="flex items-center gap-2">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{{ data_get_str($server, 'name')->limit(10) }} > Hetzner Token | Coolify
|
||||
</x-slot>
|
||||
<livewire:server.navbar :server="$server" />
|
||||
<div class="flex flex-col h-full gap-8 sm:flex-row">
|
||||
<div class="flex flex-col h-full gap-2 md:gap-8 md:flex-row">
|
||||
<x-server.sidebar :server="$server" activeMenu="cloud-provider-token" />
|
||||
<div class="w-full">
|
||||
@if ($server->hetzner_server_id)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{{ data_get_str($server, 'name')->limit(10) }} > Cloudflare Tunnel | Coolify
|
||||
</x-slot>
|
||||
<livewire:server.navbar :server="$server" />
|
||||
<div class="flex flex-col h-full gap-8 sm:flex-row">
|
||||
<div class="flex flex-col h-full gap-2 md:gap-8 md:flex-row">
|
||||
<x-server.sidebar :server="$server" activeMenu="cloudflare-tunnel" />
|
||||
<div class="w-full">
|
||||
<div class="flex flex-col">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{{ data_get_str($server, 'name')->limit(10) }} > Delete Server | Coolify
|
||||
</x-slot>
|
||||
<livewire:server.navbar :server="$server" />
|
||||
<div class="flex flex-col h-full gap-8 sm:flex-row">
|
||||
<div class="flex flex-col h-full gap-2 md:gap-8 md:flex-row">
|
||||
<x-server.sidebar :server="$server" activeMenu="danger" />
|
||||
<div class="w-full">
|
||||
@if ($server->id !== 0)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{{ data_get_str($server, 'name')->limit(10) }} > Destinations | Coolify
|
||||
</x-slot>
|
||||
<livewire:server.navbar :server="$server" />
|
||||
<div class="flex flex-col h-full gap-8 sm:flex-row">
|
||||
<div class="flex flex-col h-full gap-2 md:gap-8 md:flex-row">
|
||||
<x-server.sidebar :server="$server" activeMenu="destinations" />
|
||||
<div class="w-full">
|
||||
@if ($server->isFunctional())
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{{ data_get_str($server, 'name')->limit(10) }} > Docker Cleanup | Coolify
|
||||
</x-slot>
|
||||
<livewire:server.navbar :server="$server" />
|
||||
<div x-data="{ activeTab: window.location.hash ? window.location.hash.substring(1) : 'general' }" class="flex flex-col h-full gap-8 sm:flex-row">
|
||||
<div x-data="{ activeTab: window.location.hash ? window.location.hash.substring(1) : 'general' }" class="flex flex-col h-full gap-2 md:gap-8 md:flex-row">
|
||||
<x-server.sidebar :server="$server" activeMenu="docker-cleanup" />
|
||||
<div class="w-full">
|
||||
<form wire:submit='submit'>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{{ data_get_str($server, 'name')->limit(10) }} > Log Drains | Coolify
|
||||
</x-slot>
|
||||
<livewire:server.navbar :server="$server" />
|
||||
<div class="flex flex-col h-full gap-8 sm:flex-row">
|
||||
<div class="flex flex-col h-full gap-2 md:gap-8 md:flex-row">
|
||||
<x-server.sidebar :server="$server" activeMenu="log-drains" />
|
||||
<div class="w-full">
|
||||
@if ($server->isFunctional())
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div class="pb-6">
|
||||
<div class="pb-0 md:pb-6">
|
||||
<x-slide-over @startproxy.window="slideOverOpen = true" fullScreen closeWithX>
|
||||
<x-slot:title>Proxy Startup Logs</x-slot:title>
|
||||
<x-slot:content>
|
||||
@@ -12,14 +12,17 @@
|
||||
<livewire:activity-monitor header="Logs" fullHeight />
|
||||
</x-slot:content>
|
||||
</x-slide-over>
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<h1>Server</h1>
|
||||
<h1>Server</h1>
|
||||
<div class="pt-2 pb-4 md:pb-10">
|
||||
<div class="flex-col md:flex-row flex gap-2">
|
||||
<div data-testid="server-subtitle" class="text-xs lg:text-sm min-w-0 truncate">
|
||||
{{ data_get($server, 'name') }}
|
||||
</div>
|
||||
@php
|
||||
$showSentinelStatus = $server->isFunctional() && $server->isSentinelEnabled();
|
||||
@endphp
|
||||
@if ($server->proxySet() || $showSentinelStatus)
|
||||
<div data-testid="server-status-summary" class="flex flex-wrap items-center gap-2">
|
||||
<div data-testid="server-status-summary" class="flex flex-wrap items-center gap-1">
|
||||
@if ($server->proxySet())
|
||||
<div class="flex items-center gap-1">
|
||||
@if ($proxyStatus === 'running')
|
||||
@@ -57,11 +60,10 @@
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="subtitle">{{ data_get($server, 'name') }}</div>
|
||||
</div>
|
||||
<div class="navbar-main">
|
||||
<nav
|
||||
class="flex items-center gap-6 overflow-x-scroll sm:overflow-x-hidden scrollbar min-h-10 whitespace-nowrap pt-2">
|
||||
class="scrollbar hidden min-h-10 w-full flex-nowrap items-center gap-6 overflow-x-scroll overflow-y-hidden pb-1 whitespace-nowrap md:flex md:w-auto md:overflow-visible">
|
||||
<a class="{{ request()->routeIs('server.show') ? 'dark:text-white' : '' }}" href="{{ route('server.show', [
|
||||
'server_uuid' => data_get($server, 'uuid'),
|
||||
]) }}" {{ wireNavigate() }}>
|
||||
@@ -114,12 +116,70 @@
|
||||
</a>
|
||||
@endcan
|
||||
</nav>
|
||||
<div class="order-first sm:order-last">
|
||||
<div class="order-first w-full md:order-last md:w-auto">
|
||||
<div>
|
||||
@if ($server->proxySet())
|
||||
@can('manageProxy', $server)
|
||||
<div id="server-mobile-actions" class="mt-2 mb-3 md:hidden">
|
||||
<div class="mb-1 text-xs font-semibold uppercase tracking-wide text-neutral-500 dark:text-neutral-400">Actions</div>
|
||||
@if ($proxyStatus === 'running')
|
||||
<div class="flex gap-2">
|
||||
<div class="flex flex-nowrap gap-2 overflow-x-auto">
|
||||
<button type="button" class="button shrink-0"
|
||||
@click="document.getElementById('server-mobile-restart-proxy-trigger')?.click()">
|
||||
<svg class="w-5 h-5 dark:text-warning" viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
|
||||
stroke-width="2">
|
||||
<path d="M19.933 13.041a8 8 0 1 1-9.925-8.788c3.899-1 7.935 1.007 9.425 4.747" />
|
||||
<path d="M20 4v5h-5" />
|
||||
</g>
|
||||
</svg>
|
||||
Restart Proxy
|
||||
</button>
|
||||
<button type="button" class="button shrink-0 text-error"
|
||||
@click="document.getElementById('server-mobile-stop-proxy-trigger')?.click()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-error" viewBox="0 0 24 24"
|
||||
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M6 5m0 1a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1v12a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1z">
|
||||
</path>
|
||||
<path
|
||||
d="M14 5m0 1a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1v12a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1z">
|
||||
</path>
|
||||
</svg>
|
||||
Stop Proxy
|
||||
</button>
|
||||
@if ($traefikDashboardAvailable)
|
||||
<a class="button shrink-0" target="_blank" href="http://{{ $serverIp }}:8080">
|
||||
Traefik Dashboard
|
||||
<x-external-link />
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<x-modal-confirmation title="Confirm Proxy Restart?" buttonTitle="Restart Proxy"
|
||||
submitAction="restart" :actions="[
|
||||
'This proxy will be stopped and started again.',
|
||||
'All resources hosted on coolify will be unavailable during the restart.',
|
||||
]" :confirmWithText="false" :confirmWithPassword="false" step2ButtonText="Restart Proxy"
|
||||
:dispatchEvent="true" dispatchEventType="restartEvent">
|
||||
<x-slot:trigger>
|
||||
<button id="server-mobile-restart-proxy-trigger" type="button" class="hidden">Restart Proxy</button>
|
||||
</x-slot:trigger>
|
||||
</x-modal-confirmation>
|
||||
<x-modal-confirmation title="Confirm Proxy Stopping?" buttonTitle="Stop Proxy"
|
||||
submitAction="stop(true)" :actions="[
|
||||
'The coolify proxy will be stopped.',
|
||||
'All resources hosted on coolify will be unavailable.',
|
||||
]" :confirmWithText="false"
|
||||
:confirmWithPassword="false" step2ButtonText="Stop Proxy" :dispatchEvent="true"
|
||||
dispatchEventType="stopEvent">
|
||||
<x-slot:trigger>
|
||||
<button id="server-mobile-stop-proxy-trigger" type="button" class="hidden">Stop Proxy</button>
|
||||
</x-slot:trigger>
|
||||
</x-modal-confirmation>
|
||||
<div class="hidden gap-2 md:flex">
|
||||
<div class="mt-1" wire:loading wire:target="loadProxyConfiguration">
|
||||
<x-loading text="Checking Traefik dashboard" />
|
||||
</div>
|
||||
@@ -181,6 +241,7 @@
|
||||
</svg>
|
||||
Start Proxy
|
||||
</button>
|
||||
</div>
|
||||
@endif
|
||||
@endcan
|
||||
@endif
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{{ data_get_str($server, 'name')->limit(10) }} > Private Key | Coolify
|
||||
</x-slot>
|
||||
<livewire:server.navbar :server="$server" />
|
||||
<div class="flex flex-col h-full gap-8 sm:flex-row">
|
||||
<div class="flex flex-col h-full gap-2 md:gap-8 md:flex-row">
|
||||
<x-server.sidebar :server="$server" activeMenu="private-key" />
|
||||
<div class="w-full">
|
||||
<div class="flex items-end gap-2">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Proxy Dynamic Configuration | Coolify
|
||||
</x-slot>
|
||||
<livewire:server.navbar :server="$server" />
|
||||
<div class="flex flex-col h-full gap-8 sm:flex-row">
|
||||
<div class="flex flex-col h-full gap-2 md:gap-8 md:flex-row">
|
||||
<x-server.sidebar-proxy :server="$server" :parameters="$parameters" />
|
||||
@if ($server->isFunctional())
|
||||
<div class="w-full">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Proxy Logs | Coolify
|
||||
</x-slot>
|
||||
<livewire:server.navbar :server="$server" />
|
||||
<div class="flex flex-col h-full gap-8 sm:flex-row">
|
||||
<div class="flex flex-col h-full gap-2 md:gap-8 md:flex-row">
|
||||
<x-server.sidebar-proxy :server="$server" :parameters="$parameters" />
|
||||
<div class="w-full">
|
||||
<h2 class="pb-4">Logs</h2>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
</x-slot>
|
||||
<livewire:server.navbar :server="$server" />
|
||||
@if ($server->isFunctional())
|
||||
<div class="flex flex-col h-full gap-8 sm:flex-row">
|
||||
<div class="flex flex-col h-full gap-2 md:gap-8 md:flex-row">
|
||||
<x-server.sidebar-proxy :server="$server" :parameters="$parameters" />
|
||||
<div class="w-full">
|
||||
<livewire:server.proxy :server="$server" />
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{{ data_get_str($server, 'name')->limit(10) }} > Server Resources | Coolify
|
||||
</x-slot>
|
||||
<livewire:server.navbar :server="$server" />
|
||||
<div x-data="{ activeTab: 'managed' }" class="flex flex-col h-full gap-8 md:flex-row">
|
||||
<div x-data="{ activeTab: 'managed' }" class="flex flex-col h-full gap-2 md:gap-8 md:flex-row">
|
||||
<div class="w-full">
|
||||
<div class="flex flex-col">
|
||||
<div class="flex gap-2">
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</x-slot:content>
|
||||
</x-slide-over>
|
||||
|
||||
<div x-data="{ activeTab: window.location.hash ? window.location.hash.substring(1) : 'general' }" class="flex flex-col h-full gap-8 sm:flex-row">
|
||||
<div x-data="{ activeTab: window.location.hash ? window.location.hash.substring(1) : 'general' }" class="flex flex-col h-full gap-2 md:gap-8 md:flex-row">
|
||||
<x-server.sidebar-security :server="$server" :parameters="$parameters" />
|
||||
<form wire:submit='submit' class="w-full">
|
||||
<div>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{{ data_get_str($server, 'name')->limit(10) }} > Terminal Access | Coolify
|
||||
</x-slot>
|
||||
<livewire:server.navbar :server="$server" />
|
||||
<div x-data="{ activeTab: window.location.hash ? window.location.hash.substring(1) : 'general' }" class="flex flex-col h-full gap-8 sm:flex-row">
|
||||
<div x-data="{ activeTab: window.location.hash ? window.location.hash.substring(1) : 'general' }" class="flex flex-col h-full gap-2 md:gap-8 md:flex-row">
|
||||
<x-server.sidebar-security :server="$server" :parameters="$parameters" />
|
||||
<div class="w-full">
|
||||
<div>
|
||||
@@ -52,4 +52,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -3,7 +3,7 @@
|
||||
Sentinel Logs | Coolify
|
||||
</x-slot>
|
||||
<livewire:server.navbar :server="$server" />
|
||||
<div class="flex flex-col h-full gap-8 sm:flex-row">
|
||||
<div class="flex flex-col h-full gap-2 md:gap-8 md:flex-row">
|
||||
<x-server.sidebar-sentinel :server="$server" :parameters="$parameters" />
|
||||
<div class="w-full">
|
||||
<h2 class="pb-4">Logs</h2>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
</x-slot>
|
||||
<livewire:server.navbar :server="$server" />
|
||||
@if ($server->isFunctional())
|
||||
<div class="flex flex-col h-full gap-8 sm:flex-row">
|
||||
<div class="flex flex-col h-full gap-2 md:gap-8 md:flex-row">
|
||||
<x-server.sidebar-sentinel :server="$server" :parameters="$parameters" />
|
||||
<div class="w-full">
|
||||
<livewire:server.sentinel :server="$server" />
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{{ data_get_str($server, 'name')->limit(10) }} > General | Coolify
|
||||
</x-slot>
|
||||
<livewire:server.navbar :server="$server" />
|
||||
<div class="flex flex-col h-full gap-8 sm:flex-row">
|
||||
<div class="flex flex-col h-full gap-2 md:gap-8 md:flex-row">
|
||||
<x-server.sidebar :server="$server" activeMenu="general" />
|
||||
<div class="w-full">
|
||||
<form wire:submit.prevent='submit' class="flex flex-col">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{{ data_get_str($server, 'name')->limit(10) }} > Swarm | Coolify
|
||||
</x-slot>
|
||||
<livewire:server.navbar :server="$server" />
|
||||
<div class="flex flex-col h-full gap-8 sm:flex-row">
|
||||
<div class="flex flex-col h-full gap-2 md:gap-8 md:flex-row">
|
||||
<x-server.sidebar :server="$server" activeMenu="swarm" />
|
||||
<div class="w-full">
|
||||
<div>
|
||||
|
||||
Reference in new issue
Block a user