Skip to content

Commit

Permalink
fix: proxies avatars which should fix #2591 and remove all CSP errors (
Browse files Browse the repository at this point in the history
  • Loading branch information
amir20 authored Dec 16, 2023
1 parent 83746fd commit 4b658fb
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 25 deletions.
5 changes: 4 additions & 1 deletion assets/components/Links.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@

<dropdown class="dropdown-end" v-if="config.user">
<template #trigger>
<img class="h-6 w-6 max-w-none rounded-full p-px ring-1 ring-base-content/60" :src="config.user.avatar" />
<img
class="h-6 w-6 max-w-none rounded-full p-px ring-1 ring-base-content/60"
:src="withBase('/api/profile/avatar')"
/>
</template>
<template #content>
<div class="p-2">
Expand Down
1 change: 0 additions & 1 deletion assets/stores/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export interface Config {
username: string;
email: string;
name: string;
avatar: string;
};
profile?: Profile;
pages?: { id: string; title: string }[];
Expand Down
8 changes: 4 additions & 4 deletions internal/auth/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@ type User struct {
Username string `json:"username"`
Email string `json:"email" yaml:"email"`
Name string `json:"name" yaml:"name"`
Avatar string `json:"avatar,omitempty"`
Password string `json:"-" yaml:"password"`
}

func newUser(username, email, name string) User {
avatar := fmt.Sprintf("https://gravatar.com/avatar/%s?d=https%%3A%%2F%%2Fui-avatars.com%%2Fapi%%2F/%s/128", hashEmail(email), name)
func (u User) AvatarURL() string {
return fmt.Sprintf("https://gravatar.com/avatar/%s?d=https%%3A%%2F%%2Fui-avatars.com%%2Fapi%%2F/%s/128", hashEmail(u.Email), u.Name)
}

func newUser(username, email, name string) User {
return User{
Username: username,
Email: email,
Name: name,
Avatar: avatar,
}
}

Expand Down
36 changes: 18 additions & 18 deletions internal/web/__snapshots__/web.snapshot
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
/* snapshot: Test_createRoutes_foobar */
HTTP/1.1 200 OK
Connection: close
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' gravatar.com data:; manifest-src 'self'; connect-src 'self' api.github.com;
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
Content-Type: text/plain; charset=utf-8

foo page

/* snapshot: Test_createRoutes_index */
HTTP/1.1 200 OK
Connection: close
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' gravatar.com data:; manifest-src 'self'; connect-src 'self' api.github.com;
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
Content-Type: text/plain; charset=utf-8

index page

/* snapshot: Test_createRoutes_redirect */
HTTP/1.1 301 Moved Permanently
Connection: close
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' gravatar.com data:; manifest-src 'self'; connect-src 'self' api.github.com;
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
Content-Type: text/html; charset=utf-8
Location: /foobar/

Expand All @@ -26,7 +26,7 @@ Location: /foobar/
/* snapshot: Test_createRoutes_redirect_with_auth */
HTTP/1.1 307 Temporary Redirect
Connection: close
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' gravatar.com data:; manifest-src 'self'; connect-src 'self' api.github.com;
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
Content-Type: text/html; charset=utf-8
Location: /foobar/login

Expand All @@ -35,7 +35,7 @@ Location: /foobar/login
/* snapshot: Test_createRoutes_simple_redirect */
HTTP/1.1 307 Temporary Redirect
Connection: close
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' gravatar.com data:; manifest-src 'self'; connect-src 'self' api.github.com;
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
Content-Type: text/html; charset=utf-8
Location: /login

Expand All @@ -44,7 +44,7 @@ Location: /login
/* snapshot: Test_createRoutes_username_password */
HTTP/1.1 307 Temporary Redirect
Connection: close
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' gravatar.com data:; manifest-src 'self'; connect-src 'self' api.github.com;
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
Content-Type: text/html; charset=utf-8
Location: /login

Expand All @@ -53,7 +53,7 @@ Location: /login
/* snapshot: Test_createRoutes_username_password_invalid */
HTTP/1.1 401 Unauthorized
Connection: close
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' gravatar.com data:; manifest-src 'self'; connect-src 'self' api.github.com;
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff

Expand All @@ -65,7 +65,7 @@ Connection: close
Cache-Control: no-transform
Cache-Control: no-cache
Connection: keep-alive
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' gravatar.com data:; manifest-src 'self'; connect-src 'self' api.github.com;
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
Content-Type: text/event-stream
X-Accel-Buffering: no

Expand All @@ -75,15 +75,15 @@ data: end of stream
/* snapshot: Test_createRoutes_version */
HTTP/1.1 200 OK
Connection: close
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' gravatar.com data:; manifest-src 'self'; connect-src 'self' api.github.com;
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
Content-Type: text/html

<pre>dev</pre>

/* snapshot: Test_handler_between_dates */
HTTP/1.1 200 OK
Connection: close
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' gravatar.com data:; manifest-src 'self'; connect-src 'self' api.github.com;
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
Content-Type: application/x-jsonl; charset=UTF-8

{"m":"INFO Testing stdout logs...","ts":1589396137772,"id":466600245,"l":"info","s":"stdout"}
Expand All @@ -110,7 +110,7 @@ Connection: close
Cache-Control: no-transform
Cache-Control: no-cache
Connection: keep-alive
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' gravatar.com data:; manifest-src 'self'; connect-src 'self' api.github.com;
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
Content-Type: text/event-stream
X-Accel-Buffering: no

Expand All @@ -123,7 +123,7 @@ Connection: close
Cache-Control: no-transform
Cache-Control: no-cache
Connection: keep-alive
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' gravatar.com data:; manifest-src 'self'; connect-src 'self' api.github.com;
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
Content-Type: text/event-stream
X-Accel-Buffering: no

Expand All @@ -141,7 +141,7 @@ data: {"actorId":"1234","name":"start","host":"localhost"}
/* snapshot: Test_handler_streamLogs_error_finding_container */
HTTP/1.1 404 Not Found
Connection: close
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' gravatar.com data:; manifest-src 'self'; connect-src 'self' api.github.com;
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff

Expand All @@ -153,7 +153,7 @@ Connection: close
Cache-Control: no-transform
Cache-Control: no-cache
Connection: keep-alive
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' gravatar.com data:; manifest-src 'self'; connect-src 'self' api.github.com;
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
Content-Type: text/plain; charset=utf-8
X-Accel-Buffering: no
X-Content-Type-Options: nosniff
Expand All @@ -163,7 +163,7 @@ test error
/* snapshot: Test_handler_streamLogs_error_std */
HTTP/1.1 400 Bad Request
Connection: close
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' gravatar.com data:; manifest-src 'self'; connect-src 'self' api.github.com;
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff

Expand All @@ -175,7 +175,7 @@ Connection: close
Cache-Control: no-transform
Cache-Control: no-cache
Connection: keep-alive
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' gravatar.com data:; manifest-src 'self'; connect-src 'self' api.github.com;
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
Content-Type: text/event-stream
X-Accel-Buffering: no

Expand All @@ -190,7 +190,7 @@ Connection: close
Cache-Control: no-transform
Cache-Control: no-cache
Connection: keep-alive
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' gravatar.com data:; manifest-src 'self'; connect-src 'self' api.github.com;
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
Content-Type: text/event-stream
X-Accel-Buffering: no

Expand All @@ -203,7 +203,7 @@ Connection: close
Cache-Control: no-transform
Cache-Control: no-cache
Connection: keep-alive
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' gravatar.com data:; manifest-src 'self'; connect-src 'self' api.github.com;
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
Content-Type: text/event-stream
X-Accel-Buffering: no

Expand Down
2 changes: 1 addition & 1 deletion internal/web/csp.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

func cspHeaders(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Security-Policy", "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' gravatar.com data:; manifest-src 'self'; connect-src 'self' api.github.com;")
w.Header().Set("Content-Security-Policy", "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;")
next.ServeHTTP(w, r)
})
}
29 changes: 29 additions & 0 deletions internal/web/profile.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package web

