From 84a80ded03494eab67c3a9361a5a76351732beb7 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sun, 20 May 2018 21:21:19 +0100 Subject: [PATCH] Implements /activateEmail and changes how expiry is determined. --- src/auth.nim | 4 ++-- src/forum.nim | 29 ++++++++++++++++++++++++++--- src/frontend/forum.nim | 6 +++--- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/auth.nim b/src/auth.nim index 21588a4..13ef180 100644 --- a/src/auth.nim +++ b/src/auth.nim @@ -49,8 +49,8 @@ proc makeIdentHash*(user, password: string, epoch: int64, secret: string, comparingTo = ""): string = ## Creates a hash verifying the identity of a user. Used for password reset ## links and email activation links. - ## If ``epoch`` is smaller than the epoch of the user's last login then - ## the link is invalid. + ## The ``epoch`` determines the creation time of this hash, it will be checked + ## during verification to ensure the hash hasn't expired. ## The ``secret`` is the 'salt' field in the ``person`` table. when defined(windows): result = getMD5(user & password & $epoch & secret) diff --git a/src/forum.nim b/src/forum.nim index 970e31b..0ef53fc 100644 --- a/src/forum.nim +++ b/src/forum.nim @@ -240,9 +240,9 @@ proc verifyIdentHash( if row[0] == "": raise newForumError("User doesn't exist.", @["nick"]) let newIdent = makeIdentHash(name, row[0], epoch, row[1], ident) - # Check that the user has not been logged in since this ident hash has been - # created. Give the timestamp a certain range to prevent false negatives. - if row[2].parseInt > (epoch + 60*3): + # Check that it hasn't expired. + let diff = getTime() - epoch.fromUnix() + if diff.hours > 2: raise newForumError("Link expired") if newIdent != ident: raise newForumError("Invalid ident hash") @@ -576,6 +576,8 @@ proc executeRegister(c: TForumData, name, pass, antibot, userIp, ## Registers a new user and returns a new session key for that user's ## session if registration was successful. Exceptions are raised otherwise. + # TODO: Ignore deleted accounts in duplicate checks. + # email validation validateEmail(email, checkDuplicated=true) @@ -1279,6 +1281,27 @@ routes: except ForumError as exc: resp Http400, $(%exc.data),"application/json" + get "/activateEmail": + createTFD() + cond(@"nick" != "") + cond(@"epoch" != "") + cond(@"ident" != "") + let epoch = getInt64(@"epoch", -1) + try: + verifyIdentHash(c, @"nick", epoch, @"ident") + + exec( + db, + sql""" + update person set status = ?, lastOnline = DATETIME('now') + where name = ?; + """, + $Rank.Moderated, @"nick" + ) + redirect(uri("/activateEmail/success")) + except ForumError as exc: + redirect(uri("/activateEmail/failure/" & encodeUrl(exc.data.message))) + get "/t/@id": cond "id" in request.params diff --git a/src/frontend/forum.nim b/src/frontend/forum.nim index 35cdafc..e892549 100644 --- a/src/frontend/forum.nim +++ b/src/frontend/forum.nim @@ -1,4 +1,4 @@ -import strformat, times, options, json, tables, sugar, httpcore +import strformat, times, options, json, tables, sugar, httpcore, uri from dom import window, Location include karax/prelude @@ -104,11 +104,11 @@ proc render(): VNode = ) ) ), - r("/activateEmail/failure", + r("/activateEmail/failure/@msg", (params: Params) => ( renderMessage( "Email activation failed", - "Couldn't verify the supplied ident", + decodeUrl(params["msg"]), "fa-exclamation" ) )