remove built in api docs

This commit is contained in:
Kyle Mendell
2026-07-16 21:45:52 -05:00
parent 8beb4921c1
commit f5de8e6bad
5 changed files with 6 additions and 59 deletions
@@ -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))
-20
View File
@@ -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'"
+1 -28
View File
@@ -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 = `<!doctype html>
<html>
<head>
<title>Pocket ID API Reference</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<script
id="api-reference"
data-url="/api/openapi.json"
data-configuration='{"theme":"purple","darkMode":true,"layout":"modern","hiddenClients":["unirest"],"defaultHttpClient":{"targetKey":"shell","clientKey":"curl"}}'></script>
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference@1.62.5" integrity="sha384-jVBCKhcCfx34USN27x4iQK1SBNdL/HxKq3KuBAxTS4WPaP5w80K4fjpwB+DezJL5" crossorigin="anonymous"></script>
</body>
</html>`
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))
})
}
+2 -5
View File
@@ -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) {
+1 -1
View File
@@ -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 <link href='/api/docs'>Pocket ID API</link>.",
"add_a_new_api_key_for_programmatic_access": "Add a new API key for programmatic access to the <link href='https://pocket-id.org/docs/api'>Pocket ID API</link>.",
"add_api_key": "Add API Key",
"manage_api_keys": "Manage API Keys",
"api_key_created": "API Key Created",