cmd: integrate invisible recaptcha into puppeth
This commit is contained in:
parent
80e74fc1e0
commit
af48a331bf
|
@ -77,7 +77,7 @@
|
||||||
<div class="row" style="margin-top: 32px;">
|
<div class="row" style="margin-top: 32px;">
|
||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<h3>How does this work?</h3>
|
<h3>How does this work?</h3>
|
||||||
<p>This Ether faucet is running on the {{.Network}} network. To prevent malicious actors from exhausting all available funds or accumulating enough Ether to mount long running spam attacks, requests are tied to GitHub accounts. Anyone having a GitHub account may request funds within the permitted limit of <strong>{{.Amount}} Ether(s) / {{.Period}}</strong>.</p>
|
<p>This Ether faucet is running on the {{.Network}} network. To prevent malicious actors from exhausting all available funds or accumulating enough Ether to mount long running spam attacks, requests are tied to GitHub accounts. Anyone having a GitHub account may request funds within the permitted limit of <strong>{{.Amount}} Ether(s) / {{.Period}}</strong>.{{if .Recaptcha}} The faucet is running invisible reCaptcha protection against bots.{{end}}</p>
|
||||||
<p>To request funds, simply create a <a href="https://gist.github.com/" target="_about:blank">GitHub Gist</a> with your Ethereum address pasted into the contents (the file name doesn't matter), copy paste the gists URL into the above input box and fire away! You can track the current pending requests below the input field to see how much you have to wait until your turn comes.</p>
|
<p>To request funds, simply create a <a href="https://gist.github.com/" target="_about:blank">GitHub Gist</a> with your Ethereum address pasted into the contents (the file name doesn't matter), copy paste the gists URL into the above input box and fire away! You can track the current pending requests below the input field to see how much you have to wait until your turn comes.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -136,7 +136,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
server.onclose = function() { setTimeout(reconnect, 3000); };
|
server.onclose = function() { setTimeout(reconnect, 3000); };
|
||||||
//server.onerror = function() { setTimeout(reconnect, 3000); };
|
|
||||||
}
|
}
|
||||||
// Establish a websocket connection to the API server
|
// Establish a websocket connection to the API server
|
||||||
reconnect();
|
reconnect();
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -54,6 +54,7 @@ CMD [ \
|
||||||
"/faucet", "--genesis", "/genesis.json", "--network", "{{.NetworkID}}", "--bootnodes", "{{.Bootnodes}}", "--ethstats", "{{.Ethstats}}", \
|
"/faucet", "--genesis", "/genesis.json", "--network", "{{.NetworkID}}", "--bootnodes", "{{.Bootnodes}}", "--ethstats", "{{.Ethstats}}", \
|
||||||
"--ethport", "{{.EthPort}}", "--faucet.name", "{{.FaucetName}}", "--faucet.amount", "{{.FaucetAmount}}", "--faucet.minutes", "{{.FaucetMinutes}}", \
|
"--ethport", "{{.EthPort}}", "--faucet.name", "{{.FaucetName}}", "--faucet.amount", "{{.FaucetAmount}}", "--faucet.minutes", "{{.FaucetMinutes}}", \
|
||||||
"--github.user", "{{.GitHubUser}}", "--github.token", "{{.GitHubToken}}", "--account.json", "/account.json", "--account.pass", "/account.pass" \
|
"--github.user", "{{.GitHubUser}}", "--github.token", "{{.GitHubToken}}", "--account.json", "/account.json", "--account.pass", "/account.pass" \
|
||||||
|
{{if .CaptchaToken}}, "--captcha.token", "{{.CaptchaToken}}", "--captcha.secret", "{{.CaptchaSecret}}"{{end}} \
|
||||||
]`
|
]`
|
||||||
|
|
||||||
// faucetComposefile is the docker-compose.yml file required to deploy and maintain
|
// faucetComposefile is the docker-compose.yml file required to deploy and maintain
|
||||||
|
@ -75,7 +76,9 @@ services:
|
||||||
- FAUCET_AMOUNT={{.FaucetAmount}}
|
- FAUCET_AMOUNT={{.FaucetAmount}}
|
||||||
- FAUCET_MINUTES={{.FaucetMinutes}}
|
- FAUCET_MINUTES={{.FaucetMinutes}}
|
||||||
- GITHUB_USER={{.GitHubUser}}
|
- GITHUB_USER={{.GitHubUser}}
|
||||||
- GITHUB_TOKEN={{.GitHubToken}}{{if .VHost}}
|
- GITHUB_TOKEN={{.GitHubToken}}
|
||||||
|
- CAPTCHA_TOKEN={{.CaptchaToken}}
|
||||||
|
- CAPTCHA_SECRET={{.CaptchaSecret}}{{if .VHost}}
|
||||||
- VIRTUAL_HOST={{.VHost}}
|
- VIRTUAL_HOST={{.VHost}}
|
||||||
- VIRTUAL_PORT=8080{{end}}
|
- VIRTUAL_PORT=8080{{end}}
|
||||||
restart: always
|
restart: always
|
||||||
|
@ -97,6 +100,8 @@ func deployFaucet(client *sshClient, network string, bootnodes []string, config
|
||||||
"EthPort": config.node.portFull,
|
"EthPort": config.node.portFull,
|
||||||
"GitHubUser": config.githubUser,
|
"GitHubUser": config.githubUser,
|
||||||
"GitHubToken": config.githubToken,
|
"GitHubToken": config.githubToken,
|
||||||
|
"CaptchaToken": config.captchaToken,
|
||||||
|
"CaptchaSecret": config.captchaSecret,
|
||||||
"FaucetName": strings.Title(network),
|
"FaucetName": strings.Title(network),
|
||||||
"FaucetAmount": config.amount,
|
"FaucetAmount": config.amount,
|
||||||
"FaucetMinutes": config.minutes,
|
"FaucetMinutes": config.minutes,
|
||||||
|
@ -113,6 +118,8 @@ func deployFaucet(client *sshClient, network string, bootnodes []string, config
|
||||||
"EthName": config.node.ethstats[:strings.Index(config.node.ethstats, ":")],
|
"EthName": config.node.ethstats[:strings.Index(config.node.ethstats, ":")],
|
||||||
"GitHubUser": config.githubUser,
|
"GitHubUser": config.githubUser,
|
||||||
"GitHubToken": config.githubToken,
|
"GitHubToken": config.githubToken,
|
||||||
|
"CaptchaToken": config.captchaToken,
|
||||||
|
"CaptchaSecret": config.captchaSecret,
|
||||||
"FaucetAmount": config.amount,
|
"FaucetAmount": config.amount,
|
||||||
"FaucetMinutes": config.minutes,
|
"FaucetMinutes": config.minutes,
|
||||||
})
|
})
|
||||||
|
@ -142,11 +149,13 @@ type faucetInfos struct {
|
||||||
minutes int
|
minutes int
|
||||||
githubUser string
|
githubUser string
|
||||||
githubToken string
|
githubToken string
|
||||||
|
captchaToken string
|
||||||
|
captchaSecret string
|
||||||
}
|
}
|
||||||
|
|
||||||
// String implements the stringer interface.
|
// String implements the stringer interface.
|
||||||
func (info *faucetInfos) String() string {
|
func (info *faucetInfos) String() string {
|
||||||
return fmt.Sprintf("host=%s, api=%d, eth=%d, amount=%d, minutes=%d, github=%s, ethstats=%s", info.host, info.port, info.node.portFull, info.amount, info.minutes, info.githubUser, info.node.ethstats)
|
return fmt.Sprintf("host=%s, api=%d, eth=%d, amount=%d, minutes=%d, github=%s, captcha=%v, ethstats=%s", info.host, info.port, info.node.portFull, info.amount, info.minutes, info.githubUser, info.captchaToken != "", info.node.ethstats)
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkFaucet does a health-check against an faucet server to verify whether
|
// checkFaucet does a health-check against an faucet server to verify whether
|
||||||
|
@ -206,5 +215,7 @@ func checkFaucet(client *sshClient, network string) (*faucetInfos, error) {
|
||||||
minutes: minutes,
|
minutes: minutes,
|
||||||
githubUser: infos.envvars["GITHUB_USER"],
|
githubUser: infos.envvars["GITHUB_USER"],
|
||||||
githubToken: infos.envvars["GITHUB_TOKEN"],
|
githubToken: infos.envvars["GITHUB_TOKEN"],
|
||||||
|
captchaToken: infos.envvars["CAPTCHA_TOKEN"],
|
||||||
|
captchaSecret: infos.envvars["CAPTCHA_SECRET"],
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ func (w *wizard) deployFaucet() {
|
||||||
// Accessing GitHub gists requires API authorization, retrieve it
|
// Accessing GitHub gists requires API authorization, retrieve it
|
||||||
if infos.githubUser != "" {
|
if infos.githubUser != "" {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Printf("Reused previous (%s) GitHub API authorization (y/n)? (default = yes)\n", infos.githubUser)
|
fmt.Printf("Reuse previous (%s) GitHub API authorization (y/n)? (default = yes)\n", infos.githubUser)
|
||||||
if w.readDefaultString("y") != "y" {
|
if w.readDefaultString("y") != "y" {
|
||||||
infos.githubUser, infos.githubToken = "", ""
|
infos.githubUser, infos.githubToken = "", ""
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,29 @@ func (w *wizard) deployFaucet() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Accessing the reCaptcha service requires API authorizations, request it
|
||||||
|
if infos.captchaToken != "" {
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("Reuse previous reCaptcha API authorization (y/n)? (default = yes)")
|
||||||
|
if w.readDefaultString("y") != "y" {
|
||||||
|
infos.captchaToken, infos.captchaSecret = "", ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if infos.captchaToken == "" {
|
||||||
|
// No previous authorization (or old one discarded)
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("Enable reCaptcha protection against robots (y/n)? (default = no)")
|
||||||
|
if w.readDefaultString("n") == "y" {
|
||||||
|
// Captcha protection explicitly requested, read the site and secret keys
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Printf("What is the reCaptcha site key to authenticate human users?\n")
|
||||||
|
infos.captchaToken = w.readString()
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Printf("What is the reCaptcha secret key to verify authentications? (won't be echoed)\n")
|
||||||
|
infos.captchaSecret = w.readPassword()
|
||||||
|
}
|
||||||
|
}
|
||||||
// Figure out where the user wants to store the persistent data
|
// Figure out where the user wants to store the persistent data
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
if infos.node.datadir == "" {
|
if infos.node.datadir == "" {
|
||||||
|
|
Loading…
Reference in New Issue