@@ -48,10 +48,10 @@ func (s Session) Marshal() string {
4848
4949type IDTokenClaims struct {
5050 jwt.StandardClaims
51- AccessTokenHash string `json:"at_hash"`
52- AuthTime int `json:"auth_time"`
53- Email string `json:"email"`
54- IsPrivateEmail bool `json:"is_private_email,string "`
51+ AccessTokenHash string `json:"at_hash"`
52+ AuthTime int `json:"auth_time"`
53+ Email string `json:"email"`
54+ IsPrivateEmail BoolString `json:"is_private_email"`
5555}
5656
5757func (s * Session ) Authorize (provider goth.Provider , params goth.Params ) (string , error ) {
@@ -123,7 +123,7 @@ func (s *Session) Authorize(provider goth.Provider, params goth.Params) (string,
123123 s .ID = ID {
124124 Sub : idToken .Claims .(* IDTokenClaims ).Subject ,
125125 Email : idToken .Claims .(* IDTokenClaims ).Email ,
126- IsPrivateEmail : idToken .Claims .(* IDTokenClaims ).IsPrivateEmail ,
126+ IsPrivateEmail : idToken .Claims .(* IDTokenClaims ).IsPrivateEmail . Value () ,
127127 }
128128 }
129129
@@ -133,3 +133,36 @@ func (s *Session) Authorize(provider goth.Provider, params goth.Params) (string,
133133func (s Session ) String () string {
134134 return s .Marshal ()
135135}
136+
137+ // BoolString is a type that can be unmarshalled from a JSON field that can be either a boolean or a string.
138+ // It is used to unmarshal some fields in the Apple ID token that can be sent as either boolean or string.
139+ // See https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api/authenticating_users_with_sign_in_with_apple#3383773
140+ type BoolString struct {
141+ BoolValue bool
142+ StringValue string
143+ IsValidBool bool
144+ }
145+
146+ func (bs * BoolString ) UnmarshalJSON (data []byte ) error {
147+ var b bool
148+ if err := json .Unmarshal (data , & b ); err == nil {
149+ bs .BoolValue = b
150+ bs .IsValidBool = true
151+ return nil
152+ }
153+
154+ var s string
155+ if err := json .Unmarshal (data , & s ); err == nil {
156+ bs .StringValue = s
157+ return nil
158+ }
159+
160+ return errors .New ("json field can be either boolean or string" )
161+ }
162+
163+ func (bs * BoolString ) Value () bool {
164+ if bs .IsValidBool {
165+ return bs .BoolValue
166+ }
167+ return bs .StringValue == "true"
168+ }
0 commit comments