diff --git a/nimforum.nimble b/nimforum.nimble index 1ea21bd..d6c08f8 100644 --- a/nimforum.nimble +++ b/nimforum.nimble @@ -12,16 +12,16 @@ skipExt = @["nim"] # Dependencies -requires "nim >= 0.18.1" -requires "jester 0.4.0" +requires "nim >= 1.0.6" +requires "jester#d8a03aa" requires "bcrypt#head" requires "hmac#9c61ebe2fd134cf97" -requires "recaptcha 1.0.2" +requires "recaptcha#d06488e" requires "sass#649e0701fa5c" -requires "karax#d8df257dd" +requires "karax#f6bda9a" -requires "webdriver#20f3c1b" +requires "webdriver#c2fee57" # Tasks @@ -36,7 +36,7 @@ task frontend, "Builds the necessary JS frontend (with CSS)": exec "nimble c -r src/buildcss" exec "nimble js -d:release src/frontend/forum.nim" mkDir "public/js" - cpFile "src/frontend/nimcache/forum.js", "public/js/forum.js" + cpFile "src/frontend/forum.js", "public/js/forum.js" task minify, "Minifies the JS using Google's closure compiler": exec "closure-compiler public/js/forum.js --js_output_file public/js/forum.js.opt" diff --git a/src/auth.nim b/src/auth.nim index 0b08bfe..381b666 100644 --- a/src/auth.nim +++ b/src/auth.nim @@ -71,13 +71,13 @@ when isMainModule: "test", "$2a$08$bY85AhoD1e9u0IsD9sM7Ee6kFSLeXRLxJ6rMgfb1wDnU9liaymoTG", 1526908753, - "*B2a] IL\"~sh)q-GBd/i$^>.TL]PR~>1IX>Fp-:M3pCm^cFD\um" + "*B2a] IL\"~sh)q-GBd/i$^>.TL]PR~>1IX>Fp-:M3pCm^cFD\\um" ) let ident2 = makeIdentHash( "test", "$2a$08$bY85AhoD1e9u0IsD9sM7Ee6kFSLeXRLxJ6rMgfb1wDnU9liaymoTG", 1526908753, - "*B2a] IL\"~sh)q-GBd/i$^>.TL]PR~>1IX>Fp-:M3pCm^cFD\um" + "*B2a] IL\"~sh)q-GBd/i$^>.TL]PR~>1IX>Fp-:M3pCm^cFD\\um" ) doAssert ident == ident2 @@ -85,6 +85,6 @@ when isMainModule: "test", "$2a$08$bY85AhoD1e9u0IsD9sM7Ee6kFSLeXRLxJ6rMgfb1wDnU9liaymoTG", 1526908754, - "*B2a] IL\"~sh)q-GBd/i$^>.TL]PR~>1IX>Fp-:M3pCm^cFD\um" + "*B2a] IL\"~sh)q-GBd/i$^>.TL]PR~>1IX>Fp-:M3pCm^cFD\\um" ) - doAssert ident != invalid \ No newline at end of file + doAssert ident != invalid diff --git a/src/forum.nim b/src/forum.nim index ad1ab09..10d3511 100644 --- a/src/forum.nim +++ b/src/forum.nim @@ -8,7 +8,7 @@ import system except Thread import os, strutils, times, md5, strtabs, math, db_sqlite, - scgi, jester, asyncdispatch, asyncnet, sequtils, + jester, asyncdispatch, asyncnet, sequtils, parseutils, random, rst, recaptcha, json, re, sugar, strformat, logging import cgi except setCookie @@ -76,7 +76,6 @@ proc getGravatarUrl(email: string, size = 80): string = # ----------------------------------------------------------------------------- -template `||`(x: untyped): untyped = (if not isNil(x): x else: "") proc validateCaptcha(recaptchaResp, ip: string) {.async.} = # captcha validation: @@ -133,9 +132,9 @@ proc checkLoggedIn(c: TForumData) = let row = getRow(db, sql"select name, email, status from person where id = ?", c.userid) - c.username = ||row[0] - c.email = ||row[1] - c.rank = parseEnum[Rank](||row[2]) + c.username = row[0] + c.email = row[1] + c.rank = parseEnum[Rank](row[2]) # In order to handle the "last visit" line appropriately, i.e. # it shouldn't disappear after a refresh, we need to manage a @@ -463,7 +462,7 @@ proc executeReply(c: TForumData, threadId: int, content: string, crud(crCreate, "post", "author", "ip", "content", "thread", "replyingTo"), c.userId, c.req.ip, content, $threadId, if replyingTo.isSome(): $replyingTo.get() - else: nil + else: "-1" ) discard tryExec( db, diff --git a/src/frontend/error.nim b/src/frontend/error.nim index 4a23c44..06a8d07 100644 --- a/src/frontend/error.nim +++ b/src/frontend/error.nim @@ -86,8 +86,8 @@ when defined(js): state.error = some(error) except: - kout(getCurrentExceptionMsg().cstring) + echo getCurrentExceptionMsg() state.error = some(PostError( errorFields: @[], message: "Unknown error occurred." - )) \ No newline at end of file + )) diff --git a/src/frontend/forum.nim b/src/frontend/forum.nim index 4dea047..5fb11b4 100644 --- a/src/frontend/forum.nim +++ b/src/frontend/forum.nim @@ -49,7 +49,7 @@ proc onPopState(event: dom.Event) = # This event is usually only called when the user moves back in their # history. I fire it in karaxutils.anchorCB as well to ensure the URL is # always updated. This should be moved into Karax in the future. - kout(kstring"New URL: ", window.location.href, " ", state.url.href) + echo "New URL: ", window.location.href, " ", state.url.href document.title = state.originalTitle if state.url.href != window.location.href: state = newState() # Reload the state to remove stale data. diff --git a/src/frontend/karaxutils.nim b/src/frontend/karaxutils.nim index 462d000..2aa9d39 100644 --- a/src/frontend/karaxutils.nim +++ b/src/frontend/karaxutils.nim @@ -25,7 +25,7 @@ proc getInt64*(s: string, default = 0): int64 = when defined(js): include karax/prelude - import karax / [kdom] + import karax / [kdom, kajax] from dom import nil @@ -87,16 +87,10 @@ when defined(js): navigateTo(url) - type - FormData* = ref object - proc newFormData*(): FormData - {.importcpp: "new FormData()", constructor.} proc newFormData*(form: dom.Element): FormData {.importcpp: "new FormData(@)", constructor.} proc get*(form: FormData, key: cstring): cstring {.importcpp: "#.get(@)".} - proc append*(form: FormData, key, val: cstring) - {.importcpp: "#.append(@)".} proc renderProfileUrl*(username: string): string = makeUri(fmt"/profile/{username}") @@ -120,4 +114,4 @@ when defined(js): inc(i) # Skip = i += query.parseUntil(val, '&', i) inc(i) # Skip & - result[$decodeUri(key)] = $decodeUri(val) \ No newline at end of file + result[$decodeUri(key)] = $decodeUri(val) diff --git a/src/frontend/login.nim b/src/frontend/login.nim index f0779c7..c19088e 100644 --- a/src/frontend/login.nim +++ b/src/frontend/login.nim @@ -1,6 +1,6 @@ when defined(js): import sugar, httpcore, options, json - import dom except Event + import dom except Event, KeyboardEvent include karax/prelude import karax / [kajax, kdom] @@ -93,4 +93,4 @@ when defined(js): (state.onSignUp(); state.shown = false)): text "Create account" - render(state.resetPasswordModal, recaptchaSiteKey) \ No newline at end of file + render(state.resetPasswordModal, recaptchaSiteKey) diff --git a/src/frontend/replybox.nim b/src/frontend/replybox.nim index 9d815f6..e386dcb 100644 --- a/src/frontend/replybox.nim +++ b/src/frontend/replybox.nim @@ -26,7 +26,7 @@ when defined(js): proc performScroll() = let replyBox = dom.document.getElementById("reply-box") - replyBox.scrollIntoView(false) + replyBox.scrollIntoView() proc show*(state: ReplyBox) = # Scroll to the reply box. @@ -44,7 +44,7 @@ when defined(js): proc onPreviewPost(httpStatus: int, response: kstring, state: ReplyBox) = postFinished: - kout(response) + echo response state.rendering = some[kstring](response) proc onPreviewClick(e: Event, n: VNode, state: ReplyBox) = diff --git a/src/frontend/resetpassword.nim b/src/frontend/resetpassword.nim index c2f01a1..51b467b 100644 --- a/src/frontend/resetpassword.nim +++ b/src/frontend/resetpassword.nim @@ -1,6 +1,6 @@ when defined(js): import sugar, httpcore, options, json - import dom except Event + import dom except Event, KeyboardEvent include karax/prelude import karax / [kajax, kdom] @@ -152,4 +152,4 @@ when defined(js): ), `type`="button", onClick=(ev: Event, n: VNode) => onClick(ev, n, state)): - text "Reset password" \ No newline at end of file + text "Reset password" diff --git a/src/frontend/threadlist.nim b/src/frontend/threadlist.nim index 0516d74..b3b3d81 100644 --- a/src/frontend/threadlist.nim +++ b/src/frontend/threadlist.nim @@ -60,7 +60,7 @@ when defined(js): if user.isNone(): return not thread.isModerated let rank = user.get().rank - if rank < Moderator and thread.isModerated: + if rank < Rank.Moderator and thread.isModerated: return thread.author == user.get() return true diff --git a/src/utils.nim b/src/utils.nim index 2676ab8..1be058b 100644 --- a/src/utils.nim +++ b/src/utils.nim @@ -10,11 +10,6 @@ let import frontend/[karaxutils, error] export parseInt -proc `%`*[T](opt: Option[T]): JsonNode = - ## Generic constructor for JSON data. Creates a new ``JNull JsonNode`` - ## if ``opt`` is empty, otherwise it delegates to the underlying value. - if opt.isSome: %opt.get else: newJNull() - type Config* = object smtpAddress*: string @@ -56,7 +51,7 @@ proc loadConfig*(filename = getCurrentDir() / "forum.json"): Config = smtpPassword: "", mlistAddress: "") let root = parseFile(filename) result.smtpAddress = root{"smtpAddress"}.getStr("") - result.smtpPort = root{"smtpPort"}.getNum(25).int + result.smtpPort = root{"smtpPort"}.getInt(25) result.smtpUser = root{"smtpUser"}.getStr("") result.smtpPassword = root{"smtpPassword"}.getStr("") result.smtpFromAddr = root{"smtpFromAddr"}.getStr("") @@ -69,7 +64,7 @@ proc loadConfig*(filename = getCurrentDir() / "forum.json"): Config = result.name = root["name"].getStr() result.title = root["title"].getStr() result.ga = root{"ga"}.getStr() - result.port = root{"port"}.getNum(5000).int + result.port = root{"port"}.getInt(5000) proc processGT(n: XmlNode, tag: string): (int, XmlNode, string) = result = (0, newElement(tag), tag) diff --git a/tests/browsertester.nim b/tests/browsertester.nim index 0f4efe9..4e03081 100644 --- a/tests/browsertester.nim +++ b/tests/browsertester.nim @@ -45,7 +45,7 @@ template withBackend(body: untyped): untyped = import browsertests/[scenario1, threads, issue181] -when isMainModule: +proc main() = spawn runProcess("geckodriver -p 4444 --log config") defer: discard execCmd("killall geckodriver") @@ -70,3 +70,6 @@ when isMainModule: except: sleep(10000) # See if we can grab any more output. raise + +when isMainModule: + main()