import (
"io"
"net/http"

"github.com/amir20/dozzle/internal/auth"
Expand All @@ -23,3 +24,31 @@ func (h *handler) updateProfile(w http.ResponseWriter, r *http.Request) {

w.WriteHeader(http.StatusOK)
}

func (h *handler) avatar(w http.ResponseWriter, r *http.Request) {
user := auth.UserFromContext(r.Context())
if user == nil {
http.Error(w, "Unable to find user", http.StatusInternalServerError)
return
}

url := user.AvatarURL()

if url == "" {
http.Error(w, "Unable to find avatar", http.StatusNotFound)
return
}

response, err := http.Get(url)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

defer response.Body.Close()

w.Header().Set("Content-Type", response.Header.Get("Content-Type"))
w.Header().Set("Cache-Control", "public, max-age=86400")

io.Copy(w, response.Body)
}
1 change: 1 addition & 0 deletions internal/web/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ func createRouter(h *handler) *chi.Mux {
r.Post("/api/actions/{action}/{host}/{id}", h.containerActions)
}
r.Get("/api/releases", h.releases)
r.Get("/api/profile/avatar", h.avatar)
r.Patch("/api/profile", h.updateProfile)
r.Get("/api/content/{id}", h.staticContent)
r.Get("/logout", h.clearSession) // TODO remove this
Expand Down

0 comments on commit 4b658fb

Please sign in to comment.