From c1cac4ece9f4a95e1c555305ca9dd29b6cedc292 Mon Sep 17 00:00:00 2001 From: RXWatcher Date: Mon, 3 Aug 2026 18:41:51 +0200 Subject: [PATCH] fix(auth): bound device match codes to eight letters (#535) * fix(auth): bound device match codes to eight letters * fix(auth): use farm-themed device match codes --------- Co-authored-by: rxwatcher Co-authored-by: Quick104 <31828688+Quick104@users.noreply.github.com> --- internal/auth/device_login_words.go | 20 +++++--------------- internal/auth/device_login_words_test.go | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 internal/auth/device_login_words_test.go diff --git a/internal/auth/device_login_words.go b/internal/auth/device_login_words.go index af3e543c..94a60949 100644 --- a/internal/auth/device_login_words.go +++ b/internal/auth/device_login_words.go @@ -6,24 +6,14 @@ import ( ) var deviceMatchAdjectives = []string{ - "amber", "brisk", "calm", "cedar", "clear", "cloud", "copper", "crisp", - "delta", "ember", "fable", "fern", "frost", "gentle", "golden", "harbor", - "hazel", "hollow", "indigo", "ivy", "jade", "juniper", "kindle", "lagoon", - "linen", "lunar", "maple", "meadow", "misty", "navy", "nova", "oak", - "olive", "opal", "orbit", "pepper", "pine", "plum", "prairie", "quiet", - "raven", "river", "rose", "rustic", "sable", "sage", "scarlet", "silver", - "smoky", "solstice", "spruce", "stone", "summer", "sunny", "timber", "topaz", - "velvet", "violet", "willow", "winter", "woodland", "zephyr", + "blue", "busy", "calm", "cozy", "fast", "gold", + "kind", "soft", "tall", "tame", "tiny", "warm", } var deviceMatchNouns = []string{ - "anchor", "apple", "birch", "brook", "canyon", "castle", "comet", "cove", - "crest", "dawn", "ember", "field", "fjord", "forest", "glade", "grove", - "harbor", "hawk", "hill", "island", "lake", "lantern", "meadow", "mesa", - "moon", "oasis", "ocean", "orchard", "owl", "pine", "planet", "pond", - "quartz", "rain", "reef", "ridge", "river", "rock", "shadow", "shore", - "signal", "snow", "spark", "star", "stone", "stream", "summit", "sun", - "thunder", "trail", "tree", "valley", "wave", "whisper", "wind", "wolf", + "barn", "bell", "cart", "coop", "corn", "cow", "duck", "goat", + "hay", "hen", "lamb", "milk", "oats", "pail", "pond", "pony", + "rake", "shed", "silo", "wool", } func randomMatchCode() (string, error) { diff --git a/internal/auth/device_login_words_test.go b/internal/auth/device_login_words_test.go new file mode 100644 index 00000000..65a5fbc8 --- /dev/null +++ b/internal/auth/device_login_words_test.go @@ -0,0 +1,21 @@ +package auth + +import "testing" + +func TestDeviceMatchCodeWordsStayWithinEightLetters(t *testing.T) { + const maxLetters = 8 + const wantCombinations = 240 + for _, adjective := range deviceMatchAdjectives { + for _, noun := range deviceMatchNouns { + if got := len(adjective) + len(noun); got > maxLetters { + t.Fatalf("match code %q has %d letters, want at most %d", adjective+" "+noun, got, maxLetters) + } + } + } + + // The match phrase is a human confirmation signal, not the login secret, + // but keep enough combinations that accidental collisions remain uncommon. + if combinations := len(deviceMatchAdjectives) * len(deviceMatchNouns); combinations != wantCombinations { + t.Fatalf("match-code word lists have %d combinations, want exactly %d", combinations, wantCombinations) + } +}