dobedobedoh mentioned we could investigate moving various email related functions, email_to_user, email_should_be_diverted, etc into a new class somewhere, I agree but I think we could go much further and can refactor almost all of it into either the message api or the email message output.
email_to_user as a public API is essentially legacy code which has largely been supplanted by the Message api which is obviously superior in multiple ways. There are only a handful of direct uses of email_to_user() left:
- admin/process_email.php:38 bounce handling (tied to email protocol, we can ignore this)
- enrol/self/lib.php:462 - welcome message (external)
- lib/authlib.php:768 - account lockout (security)
- lib/moodlelib.php:5845 - send out new password (security)
- lib/moodlelib.php:5889 - password reset (security)
- lib/moodlelib.php:5920 - user confirmation (security)
- lib/moodlelib.php:5950 - password change (security)
- lib/moodlelib.php:5979/6000 - send password change info (security)
- message/output/email/message_output_email.php:93 <-- the real bulk of all emails
Often they are accompanied by a comment like this:
Directly email rather than using the messaging system to ensure its not routed to a popup or jabber.
These are all 'messages' in an abstract sense but are intimately tied to email for reasons which I think are not true any more. Lets go back to first principals and get the raw requirements for these messages:
- external - The welcome message's only real requirement is simply to notify a user outside of moodle and ideally guarantee delivery. ie you can't rely on them being in moodle or even being aware of moode, it's to get their attention and draw them into moodle. I don't see why this isn't a normal message, they can't disable their email preferences until they have logged in, so a normal message will get to them and would also be available inside moodle later.
- security - All of the security related messages are relying on an implicit trust relationship, in particular it's important that the message contents cannot be accessed from inside moodle, and the message delivery should be secure.
Now lets look at email as a message output:
- external: Yes, but delivery isn't guaranteed
- security: not fantastic
On top of this, there are many industries or audiences where email is just not a thing, in certain cultures and demographics the majority of people don't have an email. Moodle should be able to accommodate this and not be tied so heavily to email.
Now lets compare it to some other potential external message outputs
SMS: delivery probably better than email, security considered better than email (ie banks prefer sms)
iMessage: delivery in most cases has read receipts, security is great
Android: see above
In theory an admin should be able to augment or even swap out email for any of these other message output types. Why shouldn't you be able to configure moodle so you can signup / confirm / login with your phone number?
So what I'm proposing is:
- we extend the Message output API so that each output declares whether it is capable of being 'secure', nonsecure (default)
- the Email output would declare itself as secure
- for the sensitive messages above we convert them to use the message api, but pass in a new flag saying the message is sensitive, and the message system will only pass it to outputs which are declared 'secure'. The users message preferences would be ignored for these messages. In addition it will also not store a copy of the message body, but could possibly store other minimal message metadata. Or perhaps an alternate non-sensitive message could be provided to be stored.
- An admin can configure which secure output(s) to use if there are multiple installed and configured. ie email + sms, or just sms. If multiple the admin could either make them all required or give the user the choice which to use as long as at least one is setup.
- The Message output would take over responsibility for 'confirming' a user, ie email confirmation with link, sms confirmation with 6 digit code to type in, etc
- The message outputs would probably need to be able to declare fields in the user sign up page and extra rules for user_not_fully_set_up, (sorta related to
MDL-46946, probably needs a hook)
We will never fully abstract emails into the message api, there are too many things like email headers which only ever make sense in that context, but this should at least open the door to being less tied to email if people don't want to be.
It would be reasonably simple to also make a new SMS message output which then had subplugins for common SMS gateways like twilio, AmazonSNS, etc to make it really easy for the most common use case