feat: install code of 3 to 24 letters and digits with a button to make a new one; guesses are limited per address

This commit is contained in:
redtea committed 2026-10-14 21:07:36 +03:00
1 parent 47f1b2e55b
commit 29353e5e6a
4 files changed
+71 -12

No files matched your search

+32 -11
View File
@@ -14,6 +14,7 @@ const (
cfgEnrollSecret = "enroll_secret"
cfgSetupDone = "setup_done"
cfgInstallCode = "install_code"
cfgInstallLen = "install_code_len"
cfgUfwEnabled = "ufw_enabled"
cfgTunnelHost = "tunnel_host"
cfgTunnelPort = "tunnel_port"
@@ -52,7 +53,7 @@ func (db *DB) ensureDefaults() error {
return err
}
if code == "" {
if err := db.SetConfig(cfgInstallCode, shortCode()); err != nil {
if err := db.SetConfig(cfgInstallCode, shortCode(db.InstallCodeLen())); err != nil {
return err
}
}
@@ -125,16 +126,36 @@ func randToken() string {
return hex.EncodeToString(b)
}
// shortCode returns a short, URL-safe, typo-resistant code for install links.
// It avoids ambiguous characters (0/O, 1/l/I) so it is easy to read and type.
func shortCode() string {
const alphabet = "abcdefghjkmnpqrstuvwxyz23456789"
b := make([]byte, 7)
if _, err := rand.Read(b); err != nil {
panic("crypto/rand failed: " + err.Error())
// Install code length: 3 by default, up to 24.
const (
installCodeMin = 3
installCodeMax = 24
installCodeDef = 3
)
// InstallCodeLen is how many characters a new install code has.
func (db *DB) InstallCodeLen() int {
v, _ := db.GetConfig(cfgInstallLen)
if n, err := strconv.Atoi(v); err == nil && n >= installCodeMin && n <= installCodeMax {
return n
}
for i := range b {
b[i] = alphabet[int(b[i])%len(alphabet)]
return installCodeDef
}
// shortCode returns a random code of n English letters and digits for the
// /i/<code> install link. Every character is equally likely.
func shortCode(n int) string {
const alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
out := make([]byte, 0, n)
b := make([]byte, 1)
for len(out) < n {
if _, err := rand.Read(b); err != nil {
panic("crypto/rand failed: " + err.Error())
}
// 248 = 4 * 62: drop the rest, so no character comes up more often.
if b[0] < 248 {
out = append(out, alphabet[int(b[0])%len(alphabet)])
}
}
return string(b)
return string(out)
}