mirror of
https://github.com/sequentialread/pow-captcha.git
synced 2025-11-24 06:25:47 +00:00
updates for pow-bot-deterrent-rp -- fixing cross domain webworker issue
This commit is contained in:
parent
86a1d903dc
commit
9f8fc11ed5
@ -16,6 +16,5 @@ WORKDIR /app
|
|||||||
COPY --from=build /build/pow-bot-deterrent /app/pow-bot-deterrent
|
COPY --from=build /build/pow-bot-deterrent /app/pow-bot-deterrent
|
||||||
COPY static /app/static
|
COPY static /app/static
|
||||||
COPY PoW_Bot_Deterrent_API_Tokens /app/PoW_Bot_Deterrent_API_Tokens
|
COPY PoW_Bot_Deterrent_API_Tokens /app/PoW_Bot_Deterrent_API_Tokens
|
||||||
RUN chmod +x /app/pow-bot-deterrent
|
|
||||||
ENTRYPOINT ["/app/pow-bot-deterrent"]
|
ENTRYPOINT ["/app/pow-bot-deterrent"]
|
||||||
|
|
||||||
|
|||||||
16
README.md
16
README.md
@ -142,7 +142,7 @@ Return type: `text/plain` (error/status messages only)
|
|||||||
Otherwise it returns 404, 400, or 500.
|
Otherwise it returns 404, 400, or 500.
|
||||||
|
|
||||||
|
|
||||||
#### `GET /static/<filename>`
|
#### `GET /pow-bot-deterrent-static/<filename>`
|
||||||
|
|
||||||
Return type: depends on file
|
Return type: depends on file
|
||||||
|
|
||||||
@ -236,7 +236,7 @@ When `pow-bot-deterrent.js` runs, if it finds an element with `data-pow-bot-dete
|
|||||||
|
|
||||||
> 💬 *INFO* the element with the `pow-bot-deterrent` data properties should probably be styled to have a very small font size. When I was designing the css for the bot deterrent element, I made everything scale based on the font size (by using `em`). But because the page I was testing it on had a small font by default, I accidentally made it huge when it is rendered on a default HTML page. So for now you will want to make the font size of the element which contains it fairly small, like `10px` or `11px`.
|
> 💬 *INFO* the element with the `pow-bot-deterrent` data properties should probably be styled to have a very small font size. When I was designing the css for the bot deterrent element, I made everything scale based on the font size (by using `em`). But because the page I was testing it on had a small font by default, I accidentally made it huge when it is rendered on a default HTML page. So for now you will want to make the font size of the element which contains it fairly small, like `10px` or `11px`.
|
||||||
|
|
||||||
#### `window.botBotDeterrentInit`
|
#### `window.powBotDeterrentInit`
|
||||||
|
|
||||||
The bot deterrent event listeners, elements, css, & webworkers **won't be loaded until this function is called**.
|
The bot deterrent event listeners, elements, css, & webworkers **won't be loaded until this function is called**.
|
||||||
|
|
||||||
@ -248,15 +248,15 @@ For example:
|
|||||||
|
|
||||||
```
|
```
|
||||||
<script>
|
<script>
|
||||||
window.botBotDeterrentInit();
|
window.powBotDeterrentInit();
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `window.powBotDeterrentReset`
|
#### `window.powBotDeterrentReset`
|
||||||
|
|
||||||
Resets the bot deterrent(s), stops the webworkers, etc. Use this if you have updated the page and you need to call `window.botBotDeterrentInit` again.
|
Resets the bot deterrent(s), stops the webworkers, etc. Use this if you have updated the page and you need to call `window.powBotDeterrentInit` again.
|
||||||
|
|
||||||
#### `window.botBotDeterrentInitDone`
|
#### `window.powBotDeterrentInitDone`
|
||||||
|
|
||||||
A boolean variable that `pow-bot-deterrent.js` uses internally, so it can know if it has already been initialized or not.
|
A boolean variable that `pow-bot-deterrent.js` uses internally, so it can know if it has already been initialized or not.
|
||||||
|
|
||||||
@ -296,10 +296,10 @@ function MyComponent({botDeterrentURL, challenge}) {
|
|||||||
// Maybe less clear than the above, but JavaScript heads might enjoy this more:
|
// Maybe less clear than the above, but JavaScript heads might enjoy this more:
|
||||||
// window[uniqueCallback] = setNonce;
|
// window[uniqueCallback] = setNonce;
|
||||||
|
|
||||||
if(window.botBotDeterrentInitDone) {
|
if(window.powBotDeterrentInitDone) {
|
||||||
window.powBotDeterrentReset();
|
window.powBotDeterrentReset();
|
||||||
}
|
}
|
||||||
window.botBotDeterrentInit();
|
window.powBotDeterrentInit();
|
||||||
}, [uniqueCallback]);
|
}, [uniqueCallback]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -484,7 +484,7 @@ There are two main important parts, the form and the javascript at the bottom:
|
|||||||
document.querySelector("form input[type='submit']").disabled = false;
|
document.querySelector("form input[type='submit']").disabled = false;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<script src="{{ .PowAPIURL }}/static/pow-bot-deterrent.js"></script>
|
<script src="{{ .PowAPIURL }}/pow-bot-deterrent-static/pow-bot-deterrent.js"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
⚠️ **NOTE** that the element with the `pow-bot-deterrent` data properties is placed **inside a form element**. This is required because the bot deterrent needs to know which input elements it should trigger on. We only want it to trigger when the user actually intends to submit the form; otherwise we are wasting a lot of their CPU cycles for no reason!
|
⚠️ **NOTE** that the element with the `pow-bot-deterrent` data properties is placed **inside a form element**. This is required because the bot deterrent needs to know which input elements it should trigger on. We only want it to trigger when the user actually intends to submit the form; otherwise we are wasting a lot of their CPU cycles for no reason!
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
#!/bin/bash -e
|
#!/bin/bash -e
|
||||||
|
|
||||||
VERSION="0.0.13"
|
tag="0.0.0"
|
||||||
|
if git describe --tags --abbrev=0 > /dev/null 2>&1 ; then
|
||||||
|
tag="$(git describe --tags --abbrev=0)"
|
||||||
|
fi
|
||||||
|
VERSION="$tag-$(git rev-parse --short HEAD)-$(hexdump -n 2 -ve '1/1 "%.2x"' /dev/urandom)"
|
||||||
|
|
||||||
rm -rf dockerbuild || true
|
rm -rf dockerbuild || true
|
||||||
mkdir dockerbuild
|
mkdir dockerbuild
|
||||||
@ -9,17 +13,17 @@ cp Dockerfile dockerbuild/Dockerfile-amd64
|
|||||||
cp Dockerfile dockerbuild/Dockerfile-arm
|
cp Dockerfile dockerbuild/Dockerfile-arm
|
||||||
cp Dockerfile dockerbuild/Dockerfile-arm64
|
cp Dockerfile dockerbuild/Dockerfile-arm64
|
||||||
|
|
||||||
sed -E 's|FROM alpine|FROM amd64/alpine|' -i dockerbuild/Dockerfile-amd64
|
sed -E 's|FROM alpine|FROM --platform=linux/amd64 alpine|' -i dockerbuild/Dockerfile-amd64
|
||||||
sed -E 's|FROM alpine|FROM arm32v7/alpine|' -i dockerbuild/Dockerfile-arm
|
sed -E 's|FROM alpine|FROM --platform=linux/arm/v7 alpine|' -i dockerbuild/Dockerfile-arm
|
||||||
sed -E 's|FROM alpine|FROM arm64v8/alpine|' -i dockerbuild/Dockerfile-arm64
|
sed -E 's|FROM alpine|FROM --platform=linux/arm64/v8 alpine|' -i dockerbuild/Dockerfile-arm64
|
||||||
|
|
||||||
sed -E 's/GOARCH=/GOARCH=amd64/' -i dockerbuild/Dockerfile-amd64
|
sed -E 's/GOARCH=/GOARCH=amd64/' -i dockerbuild/Dockerfile-amd64
|
||||||
sed -E 's/GOARCH=/GOARCH=arm/' -i dockerbuild/Dockerfile-arm
|
sed -E 's/GOARCH=/GOARCH=arm/' -i dockerbuild/Dockerfile-arm
|
||||||
sed -E 's/GOARCH=/GOARCH=arm64/' -i dockerbuild/Dockerfile-arm64
|
sed -E 's/GOARCH=/GOARCH=arm64/' -i dockerbuild/Dockerfile-arm64
|
||||||
|
|
||||||
docker build -f dockerbuild/Dockerfile-amd64 -t sequentialread/pow-bot-deterrent:$VERSION-amd64 .
|
docker build --progress=plain -f dockerbuild/Dockerfile-amd64 -t sequentialread/pow-bot-deterrent:$VERSION-amd64 .
|
||||||
docker build -f dockerbuild/Dockerfile-arm -t sequentialread/pow-bot-deterrent:$VERSION-arm .
|
docker build --progress=plain -f dockerbuild/Dockerfile-arm -t sequentialread/pow-bot-deterrent:$VERSION-arm .
|
||||||
docker build -f dockerbuild/Dockerfile-arm64 -t sequentialread/pow-bot-deterrent:$VERSION-arm64 .
|
docker build --progress=plain -f dockerbuild/Dockerfile-arm64 -t sequentialread/pow-bot-deterrent:$VERSION-arm64 .
|
||||||
|
|
||||||
docker push sequentialread/pow-bot-deterrent:$VERSION-amd64
|
docker push sequentialread/pow-bot-deterrent:$VERSION-amd64
|
||||||
docker push sequentialread/pow-bot-deterrent:$VERSION-arm
|
docker push sequentialread/pow-bot-deterrent:$VERSION-arm
|
||||||
|
|||||||
@ -47,31 +47,6 @@
|
|||||||
document.querySelector("form input[type='submit']").disabled = false;
|
document.querySelector("form input[type='submit']").disabled = false;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<script src="/static/pow-bot-deterrent.js"></script>
|
<script src="/pow-bot-deterrent-static/pow-bot-deterrent.js"></script>
|
||||||
<!-- <script src='./static/scrypt_wasm.js'></script>
|
|
||||||
<script>
|
|
||||||
const { scrypt } = wasm_bindgen;
|
|
||||||
|
|
||||||
async function run() {
|
|
||||||
console.log("a");
|
|
||||||
await wasm_bindgen();
|
|
||||||
|
|
||||||
console.log(scrypt(hexEncode('password in hex'), hexEncode('password in hex'), 4096, 8, 1, 16))
|
|
||||||
}
|
|
||||||
|
|
||||||
run();
|
|
||||||
|
|
||||||
function hexEncode(s){
|
|
||||||
var hex, i;
|
|
||||||
|
|
||||||
var result = "";
|
|
||||||
for (i=0; i<s.length; i++) {
|
|
||||||
hex = s.charCodeAt(i).toString(16);
|
|
||||||
result += ("000"+hex).slice(-4);
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
</script> -->
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
170
main.go
170
main.go
@ -14,15 +14,34 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
configlite "git.sequentialread.com/forest/config-lite"
|
||||||
errors "git.sequentialread.com/forest/pkg-errors"
|
errors "git.sequentialread.com/forest/pkg-errors"
|
||||||
"golang.org/x/crypto/scrypt"
|
"golang.org/x/crypto/scrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
ListenPort int `json:"listen_port"`
|
||||||
|
BatchSize int `json:"batch_size"`
|
||||||
|
DeprecateAfterBatches int `json:"deprecate_after_batches"`
|
||||||
|
ScryptCPUAndMemoryCost int `json:"scrypt_cpu_and_memory_cost"`
|
||||||
|
AdminAPIToken string `json:"admin_api_token"`
|
||||||
|
|
||||||
|
EmailAddress string `json:"email_address"`
|
||||||
|
// port 993 (IMAPS)
|
||||||
|
// port 143 (STARTTLS) [deprecated!]
|
||||||
|
ImapHost string `json:"imap_host"`
|
||||||
|
ImapPort int `json:"imap_port"`
|
||||||
|
ImapEncryption string `json:"imap_encryption"`
|
||||||
|
ImapUsername string `json:"imap_username"`
|
||||||
|
ImapPassword string `json:"imap_password"`
|
||||||
|
}
|
||||||
|
|
||||||
// https://en.wikipedia.org/wiki/Scrypt
|
// https://en.wikipedia.org/wiki/Scrypt
|
||||||
type ScryptParameters struct {
|
type ScryptParameters struct {
|
||||||
CPUAndMemoryCost int `json:"N"`
|
CPUAndMemoryCost int `json:"N"`
|
||||||
@ -38,6 +57,9 @@ type Challenge struct {
|
|||||||
DifficultyLevel int `json:"dl"`
|
DifficultyLevel int `json:"dl"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var config Config
|
||||||
|
var appDirectory string
|
||||||
|
var scryptParameters ScryptParameters
|
||||||
var currentChallengesGeneration = map[string]int{}
|
var currentChallengesGeneration = map[string]int{}
|
||||||
var challenges = map[string]map[string]int{}
|
var challenges = map[string]map[string]int{}
|
||||||
|
|
||||||
@ -45,51 +67,7 @@ func main() {
|
|||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
batchSize := 1000
|
apiTokensFolder := readConfiguration()
|
||||||
deprecateAfterBatches := 10
|
|
||||||
portNumber := 2370
|
|
||||||
scryptCPUAndMemoryCost := 16384
|
|
||||||
batchSizeEnv := os.ExpandEnv("$POW_BOT_DETERRENT_BATCH_SIZE")
|
|
||||||
deprecateAfterBatchesEnv := os.ExpandEnv("$POW_BOT_DETERRENT_DEPRECATE_AFTER_BATCHES")
|
|
||||||
portNumberEnv := os.ExpandEnv("$POW_BOT_DETERRENT_LISTEN_PORT")
|
|
||||||
scryptCPUAndMemoryCostEnv := os.ExpandEnv("$POW_BOT_DETERRENT_SCRYPT_CPU_AND_MEMORY_COST")
|
|
||||||
if batchSizeEnv != "" {
|
|
||||||
batchSize, err = strconv.Atoi(batchSizeEnv)
|
|
||||||
if err != nil {
|
|
||||||
panic(errors.Wrapf(err, "can't start the app because the POW_BOT_DETERRENT_BATCH_SIZE '%s' can't be converted to an integer", batchSizeEnv))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if deprecateAfterBatchesEnv != "" {
|
|
||||||
deprecateAfterBatches, err = strconv.Atoi(deprecateAfterBatchesEnv)
|
|
||||||
if err != nil {
|
|
||||||
panic(errors.Wrapf(err, "can't start the app because the POW_BOT_DETERRENT_DEPRECATE_AFTER_BATCHES '%s' can't be converted to an integer", deprecateAfterBatchesEnv))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if portNumberEnv != "" {
|
|
||||||
portNumber, err = strconv.Atoi(portNumberEnv)
|
|
||||||
if err != nil {
|
|
||||||
panic(errors.Wrapf(err, "can't start the app because the POW_BOT_DETERRENT_LISTEN_PORT '%s' can't be converted to an integer", portNumberEnv))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if scryptCPUAndMemoryCostEnv != "" {
|
|
||||||
scryptCPUAndMemoryCost, err = strconv.Atoi(scryptCPUAndMemoryCostEnv)
|
|
||||||
if err != nil {
|
|
||||||
panic(errors.Wrapf(err, "can't start the app because the POW_BOT_DETERRENT_SCRYPT_CPU_AND_MEMORY_COST '%s' can't be converted to an integer", scryptCPUAndMemoryCostEnv))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
apiTokensFolder := locateAPITokensFolder()
|
|
||||||
adminAPIToken := os.ExpandEnv("$POW_BOT_DETERRENT_ADMIN_API_TOKEN")
|
|
||||||
if adminAPIToken == "" {
|
|
||||||
panic(errors.New("can't start the app, the POW_BOT_DETERRENT_ADMIN_API_TOKEN environment variable is required"))
|
|
||||||
}
|
|
||||||
|
|
||||||
scryptParameters := ScryptParameters{
|
|
||||||
CPUAndMemoryCost: scryptCPUAndMemoryCost,
|
|
||||||
BlockSize: 8,
|
|
||||||
Paralellization: 1,
|
|
||||||
KeyLength: 16,
|
|
||||||
}
|
|
||||||
|
|
||||||
requireMethod := func(method string) func(http.ResponseWriter, *http.Request) bool {
|
requireMethod := func(method string) func(http.ResponseWriter, *http.Request) bool {
|
||||||
return func(responseWriter http.ResponseWriter, request *http.Request) bool {
|
return func(responseWriter http.ResponseWriter, request *http.Request) bool {
|
||||||
@ -103,7 +81,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
requireAdmin := func(responseWriter http.ResponseWriter, request *http.Request) bool {
|
requireAdmin := func(responseWriter http.ResponseWriter, request *http.Request) bool {
|
||||||
if request.Header.Get("Authorization") != fmt.Sprintf("Bearer %s", adminAPIToken) {
|
if request.Header.Get("Authorization") != fmt.Sprintf("Bearer %s", config.AdminAPIToken) {
|
||||||
http.Error(responseWriter, "401 Unauthorized", http.StatusUnauthorized)
|
http.Error(responseWriter, "401 Unauthorized", http.StatusUnauthorized)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -262,8 +240,8 @@ func main() {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
toReturn := make([]string, batchSize)
|
toReturn := make([]string, config.BatchSize)
|
||||||
for i := 0; i < batchSize; i++ {
|
for i := 0; i < config.BatchSize; i++ {
|
||||||
preimageBytes := make([]byte, 8)
|
preimageBytes := make([]byte, 8)
|
||||||
_, err := rand.Read(preimageBytes)
|
_, err := rand.Read(preimageBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -309,7 +287,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
toRemove := []string{}
|
toRemove := []string{}
|
||||||
for k, generation := range challenges[token] {
|
for k, generation := range challenges[token] {
|
||||||
if generation+deprecateAfterBatches < currentChallengesGeneration[token] {
|
if generation+config.DeprecateAfterBatches < currentChallengesGeneration[token] {
|
||||||
toRemove = append(toRemove, k)
|
toRemove = append(toRemove, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -417,11 +395,23 @@ func main() {
|
|||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
http.HandleFunc("/static/captcha.css", func(responseWriter http.ResponseWriter, request *http.Request) {
|
||||||
|
bytez, _ := os.ReadFile("./static/pow-bot-deterrent.css")
|
||||||
|
responseWriter.Header().Set("Content-Type", "text/css")
|
||||||
|
responseWriter.Write(bytez)
|
||||||
|
})
|
||||||
|
http.HandleFunc("/static/captcha.js", func(responseWriter http.ResponseWriter, request *http.Request) {
|
||||||
|
bytez, _ := os.ReadFile("./static/pow-bot-deterrent.js")
|
||||||
|
responseWriter.Header().Set("Content-Type", "application/javascript")
|
||||||
|
responseWriter.Write(bytez)
|
||||||
|
})
|
||||||
|
|
||||||
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static/"))))
|
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static/"))))
|
||||||
|
http.Handle("/pow-bot-deterrent-static/", http.StripPrefix("/pow-bot-deterrent-static/", http.FileServer(http.Dir("./static/"))))
|
||||||
|
|
||||||
log.Printf("💥 PoW! Bot Deterrent server listening on port %d", portNumber)
|
log.Printf("💥 PoW! Bot Deterrent server listening on port %d", config.ListenPort)
|
||||||
|
|
||||||
err = http.ListenAndServe(fmt.Sprintf(":%d", portNumber), nil)
|
err = http.ListenAndServe(fmt.Sprintf(":%d", config.ListenPort), nil)
|
||||||
|
|
||||||
// if got this far it means server crashed!
|
// if got this far it means server crashed!
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -489,3 +479,81 @@ func getCurrentExecDir() (dir string, err error) {
|
|||||||
|
|
||||||
return dir, nil
|
return dir, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func readConfiguration() string {
|
||||||
|
apiTokensFolderPath := locateAPITokensFolder()
|
||||||
|
appDirectory = filepath.Dir(apiTokensFolderPath)
|
||||||
|
configJsonPath := filepath.Join(appDirectory, "config.json")
|
||||||
|
err := configlite.ReadConfiguration(configJsonPath, "POW_BOT_DETERRENT", []string{}, reflect.ValueOf(&config))
|
||||||
|
if err != nil {
|
||||||
|
panic(errors.Wrap(err, "ReadConfiguration returned"))
|
||||||
|
}
|
||||||
|
|
||||||
|
errors := []string{}
|
||||||
|
if config.ListenPort == 0 {
|
||||||
|
config.ListenPort = 2370
|
||||||
|
}
|
||||||
|
if config.BatchSize == 0 {
|
||||||
|
config.BatchSize = 1000
|
||||||
|
}
|
||||||
|
if config.DeprecateAfterBatches == 0 {
|
||||||
|
config.DeprecateAfterBatches = 10
|
||||||
|
}
|
||||||
|
if config.ScryptCPUAndMemoryCost == 0 {
|
||||||
|
config.ScryptCPUAndMemoryCost = 16384
|
||||||
|
}
|
||||||
|
if config.AdminAPIToken == "" {
|
||||||
|
errors = append(errors, "the POW_BOT_DETERRENT_ADMIN_API_TOKEN environment variable is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.EmailAddress != "" {
|
||||||
|
if config.ImapHost == "" {
|
||||||
|
config.ImapHost = "localhost"
|
||||||
|
}
|
||||||
|
if config.ImapPort == 0 {
|
||||||
|
config.ImapPort = 993
|
||||||
|
}
|
||||||
|
if config.ImapEncryption == "" {
|
||||||
|
config.ImapEncryption = "SMTPS"
|
||||||
|
}
|
||||||
|
if config.ImapEncryption != "STARTTLS" && config.ImapEncryption != "IMAPS" && config.ImapEncryption != "NONE" {
|
||||||
|
errors = append(errors, fmt.Sprintf("ImapEncryption '%s' must be IMAPS, STARTTLS or NONE", config.ImapEncryption))
|
||||||
|
}
|
||||||
|
if config.ImapUsername == "" {
|
||||||
|
errors = append(errors, "ImapUsername is required")
|
||||||
|
}
|
||||||
|
if config.ImapPassword == "" {
|
||||||
|
errors = append(errors, "ImapPassword is required")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(errors) > 0 {
|
||||||
|
log.Fatalln("💥 PoW Bot Deterrent can't start because there are configuration issues:")
|
||||||
|
log.Fatalln(strings.Join(errors, "\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
scryptParameters = ScryptParameters{
|
||||||
|
CPUAndMemoryCost: config.ScryptCPUAndMemoryCost,
|
||||||
|
BlockSize: 8,
|
||||||
|
Paralellization: 1,
|
||||||
|
KeyLength: 16,
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("💥 PoW Bot Deterrent starting up with config:")
|
||||||
|
configToLogBytes, _ := json.MarshalIndent(config, "", " ")
|
||||||
|
configToLogString := regexp.MustCompile(
|
||||||
|
`("admin_api_token": ")[^"]+(",)`,
|
||||||
|
).ReplaceAllString(
|
||||||
|
string(configToLogBytes),
|
||||||
|
"$1******$2",
|
||||||
|
)
|
||||||
|
configToLogString = regexp.MustCompile(
|
||||||
|
`("imap_password": ")[^"]+(",?)`,
|
||||||
|
).ReplaceAllString(
|
||||||
|
configToLogString,
|
||||||
|
"$1******$2",
|
||||||
|
)
|
||||||
|
log.Println(configToLogString)
|
||||||
|
|
||||||
|
return apiTokensFolderPath
|
||||||
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
let scrypt;
|
let scrypt;
|
||||||
let scryptPromise;
|
let scryptPromise;
|
||||||
|
let wasm;
|
||||||
|
|
||||||
let working = false;
|
let working = false;
|
||||||
const batchSize = 8;
|
const batchSize = 8;
|
||||||
@ -125,7 +126,7 @@ onmessage = function(e) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if(scrypt) {
|
if(wasm && scrypt) {
|
||||||
doWork();
|
doWork();
|
||||||
} else {
|
} else {
|
||||||
scryptPromise.then(() => {
|
scryptPromise.then(() => {
|
||||||
|
|||||||
@ -3,31 +3,27 @@
|
|||||||
const numberOfWebWorkersToCreate = 4;
|
const numberOfWebWorkersToCreate = 4;
|
||||||
|
|
||||||
window.powBotDeterrentReset = () => {
|
window.powBotDeterrentReset = () => {
|
||||||
window.botBotDeterrentInitDone = false;
|
window.powBotDeterrentInitDone = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
window.botBotDeterrentInit = () => {
|
const trimSlashes = x => x.replace(/^\/|\/$/g, '');
|
||||||
if(window.botBotDeterrentInitDone) {
|
|
||||||
console.error("botBotDeterrentInit was called twice!");
|
window.powBotDeterrentInit = () => {
|
||||||
|
if(window.powBotDeterrentInitDone) {
|
||||||
|
console.error("powBotDeterrentInit was called twice!");
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
window.botBotDeterrentInitDone = true;
|
window.powBotDeterrentInitDone = true;
|
||||||
|
|
||||||
const challenges = Array.from(document.querySelectorAll("[data-pow-bot-deterrent-challenge]"));
|
const challenges = Array.from(document.querySelectorAll("[data-pow-bot-deterrent-challenge]"));
|
||||||
const challengesMap = {};
|
const challengesMap = {};
|
||||||
let url = null;
|
let staticAssetsPath = trimSlashes("/pow-bot-deterrent-static/")
|
||||||
let proofOfWorker = { postMessage: () => console.error("error: proofOfWorker was never loaded. ") };
|
let proofOfWorker = { postMessage: () => console.error("error: proofOfWorker was never loaded. ") };
|
||||||
|
|
||||||
challenges.forEach(element => {
|
challenges.forEach(element => {
|
||||||
|
|
||||||
if(!url) {
|
if(element.dataset.powBotDeterrentStaticAssetsPath) {
|
||||||
if(!element.dataset.powBotDeterrentUrl) {
|
staticAssetsPath = trimSlashes(element.dataset.powBotDeterrentStaticAssetsPath);
|
||||||
console.error("error: element with data-pow-bot-deterrent-challenge property is missing the data-pow-bot-deterrent-url property");
|
|
||||||
}
|
|
||||||
url = element.dataset.powBotDeterrentUrl;
|
|
||||||
if(url.endsWith("/")) {
|
|
||||||
url = url.substring(0, url.length-1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!element.dataset.powBotDeterrentCallback) {
|
if(!element.dataset.powBotDeterrentCallback) {
|
||||||
@ -62,7 +58,7 @@
|
|||||||
//todo
|
//todo
|
||||||
}
|
}
|
||||||
|
|
||||||
let cssIsAlreadyLoaded = document.querySelector(`link[href='${url}/static/pow-bot-deterrent.css']`);
|
let cssIsAlreadyLoaded = document.querySelector(`link[href='/${staticAssetsPath}/pow-bot-deterrent.css']`);
|
||||||
|
|
||||||
cssIsAlreadyLoaded = cssIsAlreadyLoaded || Array.from(document.styleSheets).some(x => {
|
cssIsAlreadyLoaded = cssIsAlreadyLoaded || Array.from(document.styleSheets).some(x => {
|
||||||
try {
|
try {
|
||||||
@ -78,7 +74,7 @@
|
|||||||
"charset": "utf8",
|
"charset": "utf8",
|
||||||
});
|
});
|
||||||
stylesheet.onload = () => renderProgressInfo(element);
|
stylesheet.onload = () => renderProgressInfo(element);
|
||||||
stylesheet.setAttribute("href", `${url}/static/pow-bot-deterrent.css`);
|
stylesheet.setAttribute("href", `${staticAssetsPath}/pow-bot-deterrent.css`);
|
||||||
} else {
|
} else {
|
||||||
renderProgressInfo(element);
|
renderProgressInfo(element);
|
||||||
}
|
}
|
||||||
@ -133,22 +129,9 @@
|
|||||||
//todo
|
//todo
|
||||||
}
|
}
|
||||||
|
|
||||||
if(url) {
|
|
||||||
|
|
||||||
// // https://stackoverflow.com/questions/21913673/execute-web-worker-from-different-origin/62914052#62914052
|
|
||||||
// const webWorkerUrlWhichIsProbablyCrossOrigin = `${url}/static/proofOfWorker.js`;
|
|
||||||
|
|
||||||
// const webWorkerPointerDataURL = URL.createObjectURL(
|
|
||||||
// new Blob(
|
|
||||||
// [ `importScripts( "${ webWorkerUrlWhichIsProbablyCrossOrigin }" );` ],
|
|
||||||
// { type: "text/javascript" }
|
|
||||||
// )
|
|
||||||
// );
|
|
||||||
|
|
||||||
// return
|
|
||||||
let webWorkers;
|
let webWorkers;
|
||||||
webWorkers = [...Array(numberOfWebWorkersToCreate)].map((_, i) => {
|
webWorkers = [...Array(numberOfWebWorkersToCreate)].map((_, i) => {
|
||||||
const webWorker = new Worker('/static/proofOfWorker.js');
|
const webWorker = new Worker(`/${staticAssetsPath}/proofOfWorker.js`);
|
||||||
webWorker.onmessage = function(e) {
|
webWorker.onmessage = function(e) {
|
||||||
const challengeState = challengesMap[e.data.challenge]
|
const challengeState = challengesMap[e.data.challenge]
|
||||||
if(!challengeState) {
|
if(!challengeState) {
|
||||||
@ -213,8 +196,6 @@
|
|||||||
return webWorker;
|
return webWorker;
|
||||||
});
|
});
|
||||||
|
|
||||||
// URL.revokeObjectURL(webWorkerPointerDataURL);
|
|
||||||
|
|
||||||
proofOfWorker = {
|
proofOfWorker = {
|
||||||
postMessage: arg => webWorkers.forEach((x, i) => {
|
postMessage: arg => webWorkers.forEach((x, i) => {
|
||||||
x.postMessage({ ...arg, workerId: i })
|
x.postMessage({ ...arg, workerId: i })
|
||||||
@ -222,15 +203,14 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
window.powBotDeterrentReset = () => {
|
window.powBotDeterrentReset = () => {
|
||||||
window.botBotDeterrentInitDone = false;
|
window.powBotDeterrentInitDone = false;
|
||||||
webWorkers.forEach(x => x.terminate());
|
webWorkers.forEach(x => x.terminate());
|
||||||
};
|
};
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const challenges = Array.from(document.querySelectorAll("[data-pow-bot-deterrent-challenge]"));
|
const challenges = Array.from(document.querySelectorAll("[data-pow-bot-deterrent-challenge]"));
|
||||||
if(challenges.length) {
|
if(challenges.length) {
|
||||||
window.botBotDeterrentInit();
|
window.powBotDeterrentInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCallbackFromGlobalNamespace(callbackString) {
|
function getCallbackFromGlobalNamespace(callbackString) {
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
let scrypt;
|
let scrypt;
|
||||||
let scryptPromise;
|
let scryptPromise;
|
||||||
|
let wasm = undefined;
|
||||||
|
|
||||||
let working = false;
|
let working = false;
|
||||||
const batchSize = 4;
|
const batchSize = 4;
|
||||||
@ -149,7 +150,6 @@ let wasm_bindgen;
|
|||||||
if (typeof document !== 'undefined' && document.currentScript !== null) {
|
if (typeof document !== 'undefined' && document.currentScript !== null) {
|
||||||
script_src = new URL(document.currentScript.src, location.href).toString();
|
script_src = new URL(document.currentScript.src, location.href).toString();
|
||||||
}
|
}
|
||||||
let wasm = undefined;
|
|
||||||
|
|
||||||
let WASM_VECTOR_LEN = 0;
|
let WASM_VECTOR_LEN = 0;
|
||||||
|
|
||||||
@ -365,11 +365,11 @@ let wasm_bindgen;
|
|||||||
return __wbg_finalize_init(instance, module);
|
return __wbg_finalize_init(instance, module);
|
||||||
}
|
}
|
||||||
|
|
||||||
wasm_bindgen = Object.assign(__wbg_init, { initSync }, __exports);
|
/pow-bot-deterrent-static/_bindgen = Object.assign(__wbg_init, { initSync }, __exports);
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
scrypt = wasm_bindgen.scrypt;
|
scrypt = wasm_bindgen.scrypt;
|
||||||
scryptPromise = wasm_bindgen({module_or_path: "/static/scrypt.wasm"});
|
scryptPromise = wasm_bindgen({module_or_path: "/pow-bot-deterrent-static/scrypt.wasm"});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -46,7 +46,8 @@ echo '
|
|||||||
|
|
||||||
cat ../proofOfWorkerStub.js | tail -n +6 >> ../static/proofOfWorker.js
|
cat ../proofOfWorkerStub.js | tail -n +6 >> ../static/proofOfWorker.js
|
||||||
|
|
||||||
cat scrypt-wasm/pkg/scrypt_wasm.js >> ../static/proofOfWorker.js
|
# wasm was defined at the top of proofOfWorker.js, so don't define it again.
|
||||||
|
cat scrypt-wasm/pkg/scrypt_wasm.js | grep -v 'let wasm = ' >> ../static/proofOfWorker.js
|
||||||
|
|
||||||
# see: https://rustwasm.github.io/docs/wasm-bindgen/examples/without-a-bundler.html
|
# see: https://rustwasm.github.io/docs/wasm-bindgen/examples/without-a-bundler.html
|
||||||
echo '
|
echo '
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user