feat: sync Telegram Login OIDC provider
This commit is contained in:
parent
30774f8c39
commit
ebead9e98c
63 changed files with 11374 additions and 37 deletions
80
internal/app/telegramlogin/native.go
Normal file
80
internal/app/telegramlogin/native.go
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
package telegramlogin
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"telesrv/internal/domain"
|
||||
)
|
||||
|
||||
var nativeApplicationIDPattern = regexp.MustCompile(`^[A-Za-z0-9][A-Za-z0-9._-]{2,254}$`)
|
||||
|
||||
func normalizeNativeApplicationID(raw string) (string, error) {
|
||||
raw = strings.TrimSpace(raw)
|
||||
if !nativeApplicationIDPattern.MatchString(raw) || !strings.Contains(raw, ".") || strings.Contains(raw, "..") {
|
||||
return "", domain.ErrTelegramLoginClientInvalid
|
||||
}
|
||||
return raw, nil
|
||||
}
|
||||
|
||||
func normalizeNativeVerificationID(platform domain.TelegramLoginNativePlatform, raw string) (string, error) {
|
||||
raw = strings.ToUpper(strings.TrimSpace(raw))
|
||||
switch platform {
|
||||
case domain.TelegramLoginNativeIOS:
|
||||
if len(raw) != 10 || strings.IndexFunc(raw, func(r rune) bool {
|
||||
return !((r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9'))
|
||||
}) >= 0 {
|
||||
return "", domain.ErrTelegramLoginClientInvalid
|
||||
}
|
||||
case domain.TelegramLoginNativeAndroid:
|
||||
raw = strings.ReplaceAll(raw, ":", "")
|
||||
if len(raw) != 64 || strings.IndexFunc(raw, func(r rune) bool {
|
||||
return !((r >= 'A' && r <= 'F') || (r >= '0' && r <= '9'))
|
||||
}) >= 0 {
|
||||
return "", domain.ErrTelegramLoginClientInvalid
|
||||
}
|
||||
default:
|
||||
return "", domain.ErrTelegramLoginClientInvalid
|
||||
}
|
||||
return raw, nil
|
||||
}
|
||||
|
||||
// NormalizeNativeCallbackURI accepts the exact HTTPS universal/app link or a
|
||||
// non-web custom scheme registered for a native application. Query and
|
||||
// fragment components are forbidden because OAuth response fields are
|
||||
// appended by the provider and must not collide with application input.
|
||||
func NormalizeNativeCallbackURI(raw string, allowLoopbackHTTP bool) (string, error) {
|
||||
if raw == "" || len(raw) > maxTelegramLoginURLLength || raw != strings.TrimSpace(raw) || strings.IndexFunc(raw, unicode.IsControl) >= 0 {
|
||||
return "", domain.ErrTelegramLoginURLInvalid
|
||||
}
|
||||
u, err := url.Parse(raw)
|
||||
if err != nil || !u.IsAbs() || u.Opaque != "" || u.User != nil || u.Host == "" || u.RawQuery != "" || u.Fragment != "" || u.RawPath != "" {
|
||||
return "", domain.ErrTelegramLoginURLInvalid
|
||||
}
|
||||
if strings.EqualFold(u.Scheme, "http") || strings.EqualFold(u.Scheme, "https") {
|
||||
normalized, _, err := NormalizeRedirectURI(raw, allowLoopbackHTTP)
|
||||
return normalized, err
|
||||
}
|
||||
scheme := strings.ToLower(u.Scheme)
|
||||
if !validAppScheme(scheme) || scheme == "tg" || scheme == "javascript" || scheme == "data" || scheme == "file" || u.Port() != "" {
|
||||
return "", domain.ErrTelegramLoginURLInvalid
|
||||
}
|
||||
host := strings.ToLower(strings.TrimSuffix(u.Hostname(), "."))
|
||||
if host == "" || strings.IndexFunc(host, func(r rune) bool {
|
||||
return !((r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '-' || r == '.')
|
||||
}) >= 0 {
|
||||
return "", domain.ErrTelegramLoginURLInvalid
|
||||
}
|
||||
u.Scheme, u.Host = scheme, host
|
||||
return u.String(), nil
|
||||
}
|
||||
|
||||
func normalizeNativeDisplayName(raw string) (string, error) {
|
||||
raw = strings.TrimSpace(raw)
|
||||
if raw == "" || len(raw) > 128 || strings.IndexFunc(raw, unicode.IsControl) >= 0 {
|
||||
return "", domain.ErrTelegramLoginClientInvalid
|
||||
}
|
||||
return raw, nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue