summaryrefslogtreecommitdiff
path: root/lib/VNWeb/User/Login.pm
blob: 7c93e0581b4d1db8c0a0230d36c88459172cf7df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package VNWeb::User::Login;

use VNWeb::Prelude;


TUWF::get '/u/login' => sub {
    return tuwf->resRedirect('/', 'temp') if auth;

    my $ref = tuwf->reqGet('ref');
    $ref = '/' if !$ref || $ref !~ /^\//;

    framework_ title => 'Login', sub {
        elm_ 'User.Login' => tuwf->compile({}), $ref;
    };
};


json_api '/u/login', {
    username => { username => 1 },
    password => { password => 1 }
}, sub {
    my $data = shift;

    my $ip = norm_ip tuwf->reqIP;
    my $tm = tuwf->dbVali(
        'SELECT', sql_totime('greatest(timeout, now())'), 'FROM login_throttle WHERE ip =', \$ip
    ) || time;
    return elm_LoginThrottle if $tm-time() > config->{login_throttle}[1];

    my $insecure = is_insecurepass $data->{password};
    return $insecure ? elm_InsecurePass : elm_Success
        if auth->login($data->{username}, $data->{password}, $insecure);

    # Failed login, update throttle.
    my $upd = {
        ip      => \$ip,
        timeout => sql_fromtime $tm + config->{login_throttle}[0]
    };
    tuwf->dbExeci('INSERT INTO login_throttle', $upd, 'ON CONFLICT (ip) DO UPDATE SET', $upd);
    elm_BadLogin
};


json_api '/u/changepass', {
    username => { username => 1 },
    oldpass  => { password => 1 },
    newpass  => { password => 1 },
}, sub {
    my $data = shift;
    my $uid = tuwf->dbVali('SELECT id FROM users WHERE username =', \$data->{username});
    die if !$uid;
    return elm_InsecurePass if is_insecurepass $data->{newpass};
    die if !auth->setpass($uid, undef, $data->{oldpass}, $data->{newpass}); # oldpass should already have been verified.
    elm_Success
};


TUWF::post qr{/$RE{uid}/logout}, sub {
    return tuwf->resNotFound if !auth || auth->uid != tuwf->capture('id') || (tuwf->reqPost('csrf')||'') ne auth->csrftoken;
    auth->logout;
    tuwf->resRedirect('/', 'post');
};

1;