Received: from mail.netlandish.com (mail.netlandish.com [174.136.98.166])
	by code.netlandish.com (Postfix) with ESMTP id 5643D337
	for <~netlandish/links-dev@lists.code.netlandish.com>; Sun, 01 Mar 2026 17:29:55 +0000 (UTC)
Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=209.85.128.177; helo=mail-yw1-f177.google.com; envelope-from=peter@netlandish.com; receiver=<UNKNOWN> 
Authentication-Results: mail.netlandish.com;
	dkim=pass (1024-bit key; unprotected) header.d=netlandish.com header.i=@netlandish.com header.b=V3G8qmrK
Received: from mail-yw1-f177.google.com (mail-yw1-f177.google.com [209.85.128.177])
	by mail.netlandish.com (Postfix) with ESMTP id 622771D6432
	for <~netlandish/links-dev@lists.code.netlandish.com>; Sun, 01 Mar 2026 17:29:53 +0000 (UTC)
Received: by mail-yw1-f177.google.com with SMTP id 00721157ae682-793fdbb8d3aso43212617b3.3
        for <~netlandish/links-dev@lists.code.netlandish.com>; Sun, 01 Mar 2026 09:29:53 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=netlandish.com; s=google; t=1772386192; x=1772990992; darn=lists.code.netlandish.com;
        h=content-transfer-encoding:mime-version:message-id:date:subject:cc
         :to:from:from:to:cc:subject:date:message-id:reply-to;
        bh=OoyVUO7Cit8XbnmTTk8DLJausufih27byxrgS7Zilg4=;
        b=V3G8qmrKglH/waeVaoDWYkyS18soM2M0CbRErYSFs1xJf0e+LSMw7ub5bw5UkxD4Ti
         xGGCk0Sne8u5diz0hOkDRYQpf8ALprVKQC1Qc9HbkJLgCAtUHnBhgu83XclHkSGNOfMr
         yydDYGvTI/fVujaQxOvjvtRb7kkVnYl9HuHuk=
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20230601; t=1772386192; x=1772990992;
        h=content-transfer-encoding:mime-version:message-id:date:subject:cc
         :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date
         :message-id:reply-to;
        bh=OoyVUO7Cit8XbnmTTk8DLJausufih27byxrgS7Zilg4=;
        b=HYuasFkgOOzrIxnvuL1X7/je7YiPznZ2rJd/tfJmdOKXcOdpnzfj62CLQEasqC0BuD
         yQecyfwwsCcO+B4TUeN7D+40i3nmnlS/S5xt53XWQudktm6ATwYXveybuTNPRVqrFdr2
         aX9v9b33FWJnYi6FdbLVmhaGHUKQ8b/HKXmVPGcTvnZasboepJX9wBNaMyjDESEW7thd
         iq5/dxm5zVAoTcb8QDDUVIKAkOQ/TRiqKscglzmhJJGQGHx6KH/KCCCX9yHIDfOUWLfT
         3Qu5K2BW+0WUE7poTuZMiKgolgH8vlF97BykV6E6vuhIKhTBiD9ZlfxIvnBxE5kjW4F0
         HRkQ==
X-Gm-Message-State: AOJu0YwDrhZCUPY9a8P9b4uXOXVDtvvVmO7UcnLZiMiYaI3wVnHtMwav
	3TQUWs5acs7XtvNDSmCfmwyNhUI7AoHro6PFdbguDa0dfMdJyz/q6m2CWIauaOtgxOmx+hLIgRR
	/hbR4j58=
X-Gm-Gg: ATEYQzxlb64FbCyewSG9b7mnRkgZnoDHaDL9mrboeqaAKrE7PP/1AzGfPcSRUWWd9Bq
	g6wB7iPQd+ZA0xuTUIcX2j2hBLSUGB4GtOBSdpeveS+QO8Sg+daV37gLXR9N6mu89QEmtXDo77K
	x8Mq+gJj4NOA9V/0ZrOUkcXnAupKMMJQb4JjIHHHfZSBZRMODPb2uNjBD4FgTaD18NH/I2JhcWg
	1JzuaO2NVOuyrKL7+t7Lohowv24AKXC9E/6EtjtG8O95vjA/dTDaInLVt4Pc+J8dShN1O43uUzm
	Tg1bQRW6/JTKcdGUkTY0MD3pI/B/B6viHIkOMW8tzkkrKGLAcV8uV1zwUbtWaKRbYZ6xrELLOVH
	u2gwzFrvTWnTysJbmIRoOUtB9QhlZTg+JI6aVybvyNg5qGbM8v/MR5IlLz4j1JQN2tVxMfgo66G
	Hc9iRNPvz5T7Sid5JCPVG9EqFS
X-Received: by 2002:a05:690c:101:b0:798:6944:a033 with SMTP id 00721157ae682-7988562344fmr89116597b3.55.1772386192249;
        Sun, 01 Mar 2026 09:29:52 -0800 (PST)
