Skip /js/ in the Access Gate and set denied-page CSP so Denied UI can render.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+16
-2
@@ -181,9 +181,10 @@ func (g AccessGate) normalized() *AccessGate {
|
||||
|
||||
func (g *AccessGate) writeDenied(w http.ResponseWriter, r *http.Request) {
|
||||
if acceptsHTML(r.Header.Get("Accept")) {
|
||||
// 200 so AppAPI's proxy CSP keeps frame-ancestors 'self' and the ExApp
|
||||
// iframe can show the message (403 responses get frame-ancestors 'none').
|
||||
// 200 plus frame-ancestors 'self': AppAPI's default proxy CSP uses
|
||||
// frame-ancestors 'none' unless the ExApp sets CSP, which blanks iframes.
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
w.Header().Set("Content-Security-Policy", deniedCSP)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write(deniedHTML)
|
||||
return
|
||||
@@ -197,6 +198,9 @@ func acceptsHTML(accept string) bool {
|
||||
|
||||
func (g *AccessGate) shouldSkip(path string) bool {
|
||||
path = normalizeGatePath(path)
|
||||
if isTopMenuScriptPath(path) {
|
||||
return true
|
||||
}
|
||||
for _, p := range defaultSkipPaths {
|
||||
if path == p {
|
||||
return true
|
||||
@@ -210,6 +214,13 @@ func (g *AccessGate) shouldSkip(path string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// isTopMenuScriptPath reports AppAPI top-menu bootstrap scripts under /js/.
|
||||
// Those must load for a non-member so the shell can show Denied UI; gating
|
||||
// them yields a blank embedded page (script Accept is not text/html → 403).
|
||||
func isTopMenuScriptPath(path string) bool {
|
||||
return path == "/js" || strings.HasPrefix(path, "/js/")
|
||||
}
|
||||
|
||||
func normalizeGatePath(path string) string {
|
||||
path = strings.TrimSuffix(path, "/")
|
||||
if path == "" {
|
||||
@@ -220,6 +231,9 @@ func normalizeGatePath(path string) string {
|
||||
|
||||
var defaultSkipPaths = []string{"/heartbeat", "/enabled", "/init"}
|
||||
|
||||
// deniedCSP lets AppAPI proxy the denied page into an ExApp iframe.
|
||||
const deniedCSP = "default-src 'none'; base-uri 'none'; form-action 'none'; frame-ancestors 'self'; style-src 'unsafe-inline'"
|
||||
|
||||
var deniedHTML = []byte(`<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
|
||||
Reference in New Issue
Block a user