-
Notifications
You must be signed in to change notification settings - Fork 114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: added support for turnstile verification on signup #568
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
770e60f
feat: added support for turnstile verification on signup
dbarrosop 4165905
asd
dbarrosop 0713fd7
asd
dbarrosop 201ec95
Merge branch 'main' into turnstile
dbarrosop 24ee672
asd
dbarrosop 941ead5
sad
dbarrosop 2c49288
asd
dbarrosop File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
--- | ||
name: "gen: AI review" | ||
on: | ||
pull_request: | ||
types: [opened, reopened, ready_for_review] | ||
issue_comment: | ||
jobs: | ||
pr_agent_job: | ||
if: ${{ github.event.sender.type != 'Bot' }} | ||
runs-on: ubuntu-latest | ||
timeout-minutes: 10 | ||
permissions: | ||
issues: write | ||
pull-requests: write | ||
contents: write | ||
name: Run pr agent on every pull request, respond to user comments | ||
steps: | ||
- name: PR Agent action step | ||
id: pragent | ||
uses: Codium-ai/[email protected] | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
OPENAI_KEY: ${{ secrets.OPENAI_API_KEY }} | ||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} | ||
config.max_model_tokens: 100000 | ||
config.model: "anthropic/claude-3-5-sonnet-20240620" | ||
config.model_turbo: "anthropic/claude-3-5-sonnet-20240620" | ||
config.ignore.glob: "['vendor/**','**/client_gen.go','**/models_gen.go','**/generated.go','**/*.gen.go']" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Sign Up Form</title> | ||
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script> | ||
<style> | ||
body { | ||
font-family: Arial, sans-serif; | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
height: 100vh; | ||
margin: 0; | ||
background-color: #f0f0f0; | ||
} | ||
form { | ||
background-color: white; | ||
padding: 20px; | ||
border-radius: 8px; | ||
box-shadow: 0 0 10px rgba(0,0,0,0.1); | ||
} | ||
input { | ||
display: block; | ||
width: 100%; | ||
margin-bottom: 10px; | ||
padding: 8px; | ||
border: 1px solid #ddd; | ||
border-radius: 4px; | ||
} | ||
button { | ||
width: 100%; | ||
padding: 10px; | ||
background-color: #007bff; | ||
color: white; | ||
border: none; | ||
border-radius: 4px; | ||
cursor: pointer; | ||
} | ||
button:hover { | ||
background-color: #0056b3; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<form id="signupForm"> | ||
<h2>Sign Up</h2> | ||
<input type="email" id="email" placeholder="Email" required> | ||
<input type="password" id="password" placeholder="Password" required> | ||
<div class="cf-turnstile" data-sitekey="FIXME"></div> | ||
<button type="submit">Sign Up</button> | ||
</form> | ||
|
||
<script> | ||
document.getElementById('signupForm').addEventListener('submit', async function(e) { | ||
e.preventDefault(); | ||
|
||
const email = document.getElementById('email').value; | ||
const password = document.getElementById('password').value; | ||
const turnstileResponse = turnstile.getResponse(); | ||
|
||
if (!turnstileResponse) { | ||
alert('Please complete the Turnstile challenge.'); | ||
return; | ||
} | ||
|
||
try { | ||
const response = await fetch('http://localhost:4000/signup/email-password', { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
'x-cf-turnstile-response': turnstileResponse, | ||
}, | ||
body: JSON.stringify({ | ||
email, | ||
password, | ||
}), | ||
}); | ||
|
||
if (response.ok) { | ||
alert('Sign up successful!'); | ||
// Optionally, redirect the user or clear the form | ||
} else { | ||
const errorData = await response.json(); | ||
alert(`Sign up failed: ${errorData.message || 'Unknown error'}`); | ||
} | ||
} catch (error) { | ||
console.error('Error:', error); | ||
alert('An error occurred. Please try again.'); | ||
} | ||
}); | ||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
events { | ||
worker_connections 1024; | ||
} | ||
|
||
http { | ||
server { | ||
listen 443 ssl; | ||
server_name localhost; | ||
|
||
ssl_certificate /etc/nginx/ssl/nginx-selfsigned.crt; | ||
ssl_certificate_key /etc/nginx/ssl/nginx-selfsigned.key; | ||
|
||
ssl_protocols TLSv1.2 TLSv1.3; | ||
ssl_prefer_server_ciphers on; | ||
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384; | ||
|
||
location / { | ||
root /usr/share/nginx/html; | ||
index index.html; | ||
|
||
add_header 'Access-Control-Allow-Origin' 'https://challenges.cloudflare.com'; | ||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; | ||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; | ||
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; | ||
|
||
|
||
add_header Content-Security-Policy "default-src 'self'; frame-src 'self' https://challenges.cloudflare.com; frame-ancestors 'self' https://challenges.cloudflare.com; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://challenges.cloudflare.com; style-src 'self' 'unsafe-inline' https://challenges.cloudflare.com; img-src 'self' data: https:; font-src 'self' https:; connect-src 'self' http://localhost:4000 https://challenges.cloudflare.com;"; | ||
|
||
if ($request_method = 'OPTIONS') { | ||
add_header 'Access-Control-Allow-Origin' 'https://challenges.cloudflare.com'; | ||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; | ||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; | ||
add_header 'Access-Control-Max-Age' 1728000; | ||
add_header 'Content-Type' 'text/plain; charset=utf-8'; | ||
add_header 'Content-Length' 0; | ||
return 204; | ||
} | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
-----BEGIN CERTIFICATE----- | ||
MIIDSDCCAjACCQDGV/un6TjVazANBgkqhkiG9w0BAQsFADBmMQswCQYDVQQGEwJV | ||
UzEOMAwGA1UECAwFU3RhdGUxDTALBgNVBAcMBENpdHkxFTATBgNVBAoMDE9yZ2Fu | ||
aXphdGlvbjENMAsGA1UECwwEVW5pdDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI0 | ||
MDkyNTA4MTA0NVoXDTI1MDkyNTA4MTA0NVowZjELMAkGA1UEBhMCVVMxDjAMBgNV | ||
BAgMBVN0YXRlMQ0wCwYDVQQHDARDaXR5MRUwEwYDVQQKDAxPcmdhbml6YXRpb24x | ||
DTALBgNVBAsMBFVuaXQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN | ||
AQEBBQADggEPADCCAQoCggEBAMLzWZAlYj7FMsBHFbiRPNebUTYiVmDiyH/Yk/eG | ||
JhS4Rpw2UjI9LpBgGOJKrPRAD14KBjNHJSSTVrPV6l2kdsugDJDwDUhWlRxng1+Z | ||
zP6MNB9WME6wOFxiUARHumHaABqd/8zY4Ws1DJbPgyXgARmv+2PaeFMOrTsBn70N | ||
Og5s7JZC0V9u7vRxsbrmmWiq9Ew3GOO3RnPg+6gmrxQEo2K85h0npOeCRtP3zfd+ | ||
pAUnujstk+75gqAEPlkf+DrUmg8opd4CquoRg2dVai2YwIdvtMqE0SWgZs/wbaOg | ||
gATdOtp8T8YKuyTZ7cTnQRHZJFVMkzfZ6/WCLcysHgtItTMCAwEAATANBgkqhkiG | ||
9w0BAQsFAAOCAQEAXIDN3YBDj+QF+L1F1PlV54/hUv3vXoU35hTfKLu09k76n7wD | ||
pYLHj7/pdZtuqt+0PCllfGBXnCMMtFeH+ZSUZciSinoDg4fpUUT9BnhUVr9MvESu | ||
1fa64aYsOY9KYi8I9LpdIYs3DfpVuAKxFOOW2vH54+HaZMKfGH3ZZKQ8QL+KZzk4 | ||
zxaCkl2jCFwD2cCuvc/wu5EBGcjkv429eapFp/8lXqv9YbiW2833t0r4rkEUroP1 | ||
Dbm+kf6AUt7tm5AkxvRmbtKjQ8l5kB+GnHVMo+eltmesb8HHMYJqOBbIOTOUz6b8 | ||
uPJWrTgLvYT2El87a3pFL2XP4PkV9igakf94gg== | ||
-----END CERTIFICATE----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
-----BEGIN PRIVATE KEY----- | ||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDC81mQJWI+xTLA | ||
RxW4kTzXm1E2IlZg4sh/2JP3hiYUuEacNlIyPS6QYBjiSqz0QA9eCgYzRyUkk1az | ||
1epdpHbLoAyQ8A1IVpUcZ4Nfmcz+jDQfVjBOsDhcYlAER7ph2gAanf/M2OFrNQyW | ||
z4Ml4AEZr/tj2nhTDq07AZ+9DToObOyWQtFfbu70cbG65ploqvRMNxjjt0Zz4Puo | ||
Jq8UBKNivOYdJ6TngkbT9833fqQFJ7o7LZPu+YKgBD5ZH/g61JoPKKXeAqrqEYNn | ||
VWotmMCHb7TKhNEloGbP8G2joIAE3TrafE/GCrsk2e3E50ER2SRVTJM32ev1gi3M | ||
rB4LSLUzAgMBAAECggEAHnzCD+nYwGpEco9rVS7ZbfprK+UYzxQIOP4cvcPr5qee | ||
20Ufe53Xz1pH6fO1sojmHlXA/Hnu1BZ6o6sbeMOElHmWHYB9A0gPD58ci3HY/iHc | ||
8N2gtl2WotP5IYI6Ip1eEMuOunFcZ1CnhFo1b1HluiesT8RVtt9/tc+eNImB/8lA | ||
/FFGn6/Q78xeS9MbwFEpEXgEaBX3DKEcmfwcvu5fDpc12koYWenLGTor16fepJ5a | ||
rFI64yCxDAg3A0mRdiY6RlgmFvqlm9J3BdO+np/GrE4QkrmE78LuX8mToMwnE8Q9 | ||
vZeh731WNv2EzJsewy+ayyh/RIEH5PUAgVt+qLP+AQKBgQDujnQzgoBEgA7XTTiz | ||
w6I90lvFxw3DR7ptc4ai79gz/cTzoJoIGpcjI2cyDpcGL5RuBh06L8Y64NVQxp29 | ||
jnGFt9Hil/2ZomYlCnc3OUiaTQZnn98k4jPsLNwB8Ng+AZYHMVuJ2qut2x0KDUz2 | ||
e6F/N7h5VGjLFZnM1w80T3TIMwKBgQDRNKLbSPOLxCiNV2OF5KfDbIQt6sWPMnDo | ||
zGyGQgT4WZjLdVX4a3NYKwaHVQq6bASqbr2X1Vdk5zEMzqqTM+AvFA/9OCne1mrH | ||
fPISBimZzLB3iNyu2qTmrJKZcuTV/Bn6lwjbH2sy2Ms1CugQVJDd+LQjJ7/ZaaoM | ||
BmxUj1NfAQKBgQCLjSYI4/SpHciQxom/D1iflak9/33bmOBEGurN8kSl1XQbmP3C | ||
c9uqIJHDxKkwYzEPU+BRI5Vw6AmhoS6xrtxV/vx287bU4x2h2Yd39Li2Gwz+HZXp | ||
+7GoHW3ubLfzPfZH6uXDtPntUFqigLlfD1+gDjaKM4jCFLbOD5jDXx/P5QKBgQCM | ||
BylCkY/Ca2ehQ27v/d50pbvLaCsX7/E3QS0aqDHfcUkeVclXX8RyrUnPZ5KouQhe | ||
c4UfjcLTXROtuN7fbIePu2QAX4lXCDmskOsOOWW69hDf0ZG0z9A0PipZ31dgCz/w | ||
RQu+b0c3X3iUZlpyI8hbas5YAZEeGuWg6uOzrcNmAQKBgAf15LHx7IVEeIfn8ta/ | ||
YnZnODsvN5+4ybMIIuX8yAPmXOy3klYvp1+8BH6jZMVHXAqQugooGirfik02RzQv | ||
tCbCXDoTSMzMQU5iSlvnxtcug93rWa4VFvmU9nSqp7lpJQmiOBwWFf2/mmSwyLc9 | ||
MvOVZTA46IefrGuG64T83RRf | ||
-----END PRIVATE KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package middleware | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
"io" | ||
"net/http" | ||
"strings" | ||
|
||
"github.com/gin-gonic/gin" | ||
) | ||
|
||
var ErrTurnstileFailed = errors.New("failed to pass turnstile") | ||
|
||
const ( | ||
tunrstileURL = "https://challenges.cloudflare.com/turnstile/v0/siteverify" | ||
) | ||
|
||
type TurnstileResponse struct { | ||
Success bool `json:"success"` | ||
ErrorCodes []string `json:"error-codes"` | ||
Messages []string `json:"messages"` | ||
Raw []byte | ||
} | ||
|
||
func makeTurnstileRequest( | ||
ctx context.Context, | ||
cl *http.Client, | ||
secret string, | ||
tokenResponse string, | ||
) (*TurnstileResponse, error) { | ||
request, err := http.NewRequestWithContext( | ||
ctx, | ||
http.MethodPost, | ||
tunrstileURL, | ||
bytes.NewBufferString(`{"secret": "`+secret+`","response":"`+tokenResponse+`"}`), | ||
) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to create turnstile request: %w", err) | ||
} | ||
|
||
request.Header.Set("Content-Type", "application/json") | ||
|
||
response, err := cl.Do(request) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to send turnstile request: %w", err) | ||
} | ||
defer response.Body.Close() | ||
|
||
b, err := io.ReadAll(response.Body) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to read turnstile response: %w", err) | ||
} | ||
|
||
var turnstileResponse TurnstileResponse | ||
if err := json.Unmarshal(b, &turnstileResponse); err != nil { | ||
return nil, fmt.Errorf("failed to unmarshal turnstile response: %w", err) | ||
} | ||
|
||
turnstileResponse.Raw = b | ||
|
||
return &turnstileResponse, nil | ||
} | ||
|
||
func Tunrstile(secret string, prefix string) gin.HandlerFunc { | ||
cl := http.Client{} //nolint:exhaustruct | ||
|
||
return func(ctx *gin.Context) { | ||
if !strings.HasPrefix(ctx.Request.URL.Path, prefix+"/signup/") || | ||
strings.HasSuffix(ctx.Request.URL.Path, "/verify") || | ||
strings.HasSuffix(ctx.Request.URL.Path, "/callback") { | ||
ctx.Next() | ||
return | ||
} | ||
|
||
token := ctx.Request.Header.Get("x-cf-turnstile-response") | ||
|
||
if token == "" { | ||
_ = ctx.Error( | ||
fmt.Errorf("%w: missing x-cf-turnstile-response header", ErrTurnstileFailed), | ||
) | ||
ctx.AbortWithStatusJSON( | ||
http.StatusForbidden, | ||
gin.H{"error": "missing x-cf-turnstile-response header"}, | ||
) | ||
return | ||
} | ||
|
||
turnstileResponse, err := makeTurnstileRequest(ctx.Request.Context(), &cl, secret, token) | ||
if err != nil { | ||
_ = ctx.Error(fmt.Errorf("%w: %w", ErrTurnstileFailed, err)) | ||
ctx.AbortWithStatusJSON( | ||
http.StatusInternalServerError, | ||
gin.H{"error": "internal server error when attempting to pass turnstile"}, | ||
) | ||
return | ||
} | ||
|
||
if !turnstileResponse.Success { | ||
_ = ctx.Error(fmt.Errorf("%w: %s", ErrTurnstileFailed, string(turnstileResponse.Raw))) | ||
ctx.AbortWithStatusJSON( | ||
http.StatusForbidden, | ||
gin.H{ | ||
"error": fmt.Sprintf( | ||
"failed to pass turnstile: %v", | ||
turnstileResponse.Messages, | ||
), | ||
}, | ||
) | ||
return | ||
} | ||
|
||
ctx.Next() | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are you missing a return here?