Skip to content

Commit 0260767

Browse files
Merge pull request #369 from supertokens/twitter-provider
feat: Add twitter provider to third party recipe
2 parents caab7e8 + 042eaee commit 0260767

File tree

3 files changed

+93
-0
lines changed

3 files changed

+93
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
## [0.15.0] - 2023-09-26
1111

12+
- Adds Twitter/X as a default provider to the third party recipe
1213
- Added a `Cache-Control` header to `/jwt/jwks.json` (`GetJWKSGET`)
1314
- Added `ValidityInSeconds` to the return value of the overrideable `GetJWKS` function.
1415
- This can be used to control the `Cache-Control` header mentioned above.

recipe/thirdparty/providers/config_utils.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ func createProvider(input tpmodels.ProviderInput) *tpmodels.TypeProvider {
7575
return Linkedin(input)
7676
} else if strings.HasPrefix(input.Config.ThirdPartyId, "boxy-saml") {
7777
return BoxySaml(input)
78+
} else if strings.HasPrefix(input.Config.ThirdPartyId, "twitter") {
79+
return Twitter(input)
7880
}
7981

8082
return NewProvider(input)
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package providers
2+
3+
import (
4+
"encoding/base64"
5+
"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
6+
"github.com/supertokens/supertokens-golang/supertokens"
7+
)
8+
9+
func Twitter(input tpmodels.ProviderInput) *tpmodels.TypeProvider {
10+
if input.Config.Name == "" {
11+
input.Config.Name = "Twitter"
12+
}
13+
14+
if input.Config.AuthorizationEndpoint == "" {
15+
input.Config.AuthorizationEndpoint = "https://twitter.com/i/oauth2/authorize"
16+
}
17+
18+
if input.Config.TokenEndpoint == "" {
19+
input.Config.TokenEndpoint = "https://api.twitter.com/2/oauth2/token"
20+
}
21+
22+
if input.Config.UserInfoEndpoint == "" {
23+
input.Config.UserInfoEndpoint = "https://api.twitter.com/2/users/me"
24+
}
25+
26+
if input.Config.RequireEmail == nil {
27+
False := false
28+
input.Config.RequireEmail = &False
29+
}
30+
31+
if input.Config.UserInfoMap.FromUserInfoAPI.UserId == "" {
32+
input.Config.UserInfoMap.FromUserInfoAPI.UserId = "data.id"
33+
}
34+
35+
oOverride := input.Override
36+
37+
input.Override = func(originalImplementation *tpmodels.TypeProvider) *tpmodels.TypeProvider {
38+
oGetConfig := originalImplementation.GetConfigForClientType
39+
originalImplementation.GetConfigForClientType = func(clientType *string, userContext supertokens.UserContext) (tpmodels.ProviderConfigForClientType, error) {
40+
config, err := oGetConfig(clientType, userContext)
41+
if err != nil {
42+
return tpmodels.ProviderConfigForClientType{}, err
43+
}
44+
45+
if len(config.Scope) == 0 {
46+
config.Scope = []string{"users.read", "tweet.read"}
47+
}
48+
49+
if config.ForcePKCE == nil {
50+
True := true
51+
config.ForcePKCE = &True
52+
}
53+
54+
return config, nil
55+
}
56+
57+
originalImplementation.ExchangeAuthCodeForOAuthTokens = func(redirectURIInfo tpmodels.TypeRedirectURIInfo, userContext supertokens.UserContext) (tpmodels.TypeOAuthTokens, error) {
58+
basicAuthToken := base64.StdEncoding.EncodeToString([]byte(originalImplementation.Config.ClientID + ":" + originalImplementation.Config.ClientSecret))
59+
twitterOauthParams := map[string]interface{}{}
60+
61+
if originalImplementation.Config.TokenEndpointBodyParams != nil {
62+
twitterOauthParams = originalImplementation.Config.TokenEndpointBodyParams
63+
}
64+
65+
codeVerifier := ""
66+
67+
if redirectURIInfo.PKCECodeVerifier != nil {
68+
codeVerifier = *redirectURIInfo.PKCECodeVerifier
69+
}
70+
71+
twitterOauthParams["grant_type"] = "authorization_code"
72+
twitterOauthParams["client_id"] = originalImplementation.Config.ClientID
73+
twitterOauthParams["code_verifier"] = codeVerifier
74+
twitterOauthParams["redirect_uri"] = redirectURIInfo.RedirectURIOnProviderDashboard
75+
twitterOauthParams["code"] = redirectURIInfo.RedirectURIQueryParams["code"]
76+
77+
return doPostRequest(originalImplementation.Config.TokenEndpoint, twitterOauthParams, map[string]interface{}{
78+
"Authorization": "Basic " + basicAuthToken,
79+
})
80+
}
81+
82+
if oOverride != nil {
83+
originalImplementation = oOverride(originalImplementation)
84+
}
85+
86+
return originalImplementation
87+
}
88+
89+
return NewProvider(input)
90+
}

0 commit comments

Comments
 (0)