xd
This commit is contained in:
commit
7e00837737
10 changed files with 219 additions and 0 deletions
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2024 Fijxu <fijxu@nadeko.net>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
3
README.md
Normal file
3
README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# mcaptcha-backend-poc
|
||||
|
||||
Just a little Proof of concept that I did to learn how to use mCaptcha
|
5
config.example.yml
Normal file
5
config.example.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
# https://mcaptcha.nadeko.net/sitekeys
|
||||
mcaptchaSitekey: ""
|
||||
# https://mcaptcha.nadeko.net/settings
|
||||
mcaptchaAccountSecret: ""
|
||||
mcaptchaInstance: "mcaptcha.nadeko.net"
|
17
shard.yml
Normal file
17
shard.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
name: mcaptcha-backend
|
||||
version: 0.1.0
|
||||
|
||||
authors:
|
||||
- Fijxu <fijxu@nadeko.net>
|
||||
|
||||
targets:
|
||||
mcaptcha-backend:
|
||||
main: src/mcaptcha-backend.cr
|
||||
|
||||
dependencies:
|
||||
kemal:
|
||||
github: kemalcr/kemal
|
||||
|
||||
crystal: '>= 1.13.1'
|
||||
|
||||
license: MIT
|
9
spec/mcaptcha-backend_spec.cr
Normal file
9
spec/mcaptcha-backend_spec.cr
Normal file
|
@ -0,0 +1,9 @@
|
|||
require "./spec_helper"
|
||||
|
||||
describe Mcaptcha::Backend do
|
||||
# TODO: Write tests
|
||||
|
||||
it "works" do
|
||||
false.should eq(true)
|
||||
end
|
||||
end
|
2
spec/spec_helper.cr
Normal file
2
spec/spec_helper.cr
Normal file
|
@ -0,0 +1,2 @@
|
|||
require "spec"
|
||||
require "../src/mcaptcha-backend"
|
16
src/config.cr
Normal file
16
src/config.cr
Normal file
|
@ -0,0 +1,16 @@
|
|||
require "yaml"
|
||||
|
||||
class Config
|
||||
include YAML::Serializable
|
||||
|
||||
property mcaptchaSitekey : String
|
||||
property mcaptchaAccountSecret : String
|
||||
property mcaptchaInstance : String
|
||||
|
||||
def self.load
|
||||
config_file = "./config.yml"
|
||||
config_yaml = File.read(config_file)
|
||||
config = Config.from_yaml(config_yaml)
|
||||
config
|
||||
end
|
||||
end
|
48
src/mcaptcha-backend.cr
Normal file
48
src/mcaptcha-backend.cr
Normal file
|
@ -0,0 +1,48 @@
|
|||
require "http/client"
|
||||
require "kemal"
|
||||
require "json"
|
||||
require "./config"
|
||||
|
||||
CONFIG = Config.load
|
||||
|
||||
allowed_ips = Array(String).new
|
||||
|
||||
def ip_address(env) : String
|
||||
begin
|
||||
return env.request.headers.try &.["X-Forwarded-For"]
|
||||
rescue
|
||||
return env.request.remote_address.to_s.split(":").first
|
||||
end
|
||||
end
|
||||
|
||||
get "/" do |env|
|
||||
if !allowed_ips.includes?(ip_address(env))
|
||||
render "src/views/captcha.ecr"
|
||||
else
|
||||
render "src/views/main.html"
|
||||
end
|
||||
end
|
||||
|
||||
post "/captcha" do |env|
|
||||
# token = env.params.body["mcaptcha__token"]
|
||||
token = env.params.json["token"]
|
||||
data = JSON.build do |j|
|
||||
j.object do
|
||||
j.field "token", token
|
||||
j.field "key", CONFIG.mcaptchaSitekey
|
||||
j.field "secret", CONFIG.mcaptchaAccountSecret
|
||||
end
|
||||
end
|
||||
req = HTTP::Client.post("https://#{CONFIG.mcaptchaInstance}/api/v1/pow/siteverify",
|
||||
headers: HTTP::Headers{"Content-Type" => "application/json"},
|
||||
body: data)
|
||||
|
||||
if req.success?
|
||||
res = JSON.parse(req.body)
|
||||
end
|
||||
|
||||
allowed_ips << ip_address(env)
|
||||
res
|
||||
end
|
||||
|
||||
Kemal.run
|
97
src/views/captcha.ecr
Normal file
97
src/views/captcha.ecr
Normal file
|
@ -0,0 +1,97 @@
|
|||
<!-- <form id="captcha-form">
|
||||
<label
|
||||
data-mcaptcha_url="https://mcaptcha.nadeko.net/widget/?sitekey=XyyQdgv8Qje0hgAhxgAkrXE8upwa2c2c"
|
||||
for="mcaptcha__token"
|
||||
id="mcaptcha__token-label">
|
||||
mCaptcha authorization token.
|
||||
<a href="https://mcaptcha.org/docs/user-manual/how-to-mcaptcha-without-js/">Instructions</a>
|
||||
<input type="text" name="mcaptcha__token" id="mcaptcha__token" />
|
||||
</label>
|
||||
<div id="mcaptcha__widget-container"></div>
|
||||
<script src="https://unpkg.com/@mcaptcha/vanilla-glue@0.1.0-rc2/dist/index.js"></script>
|
||||
<button type="submit">Submit Form</button>
|
||||
</form> -->
|
||||
|
||||
<!-- <html>
|
||||
|
||||
<head>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<form id="mcaptchaForm" action="/submit-mcaptcha" method="POST">
|
||||
<label data-mcaptcha_url="https://mcaptcha.nadeko.net/widget/?sitekey=XyyQdgv8Qje0hgAhxgAkrXE8upwa2c2c"
|
||||
for="mcaptcha__token" id="mcaptcha__token-label">
|
||||
mCaptcha authorization token.
|
||||
<a href="https://mcaptcha.org/docs/user-manual/how-to-mcaptcha-without-js/">Instructions</a>
|
||||
</label>
|
||||
<div id="mcaptcha__widget-container"></div>
|
||||
<input type="hidden" name="mcaptcha__token" id="mcaptcha__token" />
|
||||
<button type="submit">Submit</button>
|
||||
<script src="https://unpkg.com/@mcaptcha/vanilla-glue@0.1.0-rc2/dist/index.js"></script>
|
||||
</form>
|
||||
</body>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const form = document.getElementById('mcaptchaForm');
|
||||
const captchaInput = document.getElementById('mcaptcha__token');
|
||||
|
||||
form.addEventListener('change', function (e) {
|
||||
if (captchaInput.value && captchaInput.value.trim() !== '') {
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</html> -->
|
||||
|
||||
<iframe name="xd" style="display:none;"></iframe>
|
||||
<!-- <form id="mcaptchaForm" method="POST" action="/captcha" target="xd"> -->
|
||||
<label data-mcaptcha_url="https://<%= CONFIG.mcaptchaInstance %>/widget/?sitekey=<%= CONFIG.mcaptchaSitekey %>"
|
||||
for="mcaptcha__token" id="mcaptcha__token-label">
|
||||
mCaptcha authorization token.
|
||||
<a href="https://mcaptcha.org/docs/user-manual/how-to-mcaptcha-without-js/">Instructions</a>
|
||||
</label>
|
||||
<div id="mcaptcha__widget-container"></div>
|
||||
<input type=" name=" mcaptcha__token" id="mcaptcha__token" />
|
||||
<script src="https://unpkg.com/@mcaptcha/vanilla-glue@0.1.0-rc2/dist/index.js"></script>
|
||||
<!-- </form> -->
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const tokenInput = document.getElementById('mcaptcha__token');
|
||||
|
||||
// Function to send the token value to the server
|
||||
function sendToken(value) {
|
||||
fetch('/captcha', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ token: value }),
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log('Success:', data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
});
|
||||
}
|
||||
|
||||
// Function to monitor input changes
|
||||
function monitorInput() {
|
||||
let previousValue = '';
|
||||
|
||||
setInterval(() => {
|
||||
const currentValue = tokenInput.value;
|
||||
if (currentValue && currentValue !== previousValue) {
|
||||
previousValue = currentValue;
|
||||
sendToken(currentValue);
|
||||
}
|
||||
}, 500); // Check every 500 milliseconds
|
||||
}
|
||||
|
||||
monitorInput();
|
||||
});
|
||||
</script>
|
1
src/views/main.html
Normal file
1
src/views/main.html
Normal file
|
@ -0,0 +1 @@
|
|||
passed
|
Loading…
Reference in a new issue