Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ Once done, just go to <your host> and login as "admin" with <any password>.
| HOST | Url to OnLogs host from protocol to domain name. | | if `AGENT=true`
| ONLOGS_TOKEN | Token that will use an agent to authorize and connect to HOST | Generates with OnLogs interface | if `AGENT=true`
| MAX_LOGS_SIZE | Maximum allowed total logs size before cleanup triggers. Accepts human-readable formats like 5GB, 500MB, 1.5GB etc. When exceeded, 10% of logs (by count) will be removed proportionally across containers starting from oldest | 10GB | -
| DISABLE_AUTH | Option to completely disable built in authentication in the application. When this option is set to `true` the app will behave like if the Administrator is logged in. The option to manage users will be removed. | false | -

### Docket socket URL
By default the app will connect using the raw unix socket. But this can be overriden via the ENV variable `DOCKER_HOST`. That way you can specify fully qualified URL to the socket or URL of an docker socket proxy.
Expand Down
2 changes: 1 addition & 1 deletion application/backend/.env example
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ PASSWORD=fsadfsadfad
ENV_NAME = local
PORT=2874
ONLOGS_PATH_PREFIX=''

DISABLE_AUTH=false
# HOST=onlogs.coposter.me
# AGENT=true
29 changes: 24 additions & 5 deletions application/backend/app/routes/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ func enableCors(w *http.ResponseWriter) {
}

func verifyAdminUser(w *http.ResponseWriter, req *http.Request) bool {
if os.Getenv("DISABLE_AUTH") == "true" {
return true
}

username, err := util.GetUserFromJWT(*req)
if username != os.Getenv("ADMIN_USERNAME") {
(*w).WriteHeader(http.StatusForbidden)
Expand All @@ -59,6 +63,10 @@ func verifyAdminUser(w *http.ResponseWriter, req *http.Request) bool {
}

func verifyUser(w *http.ResponseWriter, req *http.Request) bool {
if os.Getenv("DISABLE_AUTH") == "true" {
return true
}

_, err := util.GetUserFromJWT(*req)
if err != nil {
(*w).WriteHeader(http.StatusUnauthorized)
Expand Down Expand Up @@ -91,19 +99,30 @@ func (h *RouteController)Frontend(w http.ResponseWriter, req *http.Request) {
if err != nil {
dir = http.Dir("dist")
file, err = dir.Open("index.html")
fileName = "index.html"
}
if err != nil {
return
}
defer file.Close()

stat, _ := file.Stat()
content, _ := io.ReadAll(file)

Comment on lines +109 to +111
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

file.Stat() and io.ReadAll(file) errors are ignored. If Stat() fails, stat will be nil and stat.ModTime() will panic; if ReadAll fails, you may serve partial/empty content without signaling an error. Please handle these errors and return an appropriate HTTP status (e.g. 500) instead of proceeding.

Copilot uses AI. Check for mistakes.
if fileName == "index.html" {
var disableAuth []byte
if os.Getenv("DISABLE_AUTH") == "true" {
disableAuth = []byte("true")
} else {
disableAuth = []byte("false")
}

content = bytes.Replace(content, []byte("$DISABLE_AUTH$"), disableAuth, 1)
}

w.Header().Set("Cache-Control", "no-store")
w.Header().Set("Content-Type", mime.TypeByExtension(filepath.Ext(fileName)))

stat, _ := file.Stat()
content := make([]byte, stat.Size())
io.ReadFull(file, content)
http.ServeContent(w, req, requestedPath, stat.ModTime(), bytes.NewReader(content))
http.ServeContent(w, req, fileName, stat.ModTime(), bytes.NewReader(content))
}

func (h *RouteController)CheckCookie(w http.ResponseWriter, req *http.Request) {
Expand Down
12 changes: 6 additions & 6 deletions application/backend/app/routes/routes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import (
"github.com/devforth/OnLogs/app/userdb"
"github.com/devforth/OnLogs/app/util"
"github.com/devforth/OnLogs/app/vars"
"github.com/joho/godotenv"
"github.com/docker/docker/client"
"github.com/joho/godotenv"
"github.com/syndtr/goleveldb/leveldb"
)

Expand All @@ -33,11 +33,11 @@ func initTestConfig() *RouteController {
DockerClient: dockerService,
}

// Initialize the "Controller" with its dependencies
routerCtrl := &RouteController{
DockerService: dockerService,
// Initialize the "Controller" with its dependencies
routerCtrl := &RouteController{
DockerService: dockerService,
DaemonService: daemonService,
}
}
return routerCtrl
}

Expand Down Expand Up @@ -93,7 +93,7 @@ func TestCheckCookie(t *testing.T) {
func TestGetHosts(t *testing.T) {
err := godotenv.Load("../../.env")
if err != nil {
os.Setenv("DOCKER_HOST", "tcp://localhost:2375")
os.Setenv("DOCKER_HOST", "unix:///var/run/docker.sock")
}
ctrl := initTestConfig()

Expand Down
4 changes: 4 additions & 0 deletions application/frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@

<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OnLogs</title>

<script>
window.DISABLE_AUTH=$DISABLE_AUTH$ ?? false;
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$DISABLE_AUTH$ is not valid JavaScript syntax when this file is served without backend substitution (e.g. during local frontend dev / Vite). As written, the page will error before the app loads. Consider placing the placeholder inside a string and parsing it (or using a build-time env injection) so the script remains valid even when the placeholder is not replaced.

Suggested change
window.DISABLE_AUTH=$DISABLE_AUTH$ ?? false;
(function () {
const rawDisableAuth = '$DISABLE_AUTH$';
const value = String(rawDisableAuth).trim().toLowerCase();
const isDisabled =
value === 'true' || value === '1' || value === 'yes';
window.DISABLE_AUTH = isDisabled;
})();

Copilot uses AI. Check for mistakes.
</script>
</head>
<body>
<div id="app"></div>
Expand Down
4 changes: 4 additions & 0 deletions application/frontend/src/lib/ClientPanel/ClientPanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
let localTheme = "";
let api = new fetchApi();

const showUserMenu = window.DISABLE_AUTH ?? true;
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

showUserMenu is derived from window.DISABLE_AUTH in a way that inverts the intended behavior: when auth is enabled (DISABLE_AUTH === false), false ?? true evaluates to false and the Users menu is hidden; when auth is disabled it becomes visible. Consider computing this as the inverse of DISABLE_AUTH (defaulting to auth enabled) so the Users menu is hidden only when auth is disabled.

Suggested change
const showUserMenu = window.DISABLE_AUTH ?? true;
const showUserMenu = !(window.DISABLE_AUTH ?? false);

Copilot uses AI. Check for mistakes.

//store management
function toggleUserMenu() {
userMenuOpen.update((v) => !v);
Expand Down Expand Up @@ -69,6 +71,7 @@
($activeMenuOption === 'view' && 'active')}"
/>
</li>
{#if showUserMenu}
<li
on:click={toggleUserMenu}
class={$activeMenuOption === "users" && "active"}
Expand All @@ -78,6 +81,7 @@
class="higlightedOverlay {$activeMenuOption === 'users' && 'active'}"
/>
</li>
{/if}

<!-- <li class={$activeMenuOption === "wheel" && "active"}>
<i class="log log-Wheel" />
Expand Down