Expose new tlsMode and tlsVerify options for connecting to the mail submission agent #134
No reviewers
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
bewcloud/bewcloud!134
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat-email-tls-opts"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Replaces #125.
Exposes all the cursed security options I’ve in the past or present seen mail servers require.
This is a slightly breaking change: If the mail server does not support any encryption, one has to now explicitly set
email.tlsModeto"none", as the mail client will now refuse to automatically do an insecure downgrade to plaintext if StartTLS is not offered.Thanks @ntninja this looks very good, but I don't want to ship a breaking change (especially so soon after one), can we come up with a way where that's not necessary?
Additionally, there's no need to change the
.env.samplefile; email is only used for signup or MFA, nothing else, and I don't plan to use it for anything else.The only thing, I can think of is adding an additional value to
tlsModecalled"auto"that for bewCloud v3.x implements the new behaviour suggested here, while thenulldefault retains the previous meaning. We could then emit a warning on startup if people have.email.portset to a value different from465, but did not set.email.tlsMode.For bewCloud 4.x
nulland"auto"will then become equivalent. (I could leave a PR open for that if you want.)Sounds good enough?
The previous comment is wrong though: These variables do not (with or without this patch) enable signup email verification or multi-factor authentication via email.
Instead these variables have previously (and still do with this patch) only provided the authentication information when connecting the Mail Submission Agent. Not providing any authentication information is a better default than sending
fake:fakeas “credentials”.I forgot to mention this, but without this patch connecting to the Mail Submission Agent is currently broken. This is because nodemailer will attempt
PLAINauthentication if any.authfields are present, but then thePLAINauthentication backend will (correctly) refuse to performPAIN“authentication” without any credentials (doesn’t make sense and is, to my knowledge, prohibited by RFC).I might be missing something, but why can't we not allow
null, default toauto, and haveautobehave as it does now?I suppose you can change
enabletouse, then.Because
nullas implemented here, mean “immediate TLS on port 465, required StartTLS otherwise”, while the previous default in bewCloud is “immediate TLS on port 465, opportunistic StartTLS otherwise”.The proposed mechanism is for “auto” (the new recommended value mentioned in sample config) to mean “immediate TLS on port 465, required StartTLS otherwise”, with the default
nullretaining the previous bewCloud behaviour of “immediate TLS on port 465, opportunistic StartTLS otherwise”. They can then become one and the same in bewCloud 4.The
nulldefault value is intended is an indefinite stop-gap for backward-compatibility during bewCloud 3 only.So would this be OK then?
@BrunoBernardino: Commit https://github.com/bewcloud/bewcloud/pull/134/changes/471a1828ea0fbf9db9f7aee93979ad6ab678891a implements the legacy compatibility behaviour for
tlsMode.This is looking great and very close! I have a few minor tweaks and a slight refactor request!
@ -32,6 +32,8 @@ const config: PartialDeep<Config> = {// from: '[email protected]',This should match the type JSDoc:
This should match the type JSDoc:
@ -37,6 +37,8 @@ export class AppConfig {from: '[email protected]',I think this comment is confusing and unnecessary since we have more info in the types/JSDoc.
@ -97,6 +99,10 @@ export class AppConfig {Please make this more consistent with past warnings.
@ -15,14 +15,31 @@ export class EmailModel {throw new Error('config.email.from, config.email.host, or config.email.port is not set');}let tlsMode = emailConfig.tlsMode;Please rewrite this bit to remain/keep the
transporterConfiga variable that's just used increateTransportlater. It makes debugging configuration easier in the future.@ -206,6 +206,10 @@ export interface Config {host: string;I think this can be simplified.
I think this can be clearer.
@ -206,6 +206,10 @@ export interface Config {host: string;Changed it in a slightly way, yous makes it non-obvious that the hostname is indeed only for TLS certificate verification
@ -15,14 +15,31 @@ export class EmailModel {throw new Error('config.email.from, config.email.host, or config.email.port is not set');}let tlsMode = emailConfig.tlsMode;Makes sense, I had even done that during debugging… 🤔
@BrunoBernardino: Should hopefully be OK now
Almost there, I just have a couple more suggestions and questions! Thank you for your patience!
@ -15,14 +15,31 @@ export class EmailModel {throw new Error('config.email.from, config.email.host, or config.email.port is not set');We don't need to split comments into multiple lines, and I personally don't like it.
@ -23,0 +33,4 @@tls: (emailConfig.tlsVerify === false ? { rejectUnauthorized: false } :emailConfig.tlsVerify !== true ? { servername: emailConfig.tlsVerify } :{}Shouldn't we set
rejectUnauthorized: trueiftlsVerify === true?@ -23,0 +35,4 @@emailConfig.tlsVerify !== true ? { servername: emailConfig.tlsVerify } :{}),Isn't it better to set this as
undefinedornullinstead of an empty object? I haven't checked thenodemailerconfig code yet, but I'd assumenullgiven what's done forauthbelow.@ -206,6 +206,10 @@ export interface Config {host: string;Pedantic, but makes it more understandable.
@ -23,0 +33,4 @@tls: (emailConfig.tlsVerify === false ? { rejectUnauthorized: false } :emailConfig.tlsVerify !== true ? { servername: emailConfig.tlsVerify } :{}Not necessary, unlike with opportunistic StartTLS (which makes things “just work” more often, but also reduces security in the face of an active attacker to exactly 0) there are no bad defaults here. (That is, TLS certificates are always checked unless you explicitly opt out of that.)
@ -23,0 +35,4 @@emailConfig.tlsVerify !== true ? { servername: emailConfig.tlsVerify } :{}),Empty object means: Use the defaults, so this is OK.
(
authis different: The presence of any object signals it to enable authentication, so I had to passnullthere – not a great API.)@ -206,6 +206,10 @@ export interface Config {host: string;That’s incorrect grammar in english I’m afraid, you don’t add the comma its clear that the if and the are part of the same clause. How you suggested may also be ready as “Whether to verify the TLS certificate, if a string is used” + [something]. It’s like the famous gun amendment of the US constitution. 😆
Fixed the multi-line comment
@ -23,0 +33,4 @@tls: (emailConfig.tlsVerify === false ? { rejectUnauthorized: false } :emailConfig.tlsVerify !== true ? { servername: emailConfig.tlsVerify } :{}Thanks for the clarification!
@ -23,0 +35,4 @@emailConfig.tlsVerify !== true ? { servername: emailConfig.tlsVerify } :{}),Gotcha.
@ -206,6 +206,10 @@ export interface Config {host: string;I should've made the first comma a dot, sorry.
@ -206,6 +206,10 @@ export interface Config {host: string;Like this:
Thanks for the changes!
This is live in v3.3.0!