arblant
firefox-vpn-client / core / internal / fxa / normalize.go
normalize.go46 lines · 1.3 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
package fxa

import (
	"strings"
	"unicode"
)

// NormalizeCode cleans a code a person typed or pasted (an emailed
// verification code, an authenticator code, an unblock code): Persian and
// Arabic-Indic digits become ASCII digits, and spaces and invisible
// characters (a zero-width non-joiner, direction marks, a byte-order mark
// from a paste) are dropped. Mozilla accepts only the plain form.
func NormalizeCode(code string) string {
	var b strings.Builder
	for _, r := range code {
		switch {
		case r >= '۰' && r <= '۹': // Persian digits
			b.WriteRune('0' + r - '۰')
		case r >= '٠' && r <= '٩': // Arabic-Indic digits
			b.WriteRune('0' + r - '٠')
		case invisible(r):
		default:
			b.WriteRune(r)
		}
	}
	return b.String()
}

// NormalizeEmail drops spaces and invisible characters from an email a
// person typed or pasted. It does not change letter case: the address is
// part of the password's key derivation, as Mozilla's own clients send it.
func NormalizeEmail(email string) string {
	var b strings.Builder
	for _, r := range email {
		if !invisible(r) {
			b.WriteRune(r)
		}
	}
	return b.String()
}

// invisible reports spaces and format characters (Cf: zero-width joiners,
// direction marks, the byte-order mark).
func invisible(r rune) bool {
	return unicode.IsSpace(r) || unicode.Is(unicode.Cf, r) || unicode.Is(unicode.Zs, r)
}