diff --git a/backend/internal/bootstrap/router_huma_test.go b/backend/internal/bootstrap/router_huma_test.go
index 7c1502f0..0ef152e9 100644
--- a/backend/internal/bootstrap/router_huma_test.go
+++ b/backend/internal/bootstrap/router_huma_test.go
@@ -35,7 +35,7 @@ func TestHumaRouterOpenAPI(t *testing.T) {
require.NoError(t, registerRoutes(router, db, services, nil))
response := httptest.NewRecorder()
- router.ServeHTTP(response, httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/api/openapi.json", nil))
+ router.ServeHTTP(response, httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/api/openai.json", nil))
require.Equal(t, http.StatusOK, response.Code)
var document struct {
@@ -97,10 +97,7 @@ func TestHumaRouterOpenAPI(t *testing.T) {
response = httptest.NewRecorder()
router.ServeHTTP(response, httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/api/docs", nil))
- require.Equal(t, http.StatusOK, response.Code)
- require.Contains(t, response.Header().Get("Content-Security-Policy"), "https://cdn.jsdelivr.net")
- require.NotContains(t, response.Header().Get("Content-Security-Policy"), "script-src 'unsafe-inline'")
- require.Contains(t, response.Body.String(), "@scalar/api-reference@1.62.5")
+ require.Equal(t, http.StatusNotFound, response.Code)
response = httptest.NewRecorder()
newHTTPServer(router, nil).Handler.ServeHTTP(response, httptest.NewRequestWithContext(t.Context(), http.MethodHead, "/healthz", nil))
diff --git a/backend/internal/utils/csp.go b/backend/internal/utils/csp.go
index 730f593c..ce42f41d 100644
--- a/backend/internal/utils/csp.go
+++ b/backend/internal/utils/csp.go
@@ -35,26 +35,6 @@ func BuildFormPostCSP(nonce, redirectURI, scriptHash string) string {
return buildCSP(nonce, []string{redirectURI}, []string{scriptHash})
}
-// BuildAPIDocsCSP allows the pinned Scalar bundle and the assets it creates
-func BuildAPIDocsCSP(nonce string) string {
- scriptSrc := "script-src 'self' https://cdn.jsdelivr.net"
- if nonce != "" {
- scriptSrc += " 'nonce-" + nonce + "'"
- }
-
- return "default-src 'self'; " +
- "base-uri 'self'; " +
- "object-src 'none'; " +
- "frame-ancestors 'none'; " +
- "form-action 'self'; " +
- "img-src * blob: data:; " +
- "font-src 'self' https://cdn.jsdelivr.net data:; " +
- "style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; " +
- "worker-src blob:; " +
- "connect-src 'self'; " +
- scriptSrc
-}
-
func buildCSP(nonce string, formActionExtra, scriptSrcExtra []string) string {
formAction := "'self'"
scriptSrc := "script-src 'self'"
diff --git a/backend/internal/utils/huma/api.go b/backend/internal/utils/huma/api.go
index a1b4295a..5d1fb44a 100644
--- a/backend/internal/utils/huma/api.go
+++ b/backend/internal/utils/huma/api.go
@@ -3,33 +3,15 @@ package humautils
import (
"encoding/json"
"io"
- "net/http"
"github.com/danielgtaylor/huma/v2"
"github.com/danielgtaylor/huma/v2/adapters/humagin"
"github.com/gin-gonic/gin"
"github.com/pocket-id/pocket-id/backend/internal/common"
- "github.com/pocket-id/pocket-id/backend/internal/utils"
"github.com/pocket-id/pocket-id/backend/internal/utils/cookie"
)
-const scalarDocsHTML = `
-
-
- Pocket ID API Reference
-
-
-
-
-
-
-
-`
-
var ginCompatibleJSONFormat = huma.Format{
Marshal: func(w io.Writer, value any) error {
data, err := json.Marshal(value)
@@ -47,7 +29,7 @@ func New(r *gin.Engine, group *gin.RouterGroup) huma.API {
config := huma.DefaultConfig("Pocket ID API", common.Version)
config.CreateHooks = nil
config.DocsPath = ""
- config.OpenAPIPath = "/api/openapi"
+ config.OpenAPIPath = "/api/openai"
config.SchemasPath = "/api/schemas"
config.AllowAdditionalPropertiesByDefault = true
config.Security = nil
@@ -94,7 +76,6 @@ func New(r *gin.Engine, group *gin.RouterGroup) huma.API {
humagin.MultipartMaxMemory = r.MaxMultipartMemory
api := humagin.NewWithGroup(r, group, config)
api.UseMiddleware(CaptureRequestContext)
- registerScalarDocs(group)
return api
}
@@ -108,11 +89,3 @@ func rewriteValidationResponse(_ *huma.OpenAPI, operation *huma.Operation) {
}
delete(operation.Responses, "422")
}
-
-func registerScalarDocs(group *gin.RouterGroup) {
- group.GET("/api/docs", func(ctx *gin.Context) {
- nonce := utils.GetCSPNonce(ctx)
- ctx.Header("Content-Security-Policy", utils.BuildAPIDocsCSP(nonce))
- ctx.Data(http.StatusOK, "text/html; charset=utf-8", []byte(scalarDocsHTML))
- })
-}
diff --git a/backend/internal/utils/huma/api_test.go b/backend/internal/utils/huma/api_test.go
index cfad589c..6a319362 100644
--- a/backend/internal/utils/huma/api_test.go
+++ b/backend/internal/utils/huma/api_test.go
@@ -154,7 +154,7 @@ func TestCookiesStreamingAndOpenAPI(t *testing.T) {
require.True(t, reader.closed)
response = httptest.NewRecorder()
- router.ServeHTTP(response, httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/api/openapi.json", nil))
+ router.ServeHTTP(response, httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/api/openai.json", nil))
require.Equal(t, http.StatusOK, response.Code)
require.Contains(t, response.Body.String(), `"/api/test-raw"`)
require.NotContains(t, response.Body.String(), `"422"`)
@@ -162,10 +162,7 @@ func TestCookiesStreamingAndOpenAPI(t *testing.T) {
response = httptest.NewRecorder()
router.ServeHTTP(response, httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/api/docs", nil))
- require.Equal(t, http.StatusOK, response.Code)
- require.Contains(t, response.Body.String(), "@scalar/api-reference@1.62.5")
- require.Contains(t, response.Header().Get("Content-Security-Policy"), "worker-src blob:")
- require.NotContains(t, response.Header().Get("Content-Security-Policy"), "script-src 'unsafe-inline'")
+ require.Equal(t, http.StatusNotFound, response.Code)
}
func TestRegisterAppliesDecoratorsInOrder(t *testing.T) {
diff --git a/frontend/messages/en.json b/frontend/messages/en.json
index ba4eafa7..92c7515e 100644
--- a/frontend/messages/en.json
+++ b/frontend/messages/en.json
@@ -140,7 +140,7 @@
"name_passkey": "Name Passkey",
"name_your_passkey_to_easily_identify_it_later": "Name your passkey to easily identify it later.",
"create_api_key": "Create API Key",
- "add_a_new_api_key_for_programmatic_access": "Add a new API key for programmatic access to the Pocket ID API.",
+ "add_a_new_api_key_for_programmatic_access": "Add a new API key for programmatic access to the Pocket ID API.",
"add_api_key": "Add API Key",
"manage_api_keys": "Manage API Keys",
"api_key_created": "API Key Created",