mirror of
https://github.com/mjl-/mox.git
synced 2024-12-27 08:53:48 +03:00
quota: fix handling negative max size when configured for an account, and clarify value is in bytes in config file
for #115 by pmarini-nc
This commit is contained in:
parent
7b6cfcd572
commit
aea8740e65
5 changed files with 17 additions and 16 deletions
|
@ -71,7 +71,7 @@ type Static struct {
|
||||||
NoOutgoingDMARCReports bool `sconf:"optional" sconf-doc:"Do not send DMARC reports (aggregate only). By default, aggregate reports on DMARC evaluations are sent to domains if their DMARC policy requests them. Reports are sent at whole hours, with a minimum of 1 hour and maximum of 24 hours, rounded up so a whole number of intervals cover 24 hours, aligned at whole days in UTC. Reports are sent from the postmaster@<mailhostname> address."`
|
NoOutgoingDMARCReports bool `sconf:"optional" sconf-doc:"Do not send DMARC reports (aggregate only). By default, aggregate reports on DMARC evaluations are sent to domains if their DMARC policy requests them. Reports are sent at whole hours, with a minimum of 1 hour and maximum of 24 hours, rounded up so a whole number of intervals cover 24 hours, aligned at whole days in UTC. Reports are sent from the postmaster@<mailhostname> address."`
|
||||||
NoOutgoingTLSReports bool `sconf:"optional" sconf-doc:"Do not send TLS reports. By default, reports about failed SMTP STARTTLS connections and related MTA-STS/DANE policies are sent to domains if their TLSRPT DNS record requests them. Reports covering a 24 hour UTC interval are sent daily. Reports are sent from the postmaster address of the configured domain the mailhostname is in. If there is no such domain, or it does not have DKIM configured, no reports are sent."`
|
NoOutgoingTLSReports bool `sconf:"optional" sconf-doc:"Do not send TLS reports. By default, reports about failed SMTP STARTTLS connections and related MTA-STS/DANE policies are sent to domains if their TLSRPT DNS record requests them. Reports covering a 24 hour UTC interval are sent daily. Reports are sent from the postmaster address of the configured domain the mailhostname is in. If there is no such domain, or it does not have DKIM configured, no reports are sent."`
|
||||||
OutgoingTLSReportsForAllSuccess bool `sconf:"optional" sconf-doc:"Also send TLS reports if there were no SMTP STARTTLS connection failures. By default, reports are only sent when at least one failure occurred. If a report is sent, it does always include the successful connection counts as well."`
|
OutgoingTLSReportsForAllSuccess bool `sconf:"optional" sconf-doc:"Also send TLS reports if there were no SMTP STARTTLS connection failures. By default, reports are only sent when at least one failure occurred. If a report is sent, it does always include the successful connection counts as well."`
|
||||||
QuotaMessageSize int64 `sconf:"optional" sconf-doc:"Default maximum total message size for accounts, only applicable if greater than zero. Can be overridden per account. Attempting to add new messages beyond the maximum size will result in an error. Useful to prevent a single account from filling storage. The quota only applies to the email message files, not to any file system overhead and also not the message index database file (account for approximately 15% overhead)."`
|
QuotaMessageSize int64 `sconf:"optional" sconf-doc:"Default maximum total message size in bytes for each individual account, only applicable if greater than zero. Can be overridden per account. Attempting to add new messages to an account beyond its maximum total size will result in an error. Useful to prevent a single account from filling storage. The quota only applies to the email message files, not to any file system overhead and also not the message index database file (account for approximately 15% overhead)."`
|
||||||
|
|
||||||
// All IPs that were explicitly listen on for external SMTP. Only set when there
|
// All IPs that were explicitly listen on for external SMTP. Only set when there
|
||||||
// are no unspecified external SMTP listeners and there is at most one for IPv4 and
|
// are no unspecified external SMTP listeners and there is at most one for IPv4 and
|
||||||
|
@ -349,7 +349,7 @@ type Account struct {
|
||||||
SubjectPass struct {
|
SubjectPass struct {
|
||||||
Period time.Duration `sconf-doc:"How long unique values are accepted after generating, e.g. 12h."` // todo: have a reasonable default for this?
|
Period time.Duration `sconf-doc:"How long unique values are accepted after generating, e.g. 12h."` // todo: have a reasonable default for this?
|
||||||
} `sconf:"optional" sconf-doc:"If configured, messages classified as weakly spam are rejected with instructions to retry delivery, but this time with a signed token added to the subject. During the next delivery attempt, the signed token will bypass the spam filter. Messages with a clear spam signal, such as a known bad reputation, are rejected/delayed without a signed token."`
|
} `sconf:"optional" sconf-doc:"If configured, messages classified as weakly spam are rejected with instructions to retry delivery, but this time with a signed token added to the subject. During the next delivery attempt, the signed token will bypass the spam filter. Messages with a clear spam signal, such as a known bad reputation, are rejected/delayed without a signed token."`
|
||||||
QuotaMessageSize int64 `sconf:"optional" sconf-doc:"Default maximum total message size for the account, overriding any globally configured maximum size if non-zero. A negative value can be used to have no limit in case there is a limit by default. Attempting to add new messages beyond the maximum size will result in an error. Useful to prevent a single account from filling storage."`
|
QuotaMessageSize int64 `sconf:"optional" sconf-doc:"Default maximum total message size in bytes for the account, overriding any globally configured default maximum size if non-zero. A negative value can be used to have no limit in case there is a limit by default. Attempting to add new messages to an account beyond its maximum total size will result in an error. Useful to prevent a single account from filling storage."`
|
||||||
RejectsMailbox string `sconf:"optional" sconf-doc:"Mail that looks like spam will be rejected, but a copy can be stored temporarily in a mailbox, e.g. Rejects. If mail isn't coming in when you expect, you can look there. The mail still isn't accepted, so the remote mail server may retry (hopefully, if legitimate), or give up (hopefully, if indeed a spammer). Messages are automatically removed from this mailbox, so do not set it to a mailbox that has messages you want to keep."`
|
RejectsMailbox string `sconf:"optional" sconf-doc:"Mail that looks like spam will be rejected, but a copy can be stored temporarily in a mailbox, e.g. Rejects. If mail isn't coming in when you expect, you can look there. The mail still isn't accepted, so the remote mail server may retry (hopefully, if legitimate), or give up (hopefully, if indeed a spammer). Messages are automatically removed from this mailbox, so do not set it to a mailbox that has messages you want to keep."`
|
||||||
KeepRejects bool `sconf:"optional" sconf-doc:"Don't automatically delete mail in the RejectsMailbox listed above. This can be useful, e.g. for future spam training."`
|
KeepRejects bool `sconf:"optional" sconf-doc:"Don't automatically delete mail in the RejectsMailbox listed above. This can be useful, e.g. for future spam training."`
|
||||||
AutomaticJunkFlags struct {
|
AutomaticJunkFlags struct {
|
||||||
|
|
|
@ -657,12 +657,13 @@ See https://pkg.go.dev/github.com/mjl-/sconf for details.
|
||||||
# (optional)
|
# (optional)
|
||||||
OutgoingTLSReportsForAllSuccess: false
|
OutgoingTLSReportsForAllSuccess: false
|
||||||
|
|
||||||
# Default maximum total message size for accounts, only applicable if greater than
|
# Default maximum total message size in bytes for each individual account, only
|
||||||
# zero. Can be overridden per account. Attempting to add new messages beyond the
|
# applicable if greater than zero. Can be overridden per account. Attempting to
|
||||||
# maximum size will result in an error. Useful to prevent a single account from
|
# add new messages to an account beyond its maximum total size will result in an
|
||||||
# filling storage. The quota only applies to the email message files, not to any
|
# error. Useful to prevent a single account from filling storage. The quota only
|
||||||
# file system overhead and also not the message index database file (account for
|
# applies to the email message files, not to any file system overhead and also not
|
||||||
# approximately 15% overhead). (optional)
|
# the message index database file (account for approximately 15% overhead).
|
||||||
|
# (optional)
|
||||||
QuotaMessageSize: 0
|
QuotaMessageSize: 0
|
||||||
|
|
||||||
# domains.conf
|
# domains.conf
|
||||||
|
@ -934,11 +935,11 @@ See https://pkg.go.dev/github.com/mjl-/sconf for details.
|
||||||
# How long unique values are accepted after generating, e.g. 12h.
|
# How long unique values are accepted after generating, e.g. 12h.
|
||||||
Period: 0s
|
Period: 0s
|
||||||
|
|
||||||
# Default maximum total message size for the account, overriding any globally
|
# Default maximum total message size in bytes for the account, overriding any
|
||||||
# configured maximum size if non-zero. A negative value can be used to have no
|
# globally configured default maximum size if non-zero. A negative value can be
|
||||||
# limit in case there is a limit by default. Attempting to add new messages beyond
|
# used to have no limit in case there is a limit by default. Attempting to add new
|
||||||
# the maximum size will result in an error. Useful to prevent a single account
|
# messages to an account beyond its maximum total size will result in an error.
|
||||||
# from filling storage. (optional)
|
# Useful to prevent a single account from filling storage. (optional)
|
||||||
QuotaMessageSize: 0
|
QuotaMessageSize: 0
|
||||||
|
|
||||||
# Mail that looks like spam will be rejected, but a copy can be stored temporarily
|
# Mail that looks like spam will be rejected, but a copy can be stored temporarily
|
||||||
|
|
|
@ -2015,7 +2015,7 @@ func (a *Account) AddMessageSize(log mlog.Log, tx *bstore.Tx, size int64) error
|
||||||
func (a *Account) QuotaMessageSize() int64 {
|
func (a *Account) QuotaMessageSize() int64 {
|
||||||
conf, _ := a.Conf()
|
conf, _ := a.Conf()
|
||||||
size := conf.QuotaMessageSize
|
size := conf.QuotaMessageSize
|
||||||
if size <= 0 {
|
if size == 0 {
|
||||||
size = mox.Conf.Static.QuotaMessageSize
|
size = mox.Conf.Static.QuotaMessageSize
|
||||||
}
|
}
|
||||||
if size < 0 {
|
if size < 0 {
|
||||||
|
|
|
@ -1835,7 +1835,7 @@ const account = async (name) => {
|
||||||
}
|
}
|
||||||
form.reset();
|
form.reset();
|
||||||
window.location.reload(); // todo: only reload the destinations
|
window.location.reload(); // todo: only reload the destinations
|
||||||
}, fieldset = dom.fieldset(dom.label(style({ display: 'inline-block' }), dom.span('Email address or localpart', attr.title('If empty, or localpart is empty, a catchall address is configured for the domain.')), dom.br(), email = dom.input()), ' ', dom.submitbutton('Add address'))), dom.br(), dom.h2('Limits'), dom.form(fieldsetLimits = dom.fieldset(dom.label(style({ display: 'block', marginBottom: '.5ex' }), dom.span('Maximum outgoing messages per day', attr.title('Maximum number of outgoing messages for this account in a 24 hour window. This limits the damage to recipients and the reputation of this mail server in case of account compromise. Default 1000. MaxOutgoingMessagesPerDay in configuration file.')), dom.br(), maxOutgoingMessagesPerDay = dom.input(attr.type('number'), attr.required(''), attr.value(config.MaxOutgoingMessagesPerDay || 1000))), dom.label(style({ display: 'block', marginBottom: '.5ex' }), dom.span('Maximum first-time recipients per day', attr.title('Maximum number of first-time recipients in outgoing messages for this account in a 24 hour window. This limits the damage to recipients and the reputation of this mail server in case of account compromise. Default 200. MaxFirstTimeRecipientsPerDay in configuration file.')), dom.br(), maxFirstTimeRecipientsPerDay = dom.input(attr.type('number'), attr.required(''), attr.value(config.MaxFirstTimeRecipientsPerDay || 200))), dom.label(style({ display: 'block', marginBottom: '.5ex' }), dom.span('Disk usage quota: Maximum total message size ', attr.title('Default maximum total message size for the account, overriding any globally configured maximum size if non-zero. A negative value can be used to have no limit in case there is a limit by default. Attempting to add new messages beyond the maximum size will result in an error. Useful to prevent a single account from filling storage.')), dom.br(), quotaMessageSize = dom.input(attr.value(formatQuotaSize(config.QuotaMessageSize)))), dom.submitbutton('Save')), async function submit(e) {
|
}, fieldset = dom.fieldset(dom.label(style({ display: 'inline-block' }), dom.span('Email address or localpart', attr.title('If empty, or localpart is empty, a catchall address is configured for the domain.')), dom.br(), email = dom.input()), ' ', dom.submitbutton('Add address'))), dom.br(), dom.h2('Limits'), dom.form(fieldsetLimits = dom.fieldset(dom.label(style({ display: 'block', marginBottom: '.5ex' }), dom.span('Maximum outgoing messages per day', attr.title('Maximum number of outgoing messages for this account in a 24 hour window. This limits the damage to recipients and the reputation of this mail server in case of account compromise. Default 1000. MaxOutgoingMessagesPerDay in configuration file.')), dom.br(), maxOutgoingMessagesPerDay = dom.input(attr.type('number'), attr.required(''), attr.value(config.MaxOutgoingMessagesPerDay || 1000))), dom.label(style({ display: 'block', marginBottom: '.5ex' }), dom.span('Maximum first-time recipients per day', attr.title('Maximum number of first-time recipients in outgoing messages for this account in a 24 hour window. This limits the damage to recipients and the reputation of this mail server in case of account compromise. Default 200. MaxFirstTimeRecipientsPerDay in configuration file.')), dom.br(), maxFirstTimeRecipientsPerDay = dom.input(attr.type('number'), attr.required(''), attr.value(config.MaxFirstTimeRecipientsPerDay || 200))), dom.label(style({ display: 'block', marginBottom: '.5ex' }), dom.span('Disk usage quota: Maximum total message size ', attr.title('Default maximum total message size in bytes for the account, overriding any globally configured default maximum size if non-zero. A negative value can be used to have no limit in case there is a limit by default. Attempting to add new messages to an account beyond its maximum total size will result in an error. Useful to prevent a single account from filling storage.')), dom.br(), quotaMessageSize = dom.input(attr.value(formatQuotaSize(config.QuotaMessageSize)))), dom.submitbutton('Save')), async function submit(e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
fieldsetLimits.disabled = true;
|
fieldsetLimits.disabled = true;
|
||||||
|
|
|
@ -727,7 +727,7 @@ const account = async (name: string) => {
|
||||||
),
|
),
|
||||||
dom.label(
|
dom.label(
|
||||||
style({display: 'block', marginBottom: '.5ex'}),
|
style({display: 'block', marginBottom: '.5ex'}),
|
||||||
dom.span('Disk usage quota: Maximum total message size ', attr.title('Default maximum total message size for the account, overriding any globally configured maximum size if non-zero. A negative value can be used to have no limit in case there is a limit by default. Attempting to add new messages beyond the maximum size will result in an error. Useful to prevent a single account from filling storage.')),
|
dom.span('Disk usage quota: Maximum total message size ', attr.title('Default maximum total message size in bytes for the account, overriding any globally configured default maximum size if non-zero. A negative value can be used to have no limit in case there is a limit by default. Attempting to add new messages to an account beyond its maximum total size will result in an error. Useful to prevent a single account from filling storage.')),
|
||||||
dom.br(),
|
dom.br(),
|
||||||
quotaMessageSize=dom.input(attr.value(formatQuotaSize(config.QuotaMessageSize))),
|
quotaMessageSize=dom.input(attr.value(formatQuotaSize(config.QuotaMessageSize))),
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in a new issue