Received: from localhost ([2803:2d60:1107:87f:6ab5:5dce:75b0:ccfd])
        by smtp.gmail.com with ESMTPSA id 00721157ae682-79876af20ebsm42579687b3.22.2026.03.01.09.29.51
        (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
        Sun, 01 Mar 2026 09:29:51 -0800 (PST)
From: Peter Sanchez <peter@netlandish.com>
To: ~netlandish/links-dev@lists.code.netlandish.com
Cc: Peter Sanchez <peter@netlandish.com>
Subject: [PATCH links] api: getDomains return system domains if no org slug is specifically specified.
Date: Sun,  1 Mar 2026 11:29:44 -0600
Message-ID: <20260301172947.29644-1-peter@netlandish.com>
X-Mailer: git-send-email 2.52.0
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit

Also fix issue when referencing a short link short code before
verification that it was sent to the backend.

Changelog-updated: getDomains to return system domains when no
 organization slug is passed.
Changelog-updated: API version bumped to 0.10.3
Changelog-fixed: bug when shortCode is referenced before verification
 that it was passed
---
 api/graph/schema.resolvers.go | 35 +++++++++++++++++++++++++----------
 1 file changed, 25 insertions(+), 10 deletions(-)

diff --git a/api/graph/schema.resolvers.go b/api/graph/schema.resolvers.go
index 120051b..aab1ba5 100644
--- a/api/graph/schema.resolvers.go
+++ b/api/graph/schema.resolvers.go
@@ -33,6 +33,7 @@ import (
 	"time"
 
 	sq "github.com/Masterminds/squirrel"
+	"github.com/microcosm-cc/bluemonday"
 	"github.com/segmentio/ksuid"
 	qrcode "github.com/yeqown/go-qrcode/v2"
 	"github.com/yeqown/go-qrcode/writer/standard"
@@ -42,7 +43,6 @@ import (
 	auditlog "netlandish.com/x/gobwebs-auditlog"
 	oauth2 "netlandish.com/x/gobwebs-oauth2"
 	gaccounts "netlandish.com/x/gobwebs/accounts"
-	"github.com/microcosm-cc/bluemonday"
 	"netlandish.com/x/gobwebs/crypto"
 	"netlandish.com/x/gobwebs/database"
 	"netlandish.com/x/gobwebs/email"
@@ -2299,13 +2299,14 @@ func (r *mutationResolver) AddLinkShort(ctx context.Context, input *model.LinkSh
 			"%s", lt.Translate("Short Code may not exceed 20 characters")).
 			WithField("shortCode").
 			WithCode(valid.ErrValidationCode)
-	}
-	b := &gaccounts.BlacklistValidator{}
-	if !b.UsernameSafePlus(links.InvalidSlugs, *input.ShortCode) {
-		validator.Error("%s", lt.Translate("This shortCode can not be used. Please chose another one")).
-			WithField("shortCode").
-			WithCode(valid.ErrValidationCode)
-		return nil, nil
+
+		b := &gaccounts.BlacklistValidator{}
+		if !b.UsernameSafePlus(links.InvalidSlugs, *input.ShortCode) {
+			validator.Error("%s", lt.Translate("This shortCode can not be used. Please chose another one")).
+				WithField("shortCode").
+				WithCode(valid.ErrValidationCode)
+			return nil, nil
+		}
 	}
 
 	tags := make([]string, 0)
@@ -5126,7 +5127,7 @@ func (r *queryResolver) Version(ctx context.Context) (*model.Version, error) {
 	return &model.Version{
 		Major:           0,
 		Minor:           10,
-		Patch:           2,
+		Patch:           3,
 		DeprecationDate: nil,
 	}, nil
 }
@@ -5906,7 +5907,10 @@ func (r *queryResolver) GetDomains(ctx context.Context, orgSlug *string, service
 
 	ctx = timezone.Context(ctx, links.GetUserTZ(user))
 
-	var org *models.Organization
+	var (
+		org     *models.Organization
+		orgSent bool
+	)
 	orgs, err := user.GetOrgs(ctx, models.OrgUserPermissionRead)
 	if err != nil {
 		return nil, err
@@ -5920,6 +5924,7 @@ func (r *queryResolver) GetDomains(ctx context.Context, orgSlug *string, service
 			}
 		}
 	} else {
+		orgSent = true
 		for _, o := range orgs {
 			if o.Slug == *orgSlug {
 				org = o
@@ -5939,6 +5944,16 @@ func (r *queryResolver) GetDomains(ctx context.Context, orgSlug *string, service
 	opts := &database.FilterOptions{
 		Filter: sq.Eq{"d.org_id": org.ID},
 	}
+	if !orgSent {
+		// If no organization is specified then include system level domains as well
+		opts.Filter = sq.Or{
+			opts.Filter,
+			sq.And{
+				sq.Eq{"d.org_id": nil},
+				sq.Eq{"d.level": models.DomainLevelSystem},
+			},
+		}
+	}
 	if service != nil {
 		opts.Filter = sq.And{
 			opts.Filter,
-- 
2.52.0

