Subject: [PATCH links] bump gobwebs-graphql to toggle introspection when not in debug mode.

From: Peter Sanchez <[email-masked]>
Date: Tue, 26 May 2026 17:10:35 -0600

rename `config` variable name to `conf` as it conflicts with the
`config` module.
---
 cmd/api/main.go   | 29 +++++++++++++++--------------
 cmd/links/main.go | 36 ++++++++++++++++++------------------
 cmd/list/main.go  | 26 +++++++++++++-------------
 cmd/short/main.go | 22 +++++++++++-----------
 go.mod            |  2 +-
 go.sum            |  4 ++--
 6 files changed, 60 insertions(+), 59 deletions(-)

diff --git a/cmd/api/main.go b/cmd/api/main.go
index bfec080..0b18c50 100644
--- a/cmd/api/main.go
+++ b/cmd/api/main.go
@@ -44,52 +44,52 @@ func main() {
 }
 
 func run() error {
-	config, err := config.LoadConfig("./config.ini")
+	conf, err := config.LoadConfig("./config.ini")
 	if err != nil {
 		return err
 	}
 
-	db, err := cmd.OpenDB(config)
+	db, err := cmd.OpenDB(conf)
 	if err != nil {
 		return fmt.Errorf("Unable to open connection to PostgreSQL: %v", err)
 	}
 	defer db.Close()
 	database.SetPlaceholderFormat(sq.Dollar)
 
-	entropy, ok := config.File.Get("access", "entropy")
+	entropy, ok := conf.File.Get("access", "entropy")
 	if !ok {
 		return fmt.Errorf("No access entropy set. Required value")
 	}
 
-	if val, ok := config.File.Get("links", "api-listen-address"); ok {
+	if val, ok := conf.File.Get("links", "api-listen-address"); ok {
 		if val != "" {
-			config.ListenAddr = val
+			conf.ListenAddr = val
 		}
 	}
 
-	if val, ok := config.File.Get("links", "api-listen-port"); ok {
-		config.ListenPort, err = strconv.Atoi(val)
+	if val, ok := conf.File.Get("links", "api-listen-port"); ok {
+		conf.ListenPort, err = strconv.Atoi(val)
 		if err != nil {
 			return fmt.Errorf("links:api-listen-port must be an integer value")
 		}
 	}
 
-	esvc, err := cmd.LoadEmailService(config)
+	esvc, err := cmd.LoadEmailService(conf)
 	if err != nil {
 		return fmt.Errorf("unable to load email service: %v", err)
 	}
 
-	storesvc, err := cmd.LoadStorageService(config)
+	storesvc, err := cmd.LoadStorageService(conf)
 	if err != nil {
 		return fmt.Errorf("unable to load storage service: %v", err)
 	}
 
-	eSize, gSize, _, err := cmd.LoadWorkerQueueSizes(config)
+	eSize, gSize, _, err := cmd.LoadWorkerQueueSizes(conf)
 	if err != nil {
 		return err
 	}
 
-	rlConfig, err := links.NewRateLimiterConfig(config)
+	rlConfig, err := links.NewRateLimiterConfig(conf)
 	if err != nil {
 		return err
 	}
@@ -120,7 +120,7 @@ func run() error {
 		ServerContext: true,
 	}
 
-	srv := server.New(e, db, config).
+	srv := server.New(e, db, conf).
 		Initialize().
 		WithAppInfo("links-api", Version).
 		WithEmail(sq).
@@ -158,19 +158,20 @@ func run() error {
 		"QRCODES",
 	})
 	ext.GQL.ScopesPath = "/query/api-scopes.json"
+	ext.GQL.DisableIntrospection = !conf.Debug
 
 	srv, err = srv.Extend(ext)
 	if err != nil {
 		return err
 	}
 
-	if config.Debug {
+	if conf.Debug {
 		srv.SetQueueTimeout(1 * time.Millisecond)
 	}
 
 	srv.AddFuncs(template.FuncMap{
 		"buildURL": func(path string) string {
-			baseURL := fmt.Sprintf("%s://%s", config.Scheme, config.Domain)
+			baseURL := fmt.Sprintf("%s://%s", conf.Scheme, conf.Domain)
 			url, _ := url.JoinPath(baseURL, path)
 			return url
 		},
diff --git a/cmd/links/main.go b/cmd/links/main.go
index 21718a1..9e87726 100644
--- a/cmd/links/main.go
+++ b/cmd/links/main.go
@@ -122,38 +122,38 @@ func loadGQLDefaults(config *config.Config, svcConfig *gobwebsgql.ServiceConfig)
 }
 
 func run() error {
-	config, err := config.LoadConfig("./config.ini")
+	conf, err := config.LoadConfig("./config.ini")
 	if err != nil {
 		return err
 	}
 
-	entropy, ok := config.File.Get("access", "entropy")
+	entropy, ok := conf.File.Get("access", "entropy")
 	if !ok {
 		return fmt.Errorf("No access entropy set. Required value")
 	}
 
-	db, err := cmd.OpenDB(config)
+	db, err := cmd.OpenDB(conf)
 	if err != nil {
 		return fmt.Errorf("Unable to open connection to PostgreSQL: %v", err)
 	}
 	defer db.Close()
 	database.SetPlaceholderFormat(sq.Dollar)
 
-	esvc, err := cmd.LoadEmailService(config)
+	esvc, err := cmd.LoadEmailService(conf)
 	if err != nil {
 		return fmt.Errorf("unable to load email service: %v", err)
 	}
 
 	var storesvc storage.Service
-	switch config.StorageSvc {
+	switch conf.StorageSvc {
 	case "fs":
 		rootdir := "./"
-		if rd, ok := config.File.Get("storage", "root-directory"); ok {
+		if rd, ok := conf.File.Get("storage", "root-directory"); ok {
 			rootdir = rd
 		}
 		storesvc = storage.NewFileSystemService(rootdir)
 	case "s3":
-		ep, bucket, opts, err := loadStorageConfig(config)
+		ep, bucket, opts, err := loadStorageConfig(conf)
 		if err != nil {
 			return err
 		}
@@ -166,14 +166,14 @@ func run() error {
 		return fmt.Errorf("Unknown storage service configured")
 	}
 
-	eSize, gSize, iSize, err := cmd.LoadWorkerQueueSizes(config)
+	eSize, gSize, iSize, err := cmd.LoadWorkerQueueSizes(conf)
 	if err != nil {
 		return err
 	}
 
-	tlsman := cmd.LoadAutoTLS(config, db, models.DomainServiceLinks)
+	tlsman := cmd.LoadAutoTLS(conf, db, models.DomainServiceLinks)
 
-	rlConfig, err := links.NewRateLimiterConfig(config)
+	rlConfig, err := links.NewRateLimiterConfig(conf)
 	if err != nil {
 		return err
 	}
@@ -207,8 +207,8 @@ func run() error {
 			sm.Cookie.Persist = true
 			sm.Cookie.SameSite = http.SameSiteLaxMode
 			sm.Cookie.Secure = true
-			if !config.Debug {
-				ldomain, ok := config.File.Get("links", "links-service-domain")
+			if !conf.Debug {
+				ldomain, ok := conf.File.Get("links", "links-service-domain")
 				if !ok {
 					panic(fmt.Errorf("No links-service-domain set. Required value"))
 				}
@@ -218,7 +218,7 @@ func run() error {
 
 		},
 	}
-	srv := server.New(e, db, config).
+	srv := server.New(e, db, conf).
 		Initialize().
 		WithAppInfo("links", Version).
 		WithEmail(sq).
@@ -256,15 +256,15 @@ func run() error {
 		},
 		"trans": core.TmplTranslate,
 		"mediaURL": func(path string) string {
-			url, _ := url.JoinPath(config.MediaURL, path)
+			url, _ := url.JoinPath(conf.MediaURL, path)
 			return url
 		},
 		"staticURL": func(path string) string {
-			url, _ := url.JoinPath(config.StaticURL, path)
+			url, _ := url.JoinPath(conf.StaticURL, path)
 			return url
 		},
 		"buildURL": func(path string) string {
-			baseURL := fmt.Sprintf("%s://%s", config.Scheme, config.Domain)
+			baseURL := fmt.Sprintf("%s://%s", conf.Scheme, conf.Domain)
 			url, _ := url.JoinPath(baseURL, path)
 			return url
 		},
@@ -332,7 +332,7 @@ func run() error {
 
 	staticHandler := http.FileServer(http.FS(links.StaticFS))
 	e.GET("/static/*", echo.WrapHandler(staticHandler))
-	e.Static(config.MediaURL, "media")
+	e.Static(conf.MediaURL, "media")
 	accountGroup := e.Group("/accounts")
 	accounts.NewService(accountGroup, links.Render)
 	feedback.NewService(e.Group("/email-notify"), &mailChecker, true, "")
@@ -348,7 +348,7 @@ func run() error {
 		ExecuteFunc:          links.Execute,
 		ParseInputErrorsFunc: links.ParseInputErrors,
 	}
-	loadGQLDefaults(config, gqlConfig)
+	loadGQLDefaults(conf, gqlConfig)
 	gqlGroup := e.Group("")
 	// Rate limit the /graphql end point to avoid abuse
 	gqlGroup.Use(middleware.RateLimiterWithConfig(rlConfig))
diff --git a/cmd/list/main.go b/cmd/list/main.go
index 942ec79..8ebd05a 100644
--- a/cmd/list/main.go
+++ b/cmd/list/main.go
@@ -37,35 +37,35 @@ func main() {
 }
 
 func run() error {
-	config, err := config.LoadConfig("./config.ini")
+	conf, err := config.LoadConfig("./config.ini")
 	if err != nil {
 		return err
 	}
 
-	entropy, ok := config.File.Get("access", "entropy")
+	entropy, ok := conf.File.Get("access", "entropy")
 	if !ok {
 		return fmt.Errorf("No access entropy set. Required value")
 	}
 
-	if val, ok := config.File.Get("links", "list-listen-address"); ok {
+	if val, ok := conf.File.Get("links", "list-listen-address"); ok {
 		if val != "" {
-			config.ListenAddr = val
+			conf.ListenAddr = val
 		}
 	}
 
-	if val, ok := config.File.Get("links", "list-listen-port"); ok {
-		config.ListenPort, err = strconv.Atoi(val)
+	if val, ok := conf.File.Get("links", "list-listen-port"); ok {
+		conf.ListenPort, err = strconv.Atoi(val)
 		if err != nil {
 			return fmt.Errorf("links:list-listen-port must be an integer value")
 		}
 	}
 
-	eSize, gSize, _, err := cmd.LoadWorkerQueueSizes(config)
+	eSize, gSize, _, err := cmd.LoadWorkerQueueSizes(conf)
 	if err != nil {
 		return err
 	}
 
-	db, err := cmd.OpenDB(config)
+	db, err := cmd.OpenDB(conf)
 	if err != nil {
 		return fmt.Errorf("Unable to open connection to PostgreSQL: %v", err)
 	}
@@ -84,7 +84,7 @@ func run() error {
 		Sessions:      true,
 		ServerContext: true,
 	}
-	srv := server.New(e, db, config).
+	srv := server.New(e, db, conf).
 		Initialize().
 		WithAppInfo("links-list", Version).
 		DefaultMiddlewareWithConfig(mwConf).
@@ -100,7 +100,7 @@ func run() error {
 			core.CORSReadOnlyMiddleware,
 		)
 
-	tlsman := cmd.LoadAutoTLS(config, db, models.DomainServiceList)
+	tlsman := cmd.LoadAutoTLS(conf, db, models.DomainServiceList)
 	if tlsman != nil {
 		srv = srv.WithCertManager(tlsman)
 	}
@@ -111,11 +111,11 @@ func run() error {
 
 	srv.AddFuncs(template.FuncMap{
 		"staticURL": func(path string) string {
-			url, _ := url.JoinPath(config.StaticURL, path)
+			url, _ := url.JoinPath(conf.StaticURL, path)
 			return url
 		},
 		"mediaURL": func(path string) string {
-			url, _ := url.JoinPath(config.MediaURL, path)
+			url, _ := url.JoinPath(conf.MediaURL, path)
 			return url
 		},
 		"stripCommonProtocol": func(url string) string {
@@ -140,7 +140,7 @@ func run() error {
 
 	staticHandler := http.FileServer(http.FS(links.StaticFS))
 	e.GET("/static/*", echo.WrapHandler(staticHandler))
-	e.Static(config.MediaURL, "media")
+	e.Static(conf.MediaURL, "media")
 
 	detailService := e.Group("")
 	list.NewDetailService(detailService, links.Render)
diff --git a/cmd/short/main.go b/cmd/short/main.go
index 532e3b8..73e68dc 100644
--- a/cmd/short/main.go
+++ b/cmd/short/main.go
@@ -35,35 +35,35 @@ func main() {
 }
 
 func run() error {
-	config, err := config.LoadConfig("./config.ini")
+	conf, err := config.LoadConfig("./config.ini")
 	if err != nil {
 		return err
 	}
 
-	entropy, ok := config.File.Get("access", "entropy")
+	entropy, ok := conf.File.Get("access", "entropy")
 	if !ok {
 		return fmt.Errorf("No access entropy set. Required value")
 	}
 
-	if val, ok := config.File.Get("links", "short-listen-address"); ok {
+	if val, ok := conf.File.Get("links", "short-listen-address"); ok {
 		if val != "" {
-			config.ListenAddr = val
+			conf.ListenAddr = val
 		}
 	}
 
-	if val, ok := config.File.Get("links", "short-listen-port"); ok {
-		config.ListenPort, err = strconv.Atoi(val)
+	if val, ok := conf.File.Get("links", "short-listen-port"); ok {
+		conf.ListenPort, err = strconv.Atoi(val)
 		if err != nil {
 			return fmt.Errorf("links:short-listen-port must be an integer value")
 		}
 	}
 
-	eSize, gSize, _, err := cmd.LoadWorkerQueueSizes(config)
+	eSize, gSize, _, err := cmd.LoadWorkerQueueSizes(conf)
 	if err != nil {
 		return err
 	}
 
-	db, err := cmd.OpenDB(config)
+	db, err := cmd.OpenDB(conf)
 	if err != nil {
 		return fmt.Errorf("Unable to open connection to PostgreSQL: %v", err)
 	}
@@ -82,7 +82,7 @@ func run() error {
 		Sessions:      false,
 		ServerContext: true,
 	}
-	srv := server.New(e, db, config).
+	srv := server.New(e, db, conf).
 		Initialize().
 		WithAppInfo("links-short", Version).
 		DefaultMiddlewareWithConfig(mwConf).
@@ -98,7 +98,7 @@ func run() error {
 			core.CORSReadOnlyMiddleware,
 		)
 
-	tlsman := cmd.LoadAutoTLS(config, db, models.DomainServiceShort)
+	tlsman := cmd.LoadAutoTLS(conf, db, models.DomainServiceShort)
 	if tlsman != nil {
 		srv = srv.WithCertManager(tlsman)
 	}
@@ -107,7 +107,7 @@ func run() error {
 	short.NewRedirectService(redirectService, links.Render)
 	srv.AddFuncs(template.FuncMap{
 		"staticURL": func(path string) string {
-			url, _ := url.JoinPath(config.StaticURL, path)
+			url, _ := url.JoinPath(conf.StaticURL, path)
 			return url
 		},
 	})
diff --git a/go.mod b/go.mod
index d74e868..fdc028e 100644
--- a/go.mod
+++ b/go.mod
@@ -36,7 +36,7 @@ require (
 	netlandish.com/x/gobwebs v0.1.13
 	netlandish.com/x/gobwebs-auditlog v0.2.10
 	netlandish.com/x/gobwebs-formguard v0.2.11
-	netlandish.com/x/gobwebs-graphql v0.2.11
+	netlandish.com/x/gobwebs-graphql v0.2.12
 	netlandish.com/x/gobwebs-oauth2 v0.2.11
 	netlandish.com/x/gobwebs-ses-feedback v0.2.11
 	petersanchez.com/x/carrier v0.2.4
diff --git a/go.sum b/go.sum
index 548627e..6a97581 100644
--- a/go.sum
+++ b/go.sum
@@ -2588,8 +2588,8 @@ netlandish.com/x/gobwebs-auditlog v0.2.10 h1:dzdY58hdS8nD4J5uir9PzavTohWxxWdRb4q
 netlandish.com/x/gobwebs-auditlog v0.2.10/go.mod h1:TIiP98U0Mlgtn9ivjbDDg1X+Wnt8zq0hC3Ce7exqtlY=
 netlandish.com/x/gobwebs-formguard v0.2.11 h1:/Vc8e1+Wpdd7y8A0wm954w+QOKuOvU6MXwFKXKRARpE=
 netlandish.com/x/gobwebs-formguard v0.2.11/go.mod h1:b8b06b14PJMkeq0gjpwAm8qXDVnvYhT5eulkljBGhlQ=
-netlandish.com/x/gobwebs-graphql v0.2.11 h1:Q0qAco2JfXzj+qYqUTXdf2uNPqqj66mYwjK4GwuzIkQ=
-netlandish.com/x/gobwebs-graphql v0.2.11/go.mod h1:tRfppt6MobMyfgJOhZ2J6Em20X7tGKKTCETeOx/nVvk=
+netlandish.com/x/gobwebs-graphql v0.2.12 h1:C85WwEUB/eEFmW5E8KfUwlWtFTzlzTg/Jy6TFxZ/TKc=
+netlandish.com/x/gobwebs-graphql v0.2.12/go.mod h1:tRfppt6MobMyfgJOhZ2J6Em20X7tGKKTCETeOx/nVvk=
 netlandish.com/x/gobwebs-oauth2 v0.2.11 h1:mI17IoQs8iwLNRtC1lysvMkGShVLNGXyzV96P3eT4n0=
 netlandish.com/x/gobwebs-oauth2 v0.2.11/go.mod h1:7h2MfFMo9EJMLXyCNXAinLEOV9omU0uAT4al7+HcWm4=
 netlandish.com/x/gobwebs-ses-feedback v0.2.11 h1:STbn+kYib8JhFUq8ZVTYoV973ZTmw5NOXObckFqHoI4=
-- 
2.52.0

---

From: "Peter Sanchez" <[email-masked]>
Date: Tue, 26 May 2026 17:57:06 -0600

Applied.

To [email-masked]:~netlandish/links
   41ae80e..50aab15  master -> master