Skip to content

Issue 45 IMAP Mailboxes Reported As Not Authenticated

Ed Mozley edited this page Aug 24, 2026 · 2 revisions

IMAP mailboxes were reported as not authenticated (issue #45)

Open a company under Settings β†’ Companies with a Basic IMAP mailbox routed to it, and the How email reaches this company panel said:

πŸ“Œ Dedicated mailbox (not authenticated)

⚠️ A mailbox on a route above is not authenticated, so mail won't flow until it's reconnected in Settings.

None of that was true. The mailbox was connected, was being checked, and was collecting mail. The warning told people to go and reconnect something that was working, and reconnecting it could not have changed the answer.

Reported by mbsouth on issue #45 β€” the issue that added Basic IMAP support in the first place. That is a fitting place for it to land, because this bug is the incomplete half of that very feature: four screens needed teaching about IMAP mailboxes and exactly one of them ever got it.

Fixed in a1f64426, released as update #1172.

The companion bug reported alongside this one is The Verify button only ever worked for Microsoft. The general guides are Basic IMAP mailboxes and Multi-tenancy: email routing.


1. Four copies of one question

Four separate queries each carried their own copy of the same expression:

CASE WHEN token_data IS NOT NULL AND token_data != '' THEN 1 ELSE 0 END AS is_authenticated

Every copy was written before Basic IMAP mailboxes existed, and every copy was correct on the day it was written.

token_data holds the OAuth token. Microsoft and Google mailboxes have one. A Basic IMAP mailbox authenticates with a stored username and password and has no token at all β€” no code path ever writes that column for one, and the only mention of it in save_mailbox.php sets it to NULL.

So for an IMAP mailbox that expression does not return the wrong answer occasionally. It returns 0 always, on every install, no matter how correct the credentials are or how much mail the mailbox is collecting.

Which screens said what

Screen Verdict on a working IMAP mailbox
Mailboxes list Connected βœ… correct
Company routing panel not authenticated, plus "mail won't flow" ❌
Routing tester not authenticated ❌
Topology view not authenticated ❌

The mailbox list was right for a reason worth noticing: when Basic IMAP was added, get_mailboxes.php was taught about it separately, in PHP, months later β€”

if ($mailbox['provider'] === 'imap') {
    // Basic IMAP has no OAuth sign-in - it connects straight to the target
    // inbox with the stored password. "Connected" once a password is stored.
    $mailbox['is_authenticated'] = !empty($mailbox['imap_password_set']);
}

One screen was updated. The other three were never found, because there was nothing to find them by β€” four unrelated files, each with its own copy, none of them referring to any shared thing.

The general lesson: a definition that is copied is a definition that will drift, and it drifts silently. Nothing failed, nothing errored, no test went red. Three screens simply went on answering a question using a rule that had stopped being true, and the only visible symptom was that they disagreed with a fourth screen that nobody was comparing them against.

The disagreement was on screen at once

The clearest reproduction had two pinned mailboxes on one company:

Mailbox Provider Panel said
support@… Microsoft (nothing β€” fine)
edmozley@… Basic IMAP (not authenticated)

Same screen, same company, both working. One line of SQL between them.


2. What was changed

One definition, in one file. mailboxAuthenticatedSql() now lives in includes/mailbox_auth.php and is the only place that decides what "authenticated" means:

function mailboxAuthenticatedSql(string $prefix = ''): string {
    return "CASE WHEN ({$prefix}token_data IS NOT NULL AND {$prefix}token_data <> '')"
         . " OR ({$prefix}provider = 'imap' AND {$prefix}imap_password IS NOT NULL AND {$prefix}imap_password <> '')"
         . " THEN 1 ELSE 0 END";
}

OAuth providers prove it with a token; Basic IMAP proves it with a password. Either one means the mailbox can log in.

Patching the three wrong copies would have fixed the reported symptom and left the actual defect in place, ready to reappear the next time a provider is added. The copies were the bug.

No schema change. provider and imap_password are already in db_verify's target_mailboxes schema and in database/freeitsm.sql, and are already selected by get_mailboxes.php and get_topology.php β€” so this adds no requirement the mailbox screens did not already have.


3. πŸ“ The files involved

🟒 The fix

File Role
includes/mailbox_auth.php New. mailboxAuthenticatedSql() β€” the single definition, with the history of why it exists written above it

πŸ”΅ The three that were wrong

File Screen
api/system/get_tenant_email_routing.php How email reaches this company β€” the panel that carried the false "mail won't flow" warning
api/system/email_routing_test.php The routing dry-run tester
api/system/get_topology.php System β†’ Topology

βšͺ Already correct, left alone

File Why
api/tickets/get_mailboxes.php Handles IMAP in PHP and computes a richer auth_status (ok, mismatch, unverified, …) that the SQL flag alone cannot express
api/tickets/get_sendable_mailboxes.php Asks a different question β€” can this mailbox send β€” and already allowed for IMAP

4. How it was verified

A differential run against the three real mailboxes on a live install, old expression and new, side by side in one query:

Mailbox Provider Old New
ITSM Support microsoft 1 1
freeitsm.com inbox google 1 1
Zoho Mail imap 0 1

Exactly one row changes, and it is the intended one. The two unchanged rows are the control: an expression that made everything authenticated would have fixed the symptom and broken the feature, and would have looked identical if only the IMAP row had been checked.

Then live through each of the three endpoints:

Endpoint Result
get_tenant_email_routing.php Both pinned mailboxes "authenticated": true, and "warnings": [] β€” the yellow warning is gone
email_routing_test.php IMAP mailbox "authenticated": true
get_topology.php IMAP mailbox "is_authenticated": true, Microsoft and Google unchanged

What is not proven. Every mailbox on the test install holds a credential, so the negative case β€” an IMAP mailbox saved with no password, which should read as unauthenticated β€” was reasoned from the SQL rather than reproduced.


5. What this means for you

  • If a company's routing panel warned that mail would not flow from your IMAP mailbox, ignore it β€” and no, you did not need to reconnect anything. Mail was flowing.
  • The Mailboxes list was the screen telling the truth, and it still is. If it says Connected and the last-checked time is recent, the mailbox is working.
  • A genuinely unauthenticated IMAP mailbox is one with no stored password, and it will now be reported as such β€” including on these three screens.

Related pages

FreeITSM

Getting Started

Modules

Multi-tenancy (planned)

Blue sky thinking

Bugs resolved

Links

Clone this wiki locally