package auth import ( "context" "github.com/Timothylock/go-signin-with-apple/apple" "gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/encryption" "gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/errors" "gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/string_utils" "google.golang.org/api/idtoken" ) type AppleAuth struct { Code string `json:"code"` IDToken string `json:"id_token"` State string `json:"state"` } type SocialCredentials struct { Google string `json:"google"` Apple *AppleAuth `json:"apple"` } type LoginResponse struct { AccessToken string `json:"access_token"` } func ValidateGoogleIDToken(tokenString, clientID string) (string, error) { payload, err := idtoken.Validate(context.Background(), tokenString, clientID) if err != nil { return "", err } email, ok := payload.Claims["email"].(string) if !ok { return "", errors.Error("email is not a string") } return email, nil } func ValidateAppleCode(code, redirectURI, encryptionKeySecret string, isDebug bool) (string, error) { teamID := "7978M5K9YV" clientID := "za.co.bob.auth.client" keyID := "6X88ZTK5S4" signingKey, err := encryption.GetAppleSigningKey(encryptionKeySecret, isDebug) if err != nil { return "", errors.Error("apple signing key not set up") } clientSecret, err := apple.GenerateClientSecret(signingKey, teamID, clientID, keyID) if err != nil { return "", err } client := apple.New() var validationResponse apple.ValidationResponse err = client.VerifyWebToken(context.Background(), apple.WebValidationTokenRequest{ ClientID: clientID, ClientSecret: clientSecret, RedirectURI: redirectURI, Code: code, }, &validationResponse) if err != nil { return "", err } if validationResponse.ErrorDescription != "" { panic(validationResponse.ErrorDescription) } claim, _ := apple.GetClaims(validationResponse.IDToken) if claim == nil { return "", errors.Error("invalid apple token") } email := (*claim)["email"] emailVerified := (*claim)["email_verified"] if emailVerified != true { return "", errors.Error("email not verified") } return string_utils.InterfaceToString(email) } func ExtractAppleEmailFromIDToken(idToken string) (string, error) { claim, err := apple.GetClaims(idToken) if err != nil { return "", err } email := (*claim)["email"] emailVerified := (*claim)["email_verified"] if emailVerified != true { return "", errors.Error("email not verified") } return string_utils.InterfaceToString(email) } func HasSocialCredentials(socialCredentials SocialCredentials) bool { return socialCredentials.Google != "" || (socialCredentials.Apple != nil && socialCredentials.Apple.IDToken != "" && socialCredentials.Apple.Code != "") }