diff --git a/captchas.nim b/captchas.nim
deleted file mode 100644
index f569f04..0000000
--- a/captchas.nim
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-#
-# The Nim Forum
-# (c) Copyright 2012 Andreas Rumpf, Dominik Picheta
-# Look at license.txt for more info.
-# All rights reserved.
-#
-
-import cairo, os, strutils, jester
-
-proc getCaptchaFilename*(i: int): string {.inline.} =
- result = "public/captchas/capture_" & $i & ".png"
-
-proc getCaptchaUrl*(req: Request, i: int): string =
- result = req.makeUri("/captchas/capture_" & $i & ".png", absolute = false)
-
-proc createCaptcha*(file, text: string) =
- var surface = imageSurfaceCreate(FORMAT_ARGB32, int32(10*text.len), int32(10))
- var cr = create(surface)
-
- selectFontFace(cr, "serif", FONT_SLANT_NORMAL, FONT_WEIGHT_BOLD)
- setFontSize(cr, 12.0)
-
- setSourceRgb(cr, 1.0, 0.5, 0.0)
- moveTo(cr, 0.0, 10.0)
- showText(cr, repeat('O', text.len))
-
- setSourceRgb(cr, 0.0, 0.0, 1.0)
- moveTo(cr, 0.0, 10.0)
- showText(cr, text)
-
- destroy(cr)
- discard writeToPng(surface, file)
- destroy(surface)
-
-when isMainModule:
- createCaptcha("test.png", "1+33")
diff --git a/forms.tmpl b/forms.tmpl
index 9d62d95..9f6d2a7 100644
--- a/forms.tmpl
+++ b/forms.tmpl
@@ -249,10 +249,12 @@
${fieldValid(c, "email", "E-Mail:")} |
${textWidget(c, "email", reuseText, maxlength=300)} |
+ #if useCaptcha:
- | ${fieldValid(c, "antibot", "What is " & antibot(c) & "?")} |
- ${textWidget(c, "antibot", "", maxlength=4)} |
+ ${fieldValid(c, "g-recaptcha-response", "Captcha:")} |
+ ${captcha.render(includeNoScript=true)} |
+ #end if
#if c.errorMsg != "":
diff --git a/forum.json.example b/forum.json.example
new file mode 100644
index 0000000..8cf9e86
--- /dev/null
+++ b/forum.json.example
@@ -0,0 +1,4 @@
+{
+ "recaptchaSecretKey": "",
+ "recaptchaSiteKey": ""
+}
\ No newline at end of file
diff --git a/forum.nim b/forum.nim
index 7414144..3222112 100644
--- a/forum.nim
+++ b/forum.nim
@@ -8,8 +8,8 @@
import
os, strutils, times, md5, strtabs, cgi, math, db_sqlite,
- captchas, scgi, jester, asyncdispatch, asyncnet, cache, sequtils,
- parseutils, utils, random, rst, ranks
+ scgi, jester, asyncdispatch, asyncnet, cache, sequtils,
+ parseutils, utils, random, rst, ranks, recaptcha
when not defined(windows):
import bcrypt # TODO
@@ -77,6 +77,8 @@ var
db: DbConn
isFTSAvailable: bool
config: Config
+ useCaptcha: bool
+ captcha: ReCaptcha
proc init(c: var TForumData) =
c.userPass = ""
@@ -314,8 +316,16 @@ proc register(c: var TForumData, name, pass, antibot,
return setError(c, "new_password", "Invalid password!")
# captcha validation:
- if not isCaptchaCorrect(c, antibot):
- return setError(c, "antibot", "Answer to captcha incorrect!")
+ if useCaptcha:
+ var captchaValid: bool = false
+ try:
+ captchaValid = waitFor captcha.verify(antibot)
+ except:
+ echo("[ERROR] Error checking captcha: " & getCurrentExceptionMsg())
+ captchaValid = false
+
+ if not captchaValid:
+ return setError(c, "antibot", "Answer to captcha incorrect!")
# email validation
if not ('@' in email and '.' in email):
@@ -1123,7 +1133,7 @@ routes:
post "/doregister":
createTFD()
- if c.register(@"name", @"new_password", @"antibot", @"email"):
+ if c.register(@"name", @"new_password", @"g-recaptcha-response", @"email"):
resp genMain(c, "You are now registered. You must now confirm your" &
" email address by clicking the link sent to " & @"email",
"Registration successful - Nim Forum")
@@ -1353,6 +1363,11 @@ when isMainModule:
isFTSAvailable = db.getAllRows(sql("SELECT name FROM sqlite_master WHERE " &
"type='table' AND name='post_fts'")).len == 1
config = loadConfig()
+ if len(config.recaptchaSecretKey) > 0 and len(config.recaptchaSiteKey) > 0:
+ useCaptcha = true
+ captcha = initReCaptcha(config.recaptchaSecretKey, config.recaptchaSiteKey)
+ else:
+ useCaptcha = false
var http = true
if paramCount() > 0:
if paramStr(1) == "scgi":
diff --git a/forum.nim.cfg b/forum.nim.cfg
index 429dc5b..3af1ac0 100644
--- a/forum.nim.cfg
+++ b/forum.nim.cfg
@@ -2,3 +2,5 @@
# we need the documentation generator of the compiler:
path="$lib/packages/docutils"
path="$nim"
+
+-d:ssl
\ No newline at end of file
diff --git a/nimforum.nimble b/nimforum.nimble
index 3591767..b0cdb09 100644
--- a/nimforum.nimble
+++ b/nimforum.nimble
@@ -8,4 +8,4 @@ license = "MIT"
bin = "forum"
[Deps]
-Requires: "nim >= 0.14.0, cairo#head, jester#head, bcrypt#head"
+Requires: "nim >= 0.14.0, cairo#head, jester#head, bcrypt#head, recaptcha >= 1.0.0"
diff --git a/public/captchas/.gitignore b/public/captchas/.gitignore
deleted file mode 100644
index d6b7ef3..0000000
--- a/public/captchas/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*
-!.gitignore
diff --git a/utils.nim b/utils.nim
index 002ee94..ce48804 100644
--- a/utils.nim
+++ b/utils.nim
@@ -22,6 +22,8 @@ type
smtpUser: string
smtpPassword: string
mlistAddress: string
+ recaptchaSecretKey*: string
+ recaptchaSiteKey*: string
var docConfig: StringTableRef
@@ -38,6 +40,8 @@ proc loadConfig*(filename = getCurrentDir() / "forum.json"): Config =
result.smtpUser = root{"smtpUser"}.getStr("")
result.smtpPassword = root{"smtpPassword"}.getStr("")
result.mlistAddress = root{"mlistAddress"}.getStr("")
+ result.recaptchaSecretKey = root{"recaptchaSecretKey"}.getStr("")
+ result.recaptchaSiteKey = root{"recaptchaSiteKey"}.getStr("")
except:
echo("[WARNING] Couldn't read config file: ", filename)