Repository: Mailu/Mailu

Issue:
Can't Login as admin on initial creation
<!--

Thank you for opening an issue with Mailu. Please understand that issues are meant for bugs and enhancement-requests.
For **user-support questions**, reach out to us  on [matrix](https://matrix.to/#/#mailu:tedomum.net).

To be able to help you best, we need some more information.

Before you open your issue
- Check if no issue or pull-request for this already exists.
- Check [documentation](https://mailu.io/master/) and [FAQ](https://mailu.io/master/faq.html). (Tip, use the search function on the documentation page)
- You understand `Mailu` is made by volunteers in their **free time** — be concise, civil and accept that delays can occur.
- The title of the issue should be short and simple. It should contain specific terms related to the actual issue. Be specific while writing the title.

Please put your text outside of the comment blocks to be visible. You can use the button "Preview" above to check.

-->

## Environment & Version

### Environment

- [X] docker-compose
- [ ] kubernetes
- [ ] docker swarm

### Version

- Version: `1.9`

<!--
To find your version, get the image name of a mailu container and read  the version from the tag (example for version 1.7).

$> docker ps -a | grep mailu
140b09d4b09c    mailu/roundcube:1.7    "docker-php-entrypoi…"    2 weeks ago    Up 2 days (healthy)    80/tcp
$> grep MAILU_VERSION docker-compose.yml mailu.env
-->

## Description
<!--
Further explain the bug in a few words. It should be clear what the unexpected behaviour is.  Share it in an easy-to-understand language.
-->

## Replication Steps
<!--
Steps for replicating your issue
-->
Deploy this docker-compose.yml:
```yaml
# This file is auto-generated by the Mailu configuration wizard.
# Please read the documentation before attempting any change.
# Generated for compose flavor

version: '2.2'

services:

  # External dependencies
  redis:
    image: redis:alpine
    restart: always
    volumes:
      - "/mailu/redis:/data"
    dns: "192.168.222.1" # pfsense running unbound with DNSSEC enabled

  # Core services
  front:
    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-1.9}
    restart: always
    env_file: mailu.env
    logging:
      driver: json-file
    ports:
      - "192.168.222.83:80:80"
      - "192.168.222.83:443:443"
      - "192.168.222.83:25:25"
      - "192.168.222.83:465:465"
      - "192.168.222.83:587:587"
      - "192.168.222.83:110:110"
      - "192.168.222.83:995:995"
      - "192.168.222.83:143:143"
      - "192.168.222.83:993:993"
    volumes:
      - "/mailu/certs:/certs"
      - "/mailu/overrides/nginx:/overrides:ro"
    dns: "192.168.222.1"

  admin:
    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-1.9}
    restart: always
    env_file: mailu.env
    volumes:
      - "/mailu/data:/data"
      - "/mailu/dkim:/dkim"
    depends_on:
      - redis
    dns: "192.168.222.1"

  imap:
    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-1.9}
    restart: always
    env_file: mailu.env
    volumes:
      - "/mailu/mail:/mail"
      - "/mailu/overrides/dovecot:/overrides:ro"
    depends_on:
      - front
    dns: "192.168.222.1"

  smtp:
    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${MAILU_VERSION:-1.9}
    restart: always
    env_file: mailu.env
    volumes:
      - "/mailu/mailqueue:/queue"
      - "/mailu/overrides/postfix:/overrides:ro"
    depends_on:
      - front
    dns: "192.168.222.1"

  antispam:
    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-1.9}
    hostname: antispam
    restart: always
    env_file: mailu.env
    volumes:
      - "/mailu/filter:/var/lib/rspamd"
      - "/mailu/overrides/rspamd:/etc/rspamd/override.d:ro"
    depends_on:
      - front
    dns: "192.168.222.1"

  # Optional services
  antivirus:
    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}clamav:${MAILU_VERSION:-1.9}
    restart: always
    env_file: mailu.env
    volumes:
      - "/mailu/filter:/data"
    dns: "192.168.222.1"

  webdav:
    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}radicale:${MAILU_VERSION:-1.9}
    restart: always
    env_file: mailu.env
    volumes:
      - "/mailu/dav:/data"
    dns: "192.168.222.1"

  fetchmail:
    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}fetchmail:${MAILU_VERSION:-1.9}
    restart: always
    env_file: mailu.env
    volumes:
      - "/mailu/data/fetchmail:/data"
    dns: "192.168.222.1"

  # Webmail
  webmail:
    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rainloop:${MAILU_VERSION:-1.9}
    restart: always
    env_file: mailu.env
    volumes:
      - "/mailu/webmail:/data"
      - "/mailu/overrides/rainloop:/overrides:ro"
    depends_on:
      - imap
    dns: "192.168.222.1"

networks:
  default:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 192.168.203.0/24
```
with this mailu.env:
```ini
# Mailu main configuration file
#
# This file is autogenerated by the configuration management wizard for compose flavor.
# For a detailed list of configuration variables, see the documentation at
# https://mailu.io

###################################
# Common configuration variables
###################################

# Set to a randomly generated 16 bytes string
SECRET_KEY=SOQJVE139OEKUPY3

# Subnet of the docker network. This should not conflict with any networks to which your system is connected. (Internal and external!)
SUBNET=192.168.203.0/24

# Main mail domain
DOMAIN=mail.lab.arpa

# Hostnames for this server, separated with comas
HOSTNAMES=mail.lab.arpa,docker.lab.arpa

# Postmaster local part (will append the main mail domain)
POSTMASTER=admin

# Choose how secure connections will behave (value: letsencrypt, cert, notls, mail, mail-letsencrypt)
TLS_FLAVOR=notls

# Authentication rate limit per IP (per /24 on ipv4 and /56 on ipv6)
AUTH_RATELIMIT_IP=60/hour

# Authentication rate limit per user (regardless of the source-IP)
AUTH_RATELIMIT_USER=100/day

# Opt-out of statistics, replace with "True" to opt out
DISABLE_STATISTICS=False

###################################
# Optional features
###################################

# Expose the admin interface (value: true, false)
ADMIN=true
INITIAL_ADMIN_ACCOUNT=admin
INITIAL_ADMIN_DOMAIN=mail.lab.arpa
INITIAL_ADMIN_PW=5ecret!
INITIAL_ADMIN_MODE=update

# Choose which webmail to run if any (values: roundcube, rainloop, none)
WEBMAIL=rainloop

# Dav server implementation (value: radicale, none)
WEBDAV=radicale

# Antivirus solution (value: clamav, none)
ANTIVIRUS=clamav

###################################
# Mail settings
###################################

# Message size limit in bytes
# Default: accept messages up to 50MB
# Max attachment size will be 33% smaller
MESSAGE_SIZE_LIMIT=50000000

# Message rate limit (per user)
MESSAGE_RATELIMIT=200/day

# Networks granted relay permissions
# Use this with care, all hosts in this networks will be able to send mail without authentication!
RELAYNETS=

# Will relay all outgoing mails if configured
RELAYHOST=

# Fetchmail delay
FETCHMAIL_DELAY=600

# Recipient delimiter, character used to delimiter localpart from custom address part
RECIPIENT_DELIMITER=+

# DMARC rua and ruf email
DMARC_RUA=admin
DMARC_RUF=admin

# Welcome email, enable and set a topic and body if you wish to send welcome
# emails to all users.
WELCOME=false
WELCOME_SUBJECT=Welcome to your new email account
WELCOME_BODY=Welcome to your new email account, if you can read this, then it is configured properly!

# Maildir Compression
# choose compression-method, default: none (value: gz, bz2, lz4, zstd)
COMPRESSION=
# change compression-level, default: 6 (value: 1-9)
COMPRESSION_LEVEL=

# IMAP full-text search is enabled by default. Set the following variable to off in order to disable the feature.
# FULL_TEXT_SEARCH=off

###################################
# Web settings
###################################

# Path to redirect / to
WEBROOT_REDIRECT=/webmail

# Path to the admin interface if enabled
WEB_ADMIN=/admin

# Path to the webmail if enabled
WEB_WEBMAIL=/webmail

# Website name
SITENAME=mailu.lab.arpa

# Linked Website URL
WEBSITE=https://mailu.lab.arpa



###################################
# Advanced settings
###################################

# Log driver for front service. Possible values:
# json-file (default)
# journald (On systemd platforms, useful for Fail2Ban integration)
# syslog (Non systemd platforms, Fail2Ban integration. Disables `docker-compose log` for front!)
# LOG_DRIVER=json-file

# Docker-compose project name, this will prepended to containers names.
COMPOSE_PROJECT_NAME=mailu

# Number of rounds used by the password hashing scheme
CREDENTIAL_ROUNDS=12

# Header to take the real ip from
REAL_IP_HEADER=

# IPs for nginx set_real_ip_from (CIDR list separated by commas)
REAL_IP_FROM=

# choose wether mailu bounces (no) or rejects (yes) mail when recipient is unknown (value: yes, no)
REJECT_UNLISTED_RECIPIENT=

# Log level threshold in start.py (value: CRITICAL, ERROR, WARNING, INFO, DEBUG, NOTSET)
LOG_LEVEL=WARNING

# Timezone for the Mailu containers. See this link for all possible values https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
TZ=Etc/UTC

###################################
# Database settings
###################################
DB_FLAVOR=sqlite
```
## Observed behaviour
<!--
Explain or paste the result you received.
-->
Can't login as `admin@mail.lab.arpa` with password  `5ecret!`. Get red banner if password incorrect. Just shown the login page again if correct
## Expected behaviour
<!--
Explain what results you expected - be as specific as possible.
Just saying "it doesn’t work as expected" is not useful. It's also helpful to describe what you actually experienced.
-->
Login Success

## Logs
<!--
Often it is very useful to include log fragments of the involved component.
You can get the logs via `docker logs <container name> --tail 1000`.
For example for the admin container: `docker logs mailu_admin_1 --tail 1000`
or using docker-compose `docker-compose -f /mailu/docker-compose.yml logs --tail 1000 admin`

If you can find the relevant section, please share only the parts that seem relevant. If you have any logs, please enclose them in code tags, like so:

```
Your logs here!
```

-->

➜  mailu docker-compose logs --tail 1000 admin 
```bash
Attaching to mailu_admin_1
admin_1      | INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
admin_1      | INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
admin_1      | updated admin password
admin_1      | [2022-11-12 16:38:28 +0000] [17] [INFO] Starting gunicorn 20.1.0
admin_1      | [2022-11-12 16:38:28 +0000] [17] [INFO] Listening at: http://0.0.0.0:80 (17)
admin_1      | [2022-11-12 16:38:28 +0000] [17] [INFO] Using worker: sync
admin_1      | [2022-11-12 16:38:28 +0000] [25] [INFO] Booting worker with pid: 25
```
```
imap_1       | Nov 12 16:38:49 pop3-login: Info: Disconnected: Aborted login by logging out (no auth attempts in 0 secs): user=<>, rip=127.0.0.1, lip=127.0.0.1, secured, session=<r1ILpEjt5Z5/AAAB>
front_1      | 192.168.222.100 - - [12/Nov/2022:16:39:07 +0000] "POST /sso/login HTTP/1.1" 302 218 "http://mail.lab.arpa/sso/login" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
front_1      | 192.168.222.100 - - [12/Nov/2022:16:39:07 +0000] "GET /admin HTTP/1.1" 308 260 "http://mail.lab.arpa/sso/login" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
front_1      | 192.168.222.100 - - [12/Nov/2022:16:39:07 +0000] "GET /admin/ HTTP/1.1" 302 226 "http://mail.lab.arpa/sso/login" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
front_1      | 192.168.222.100 - - [12/Nov/2022:16:39:07 +0000] "GET /sso/login HTTP/1.1" 200 2071 "http://mail.lab.arpa/sso/login" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
front_1      | 192.168.222.100 - - [12/Nov/2022:16:39:07 +0000] "GET /static/vendor.css HTTP/1.1" 304 0 "http://mail.lab.arpa/sso/login" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
front_1      | 192.168.222.100 - - [12/Nov/2022:16:39:07 +0000] "GET /static/app.css HTTP/1.1" 304 0 "http://mail.lab.arpa/sso/login" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
front_1      | 192.168.222.100 - - [12/Nov/2022:16:39:07 +0000] "GET /static/vendor.js HTTP/1.1" 304 0 "http://mail.lab.arpa/sso/login" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
front_1      | 192.168.222.100 - - [12/Nov/2022:16:39:07 +0000] "GET /static/app.js HTTP/1.1" 304 0 "http://mail.lab.arpa/sso/login" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
front_1      | 192.168.222.100 - - [12/Nov/2022:16:39:07 +0000] "GET /static/mailu.png HTTP/1.1" 304 0 "http://mail.lab.arpa/sso/login" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
front_1      | 192.168.222.100 - - [12/Nov/2022:16:39:08 +0000] "GET /static/fa-solid-900.woff2 HTTP/1.1" 304 0 "http://mail.lab.arpa/static/vendor.css" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
```


Discussion:
Try a password without ! or try enclosing it in quotes
Initial password was much simpler but I used an example generated from chrome fake filler extension for the purposes of this issue (I also did try it with the password above before posting - however it wasn't working before that, with a password that basically amounts to `abdc1234`)
Try with ``SESSION_COOKIE_SECURE=False`` ... you're using notls and that's why it's required.
> Try with ``SESSION_COOKIE_SECURE=False`` ... you're using notls and that's why it's required.

Thanks. I'll give it a try. Local test environment so I figured I'd use notls just to try and keep things simple.
After all, I was setting this up to test an integration with the config cli, not transport later security. 
Please consider https://github.com/Mailu/Mailu/pull/2464 if you're trying to integrate it somewhere.

Did setting SESSION_COOKIE_SECURE fix the "can't login" problem?

Resolving patch:
diff --git a/core/admin/mailu/configuration.py b/core/admin/mailu/configuration.py
--- a/core/admin/mailu/configuration.py
+++ b/core/admin/mailu/configuration.py
@@ -73,7 +73,7 @@
     'SESSION_KEY_BITS': 128,
     'SESSION_TIMEOUT': 3600,
     'PERMANENT_SESSION_LIFETIME': 30*24*3600,
-    'SESSION_COOKIE_SECURE': True,
+    'SESSION_COOKIE_SECURE': None,
     'CREDENTIAL_ROUNDS': 12,
     'TLS_PERMISSIVE': True,
     'TZ': 'Etc/UTC',
@@ -156,6 +156,8 @@ def init_app(self, app):
         self.config['SESSION_STORAGE_URL'] = f'redis://{self.config["REDIS_ADDRESS"]}/3'
         self.config['SESSION_COOKIE_SAMESITE'] = 'Strict'
         self.config['SESSION_COOKIE_HTTPONLY'] = True
+        if self.config['SESSION_COOKIE_SECURE'] is None:
+            self.config['SESSION_COOKIE_SECURE'] = self.config['TLS_FLAVOR'] != 'notls'
         self.config['SESSION_PERMANENT'] = True
         self.config['SESSION_TIMEOUT'] = int(self.config['SESSION_TIMEOUT'])
         self.config['PERMANENT_SESSION_LIFETIME'] = int(self.config['PERMANENT_SESSION_LIFETIME'])


Test patch: