summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.md40
-rw-r--r--lang/de.lang1
-rw-r--r--lib/JWebmail/Controller/Webmail.pm15
-rw-r--r--lib/JWebmail/Model/ReadMails/MockJSON.pm7
-rw-r--r--lib/JWebmail/Model/ReadMails/Role.pm2
-rw-r--r--lib/JWebmail/Plugin/Helper.pm9
-rw-r--r--public/style2.css5
-rw-r--r--templates/webmail/login.html.ep26
-rw-r--r--templates/webmail/readmail.html.ep2
-rw-r--r--templates/webmail/writemail.html.ep3
10 files changed, 79 insertions, 31 deletions
diff --git a/CHANGES.md b/CHANGES.md
index 54f53d0..e4dd1b1 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -113,13 +113,6 @@ Current v1.1.0
- [ ] QMailAuthuser
- [x] repurpose status column in displayheader
- [x] currently just renamed to 'Multipart'
-- [x] advance ini config plugin
- - [x] allow non-leaf nodes to be arrays
- - [ ] allow quotes
- - [ ] allow continuation over multiple lines
- - [ ] warn about overrides
- - [ ] add template support, maybe
- - [ ] switch to TOML or a provided format, as INI is too basic
- [x] refactor ReadMails into a role
- [x] made languages in about clickable
- [x] make loading auth data from session easier
@@ -128,16 +121,15 @@ Current v1.1.0
- [x] merge read and raw (with content type)
- how does one extract the body functionality? (One does not.)
- [x] refactor templates to make use of link_to
-- [x] improve html styling (especially for mobile)
+- [ ] improve html styling (especially for mobile)
- [x] about
- [x] displayheaders
- [x] nocation
- [x] readmail
- [x] writemail
-- [ ] improve i18n
- - [ ] add localization of dates and time
- - [x] refactor I18N plugin to allow independent translate provider
- - [x] extend matcher dynamic with a role
+ - [x] mobile optimize
+ - [ ] cleanup css
+ - [ ] improve styling of read- and writemail
- [ ] fix tests
- [ ] moving mails to other folders
- [ ] creating new folders
@@ -154,9 +146,24 @@ Current v1.1.0
- [ ] add exception types
- [x] added exception for QMailAuthuser
- [ ] extract version for Makefile.PL from Application
-- [ ] add config validation
-- [ ] read and write s3d only once per request ($c->on('finish'))
-- [ ] compute h-mac on the client side
+- [ ] add basic telemetry (goatcounter?)
+- [ ] make mime_render return a mojo bytes object
+
+- [ ] advance ini config plugin
+ - [x] allow non-leaf nodes to be arrays
+ - [ ] allow quotes
+ - [ ] allow continuation over multiple lines
+ - [ ] warn about overrides
+ - [ ] add template support, maybe
+ - [ ] switch to TOML or a provided format, as INI is too basic
+ - [ ] add config validation
+- [ ] improve i18n
+ - [ ] add localization of dates and time
+ - [x] refactor I18N plugin to allow independent translate provider
+ - [x] extend matcher dynamic with a role
+- [x] compute hmac on the client side
+ - [x] better handling on form
+ - [ ] better random numbers
Future
------
@@ -185,9 +192,7 @@ Future
- [ ] better pagination
- [ ] merge with partial templates, maybe
- [ ] click on sender to answer
-- [ ] mobile optimize
- [ ] download mail and attachments
-- [ ] cleanup css
- [ ] allow multiple attachments
- [ ] add mails to Sent folder
- [ ] smtp send model, maybe
@@ -197,3 +202,4 @@ Future
- [ ] think about forgot password feature
- [ ] address book support
- [ ] add links on email addresses in header : click = add into address book
+- [ ] read and write s3d only once per request ($c->on('finish'))
diff --git a/lang/de.lang b/lang/de.lang
index 7aaf598..c508854 100644
--- a/lang/de.lang
+++ b/lang/de.lang
@@ -36,6 +36,7 @@ last = letzte
first = erste
previous = vorherige
sender = gesendet von
+back = zurück
# Mailboxen
Queue = Warteschlange
diff --git a/lib/JWebmail/Controller/Webmail.pm b/lib/JWebmail/Controller/Webmail.pm
index ee4a532..bdd7176 100644
--- a/lib/JWebmail/Controller/Webmail.pm
+++ b/lib/JWebmail/Controller/Webmail.pm
@@ -31,7 +31,7 @@ sub auth {
my $self = shift;
my $user = $self->session(S_USER);
- my $pw = $self->session_passwd;
+ my ($pw, $ch) = $self->session_passwd;
unless ($user && $pw) {
$self->flash(message => $self->l('no_session'));
@@ -40,9 +40,7 @@ sub auth {
return 0;
}
- my $authConf = {user => $user, password => $pw};
- $authConf->{challenge} = $self->app->secrets->[0] if $self->config->{session}{secure} eq 'cram';
- $self->stash(ST_AUTH() => $self->users->Auth($authConf));
+ $self->stash(ST_AUTH() => $self->users->Auth(user => $user, password => $pw, challenge => $ch));
return 1;
}
@@ -67,10 +65,16 @@ sub _time :prototype(&$$) {
sub login {
my $self = shift;
+ my $uses_cram = $self->config->{session}{secure} eq 'cram';
+
my $v = $self->validation;
my $user = $v->required('userid')->size(4, 50)->param;
my $passwd = $v->required('password')->size(4, 50)->like(qr/^.+$/)->param; # no new-lines
+ my $challenge;
+ if ($uses_cram) {
+ $challenge = $v->required('challenge')->size(4, 50)->param; # no new-lines
+ }
if ($v->has_error) {
$self->render(status => 400);
@@ -78,11 +82,12 @@ sub login {
}
my $auth = $self->users->Auth(user => $user, password => $passwd);
+ $auth->{challenge} = $challenge if $uses_cram;
my $valid = _time { $self->users->verify_user($auth) } $self, 'verify user';
if ($valid) {
$self->session(S_USER() => $user);
- $self->session_passwd($passwd);
+ $self->session_passwd($passwd, $challenge);
$self->res->code(303);
$self->redirect_to('displayheaders');
diff --git a/lib/JWebmail/Model/ReadMails/MockJSON.pm b/lib/JWebmail/Model/ReadMails/MockJSON.pm
index 7decb7d..345573c 100644
--- a/lib/JWebmail/Model/ReadMails/MockJSON.pm
+++ b/lib/JWebmail/Model/ReadMails/MockJSON.pm
@@ -6,8 +6,9 @@ use utf8;
use List::Util 'sum';
-use Mojo::JSON qw(decode_json);
+use Mojo::JSON 'decode_json';
+use Digest::HMAC_MD5 'hmac_md5_hex';
use Role::Tiny::With;
use namespace::clean;
@@ -51,6 +52,10 @@ sub verify_user {
my $self = shift;
my $auth = shift;
+ if ($auth->{challenge}) {
+ my $res = hmac_md5_hex($auth->{challenge}, VALID_PW);
+ return $auth->{user} eq VALID_USER && $auth->{password} eq $res;
+ }
return $auth->{user} eq VALID_USER && $auth->{password} eq VALID_PW;
}
diff --git a/lib/JWebmail/Model/ReadMails/Role.pm b/lib/JWebmail/Model/ReadMails/Role.pm
index d6472a1..466e3b0 100644
--- a/lib/JWebmail/Model/ReadMails/Role.pm
+++ b/lib/JWebmail/Model/ReadMails/Role.pm
@@ -20,7 +20,7 @@ sub Auth {
state $AuthCheck = {
user => {defined => 1, required => 1},
password => {defined => 1, required => 1},
- challenge => {defined => 1},
+ challenge => {},
};
my $self = @_ == 1 ? $_[0] : {@_};
diff --git a/lib/JWebmail/Plugin/Helper.pm b/lib/JWebmail/Plugin/Helper.pm
index cd72bfa..5edb4af 100644
--- a/lib/JWebmail/Plugin/Helper.pm
+++ b/lib/JWebmail/Plugin/Helper.pm
@@ -3,6 +3,7 @@ package JWebmail::Plugin::Helper;
use Mojo::Base Mojolicious::Plugin;
use List::Util qw(all min max);
+use Carp 'carp';
use POSIX qw(floor round log ceil);
use Mojo::Util qw(encode decode b64_encode b64_decode xml_escape);
@@ -156,7 +157,7 @@ sub _rand_data {
}
sub session_passwd {
- my ($c, $passwd) = @_;
+ my ($c, $passwd, $challenge) = @_;
my $secAlg = $c->config->{session}{secure};
die "you need to install Digest::HMAC_MD5 for cram to work"
@@ -165,7 +166,7 @@ sub session_passwd {
if (defined $passwd) { # set
if ($secAlg eq 'cram') {
- $c->session(S_PASSWD() => $passwd ? b64_encode(hmac_md5($passwd, $c->app->secrets->[0]), '') : '');
+ $c->session(S_PASSWD() => $passwd, challenge => $challenge);
}
elsif ($secAlg eq 's3d') {
unless ($passwd) {
@@ -187,8 +188,8 @@ sub session_passwd {
}
else { # get
if ($secAlg eq 'cram') {
- wantarray or warn "you forgot the challenge";
- return ($c->app->secrets->[0], $c->session(S_PASSWD));
+ wantarray or carp "you forgot the challenge";
+ return ($c->session('challenge'), $c->session(S_PASSWD));
}
elsif ($secAlg eq 's3d') {
my $pw = b64_decode($c->s3d(S_PASSWD) || '');
diff --git a/public/style2.css b/public/style2.css
index 664771a..81841e2 100644
--- a/public/style2.css
+++ b/public/style2.css
@@ -49,6 +49,11 @@ footer {
padding: 0 1rem;
}
+.jwm-mail-header {
+ background-color: var(--jwm-color-front);
+ padding: 1rem;
+}
+
.jwm-mail-body {
width: 80%;
margin: 0rem auto;
diff --git a/templates/webmail/login.html.ep b/templates/webmail/login.html.ep
index 3e224a8..0b7b080 100644
--- a/templates/webmail/login.html.ep
+++ b/templates/webmail/login.html.ep
@@ -1,5 +1,7 @@
% layout 'mainlayout';
+% my $uses_cram = config->{session}{secure} eq 'cram';
+
<div id=login class="jwm-base">
<h1>
@@ -22,14 +24,36 @@
%= label_for password => ucfirst l 'passwd'
%= password_field 'password' => (required => '')
</div>
+% if ($uses_cram) {
+ %= hidden_field challenge => rand
+% }
<div class="pure-controls">
- %= submit_button l('login') => (class => 'pure-button pure-button-primary')
+ %= submit_button l('login') => (class => 'pure-button pure-button-primary') => (name => 'submit_button') => $uses_cram ? (disabled => '') : ()
</div>
</fieldset>
% end
</div>
+% if ($uses_cram) {
+<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"
+ integrity="sha512-E8QSvWZ0eCLGk4km3hxSsNmGWbLtSCSUcewDQPQWZF6pEU8GlT8a5fF32wOl1i8ftdMhssTrF/OhyGWwonTcXA=="
+ crossorigin="anonymous" referrerpolicy="no-referrer"></script>
+<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/hmac-md5.min.js"
+ integrity="sha512-gy8JaBxTrtIxNLe1FfMAXey61VjQk3Af4EyY/EpVfmWPH16iCgdRZMHEFgKIyxMrarlc6+rDf6WneGL4SWqnpg=="
+ crossorigin="anonymous" referrerpolicy="no-referrer"></script>
+
+<script>
+ document.login1.submit_button.disabled = false;
+
+ document.forms.login1.addEventListener("formdata", (form_data_evt) => {
+ const form_data = form_data_evt.formData;
+ const res = CryptoJS.HmacMD5(form_data.get("challenge"), form_data.get("password"))
+ form_data.set("password", res)
+ });
+</script>
+% }
+
%= javascript begin
if (!document.login1.userid.value) {
document.login1.userid.focus();
diff --git a/templates/webmail/readmail.html.ep b/templates/webmail/readmail.html.ep
index f39dd0e..5bad9f3 100644
--- a/templates/webmail/readmail.html.ep
+++ b/templates/webmail/readmail.html.ep
@@ -12,7 +12,7 @@
<h1>Read Mail</h1>
- <dl>
+ <dl class="jwm-mail-header">
<dt> <%= uc l 'subject' %> </dt>
<dd> <%= $msg->{head}{subject} %> </dd>
diff --git a/templates/webmail/writemail.html.ep b/templates/webmail/writemail.html.ep
index 6342927..9d148c1 100644
--- a/templates/webmail/writemail.html.ep
+++ b/templates/webmail/writemail.html.ep
@@ -27,7 +27,8 @@
%= email_field 'back_to'
%= label_for txt => ucfirst l 'content'
- %= text_area body => (cols => 80) => (rows => 24) => (name => 'txt')
+ %# text_area body => (cols => 80) => (rows => 24) => (name => 'txt')
+ %= text_area body => (style => 'width: 100%') => (rows => 24) => (name => 'txt')
%= label_for attach => ucfirst l 'attach file'
%= file_field 'attach'