Implements /activateEmail and changes how expiry is determined.

This commit is contained in:
Dominik Picheta 2018-05-20 21:21:19 +01:00
commit 84a80ded03
3 changed files with 31 additions and 8 deletions

View file

@ -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)

View file

@ -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

View file

@ -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"
)
)