mirror of
https://github.com/mjl-/mox.git
synced 2024-12-26 16:33:47 +03:00
add account option to skip the first-time sender delay
useful for accounts that automatically process messages and want to process quickly
This commit is contained in:
parent
281411c297
commit
8b2c97808d
9 changed files with 54 additions and 32 deletions
|
@ -368,6 +368,7 @@ type Account struct {
|
||||||
JunkFilter *JunkFilter `sconf:"optional" sconf-doc:"Content-based filtering, using the junk-status of individual messages to rank words in such messages as spam or ham. It is recommended you always set the applicable (non)-junk status on messages, and that you do not empty your Trash because those messages contain valuable ham/spam training information."` // todo: sane defaults for junkfilter
|
JunkFilter *JunkFilter `sconf:"optional" sconf-doc:"Content-based filtering, using the junk-status of individual messages to rank words in such messages as spam or ham. It is recommended you always set the applicable (non)-junk status on messages, and that you do not empty your Trash because those messages contain valuable ham/spam training information."` // todo: sane defaults for junkfilter
|
||||||
MaxOutgoingMessagesPerDay int `sconf:"optional" sconf-doc:"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 int `sconf:"optional" sconf-doc:"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."`
|
||||||
MaxFirstTimeRecipientsPerDay int `sconf:"optional" sconf-doc:"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 int `sconf:"optional" sconf-doc:"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."`
|
||||||
|
NoFirstTimeSenderDelay bool `sconf:"optional" sconf-doc:"Do not apply a delay to SMTP connections before accepting an incoming message from a first-time sender. Can be useful for accounts that sends automated responses and want instant replies."`
|
||||||
Routes []Route `sconf:"optional" sconf-doc:"Routes for delivering outgoing messages through the queue. Each delivery attempt evaluates these account routes, domain routes and finally global routes. The transport of the first matching route is used in the delivery attempt. If no routes match, which is the default with no configured routes, messages are delivered directly from the queue."`
|
Routes []Route `sconf:"optional" sconf-doc:"Routes for delivering outgoing messages through the queue. Each delivery attempt evaluates these account routes, domain routes and finally global routes. The transport of the first matching route is used in the delivery attempt. If no routes match, which is the default with no configured routes, messages are delivered directly from the queue."`
|
||||||
|
|
||||||
DNSDomain dns.Domain `sconf:"-"` // Parsed form of Domain.
|
DNSDomain dns.Domain `sconf:"-"` // Parsed form of Domain.
|
||||||
|
|
|
@ -1032,6 +1032,11 @@ See https://pkg.go.dev/github.com/mjl-/sconf for details.
|
||||||
# this mail server in case of account compromise. Default 200. (optional)
|
# this mail server in case of account compromise. Default 200. (optional)
|
||||||
MaxFirstTimeRecipientsPerDay: 0
|
MaxFirstTimeRecipientsPerDay: 0
|
||||||
|
|
||||||
|
# Do not apply a delay to SMTP connections before accepting an incoming message
|
||||||
|
# from a first-time sender. Can be useful for accounts that sends automated
|
||||||
|
# responses and want instant replies. (optional)
|
||||||
|
NoFirstTimeSenderDelay: false
|
||||||
|
|
||||||
# Routes for delivering outgoing messages through the queue. Each delivery attempt
|
# Routes for delivering outgoing messages through the queue. Each delivery attempt
|
||||||
# evaluates these account routes, domain routes and finally global routes. The
|
# evaluates these account routes, domain routes and finally global routes. The
|
||||||
# transport of the first matching route is used in the delivery attempt. If no
|
# transport of the first matching route is used in the delivery attempt. If no
|
||||||
|
|
|
@ -1032,12 +1032,12 @@ func DestinationSave(ctx context.Context, account, destName string, newDest conf
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccountLimitsSave saves new message sending limits for an account.
|
// AccountAdminSettingsSave saves new account settings for an account only an admin can change.
|
||||||
func AccountLimitsSave(ctx context.Context, account string, maxOutgoingMessagesPerDay, maxFirstTimeRecipientsPerDay int, quotaMessageSize int64) (rerr error) {
|
func AccountAdminSettingsSave(ctx context.Context, account string, maxOutgoingMessagesPerDay, maxFirstTimeRecipientsPerDay int, quotaMessageSize int64, firstTimeSenderDelay bool) (rerr error) {
|
||||||
log := pkglog.WithContext(ctx)
|
log := pkglog.WithContext(ctx)
|
||||||
defer func() {
|
defer func() {
|
||||||
if rerr != nil {
|
if rerr != nil {
|
||||||
log.Errorx("saving account limits", rerr, slog.String("account", account))
|
log.Errorx("saving admin account settings", rerr, slog.String("account", account))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -1060,12 +1060,13 @@ func AccountLimitsSave(ctx context.Context, account string, maxOutgoingMessagesP
|
||||||
acc.MaxOutgoingMessagesPerDay = maxOutgoingMessagesPerDay
|
acc.MaxOutgoingMessagesPerDay = maxOutgoingMessagesPerDay
|
||||||
acc.MaxFirstTimeRecipientsPerDay = maxFirstTimeRecipientsPerDay
|
acc.MaxFirstTimeRecipientsPerDay = maxFirstTimeRecipientsPerDay
|
||||||
acc.QuotaMessageSize = quotaMessageSize
|
acc.QuotaMessageSize = quotaMessageSize
|
||||||
|
acc.NoFirstTimeSenderDelay = !firstTimeSenderDelay
|
||||||
nc.Accounts[account] = acc
|
nc.Accounts[account] = acc
|
||||||
|
|
||||||
if err := writeDynamic(ctx, log, nc); err != nil {
|
if err := writeDynamic(ctx, log, nc); err != nil {
|
||||||
return fmt.Errorf("writing domains.conf: %v", err)
|
return fmt.Errorf("writing domains.conf: %v", err)
|
||||||
}
|
}
|
||||||
log.Info("account limits saved", slog.String("account", account))
|
log.Info("admin account settings saved", slog.String("account", account))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2805,8 +2805,8 @@ func (c *conn) deliver(ctx context.Context, recvHdrFor func(string) string, msgW
|
||||||
log.Check(err, "adding dmarc evaluation to database for aggregate report")
|
log.Check(err, "adding dmarc evaluation to database for aggregate report")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conf, _ := acc.Conf()
|
||||||
if !a.accept {
|
if !a.accept {
|
||||||
conf, _ := acc.Conf()
|
|
||||||
if conf.RejectsMailbox != "" {
|
if conf.RejectsMailbox != "" {
|
||||||
present, _, messagehash, err := rejectPresent(log, acc, conf.RejectsMailbox, &m, dataFile)
|
present, _, messagehash, err := rejectPresent(log, acc, conf.RejectsMailbox, &m, dataFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -2870,10 +2870,10 @@ func (c *conn) deliver(ctx context.Context, recvHdrFor func(string) string, msgW
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is a first-time sender and not a forwarded message, wait before actually
|
// If this is a first-time sender and not a forwarded/mailing list message, wait
|
||||||
// delivering. If this turns out to be a spammer, we've kept one of their
|
// before actually delivering. If this turns out to be a spammer, we've kept one of
|
||||||
// connections busy.
|
// their connections busy.
|
||||||
if delayFirstTime && !m.IsForward && a.reason == reasonNoBadSignals && c.firstTimeSenderDelay > 0 {
|
if delayFirstTime && !m.IsForward && !m.IsMailingList && a.reason == reasonNoBadSignals && !conf.NoFirstTimeSenderDelay && c.firstTimeSenderDelay > 0 {
|
||||||
log.Debug("delaying before delivering from sender without reputation", slog.Duration("delay", c.firstTimeSenderDelay))
|
log.Debug("delaying before delivering from sender without reputation", slog.Duration("delay", c.firstTimeSenderDelay))
|
||||||
mox.Sleep(mox.Context, c.firstTimeSenderDelay)
|
mox.Sleep(mox.Context, c.firstTimeSenderDelay)
|
||||||
}
|
}
|
||||||
|
@ -2915,7 +2915,7 @@ func (c *conn) deliver(ctx context.Context, recvHdrFor func(string) string, msgW
|
||||||
metricDelivery.WithLabelValues("delivered", a.reason).Inc()
|
metricDelivery.WithLabelValues("delivered", a.reason).Inc()
|
||||||
log.Info("incoming message delivered", slog.String("reason", a.reason), slog.Any("msgfrom", msgFrom))
|
log.Info("incoming message delivered", slog.String("reason", a.reason), slog.Any("msgfrom", msgFrom))
|
||||||
|
|
||||||
conf, _ := acc.Conf()
|
conf, _ = acc.Conf()
|
||||||
if conf.RejectsMailbox != "" && m.MessageID != "" {
|
if conf.RejectsMailbox != "" && m.MessageID != "" {
|
||||||
if err := acc.RejectsRemove(log, conf.RejectsMailbox, m.MessageID); err != nil {
|
if err := acc.RejectsRemove(log, conf.RejectsMailbox, m.MessageID); err != nil {
|
||||||
log.Errorx("removing message from rejects mailbox", err, slog.String("messageid", messageID))
|
log.Errorx("removing message from rejects mailbox", err, slog.String("messageid", messageID))
|
||||||
|
|
|
@ -1957,10 +1957,10 @@ func (Admin) SetPassword(ctx context.Context, accountName, password string) {
|
||||||
xcheckf(ctx, err, "setting password")
|
xcheckf(ctx, err, "setting password")
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAccountLimits set new limits on outgoing messages for an account.
|
// AccountSettingsSave set new settings for an account that only an admin can set.
|
||||||
func (Admin) SetAccountLimits(ctx context.Context, accountName string, maxOutgoingMessagesPerDay, maxFirstTimeRecipientsPerDay int, maxMsgSize int64) {
|
func (Admin) AccountSettingsSave(ctx context.Context, accountName string, maxOutgoingMessagesPerDay, maxFirstTimeRecipientsPerDay int, maxMsgSize int64, firstTimeSenderDelay bool) {
|
||||||
err := mox.AccountLimitsSave(ctx, accountName, maxOutgoingMessagesPerDay, maxFirstTimeRecipientsPerDay, maxMsgSize)
|
err := mox.AccountAdminSettingsSave(ctx, accountName, maxOutgoingMessagesPerDay, maxFirstTimeRecipientsPerDay, maxMsgSize, firstTimeSenderDelay)
|
||||||
xcheckf(ctx, err, "saving account limits")
|
xcheckf(ctx, err, "saving account settings")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientConfigsDomain returns configurations for email clients, IMAP and
|
// ClientConfigsDomain returns configurations for email clients, IMAP and
|
||||||
|
|
|
@ -795,12 +795,12 @@ var api;
|
||||||
const params = [accountName, password];
|
const params = [accountName, password];
|
||||||
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params);
|
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params);
|
||||||
}
|
}
|
||||||
// SetAccountLimits set new limits on outgoing messages for an account.
|
// AccountSettingsSave set new settings for an account that only an admin can set.
|
||||||
async SetAccountLimits(accountName, maxOutgoingMessagesPerDay, maxFirstTimeRecipientsPerDay, maxMsgSize) {
|
async AccountSettingsSave(accountName, maxOutgoingMessagesPerDay, maxFirstTimeRecipientsPerDay, maxMsgSize, firstTimeSenderDelay) {
|
||||||
const fn = "SetAccountLimits";
|
const fn = "AccountSettingsSave";
|
||||||
const paramTypes = [["string"], ["int32"], ["int32"], ["int64"]];
|
const paramTypes = [["string"], ["int32"], ["int32"], ["int64"], ["bool"]];
|
||||||
const returnTypes = [];
|
const returnTypes = [];
|
||||||
const params = [accountName, maxOutgoingMessagesPerDay, maxFirstTimeRecipientsPerDay, maxMsgSize];
|
const params = [accountName, maxOutgoingMessagesPerDay, maxFirstTimeRecipientsPerDay, maxMsgSize, firstTimeSenderDelay];
|
||||||
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params);
|
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params);
|
||||||
}
|
}
|
||||||
// ClientConfigsDomain returns configurations for email clients, IMAP and
|
// ClientConfigsDomain returns configurations for email clients, IMAP and
|
||||||
|
@ -1807,6 +1807,7 @@ const account = async (name) => {
|
||||||
let maxOutgoingMessagesPerDay;
|
let maxOutgoingMessagesPerDay;
|
||||||
let maxFirstTimeRecipientsPerDay;
|
let maxFirstTimeRecipientsPerDay;
|
||||||
let quotaMessageSize;
|
let quotaMessageSize;
|
||||||
|
let firstTimeSenderDelay;
|
||||||
let formPassword;
|
let formPassword;
|
||||||
let fieldsetPassword;
|
let fieldsetPassword;
|
||||||
let password;
|
let password;
|
||||||
|
@ -1892,13 +1893,13 @@ 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('Localpart', attr.title('The localpart is the part before the "@"-sign of an email address. If empty, a catchall address is configured for the domain.')), dom.br(), localpart = dom.input()), '@', dom.label(style({ display: 'inline-block' }), dom.span('Domain'), dom.br(), domain = dom.select((domains || []).map(d => dom.option(domainName(d), domainName(d) === config.Domain ? attr.selected('') : [])))), ' ', 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))), ' Current usage is ', formatQuotaSize(Math.floor(diskUsage / (1024 * 1024)) * 1024 * 1024), '.'), dom.submitbutton('Save')), async function submit(e) {
|
}, fieldset = dom.fieldset(dom.label(style({ display: 'inline-block' }), dom.span('Localpart', attr.title('The localpart is the part before the "@"-sign of an email address. If empty, a catchall address is configured for the domain.')), dom.br(), localpart = dom.input()), '@', dom.label(style({ display: 'inline-block' }), dom.span('Domain'), dom.br(), domain = dom.select((domains || []).map(d => dom.option(domainName(d), domainName(d) === config.Domain ? attr.selected('') : [])))), ' ', dom.submitbutton('Add address'))), dom.br(), dom.h2('Settings'), 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))), ' Current usage is ', formatQuotaSize(Math.floor(diskUsage / (1024 * 1024)) * 1024 * 1024), '.'), dom.div(style({ display: 'block', marginBottom: '.5ex' }), dom.label(firstTimeSenderDelay = dom.input(attr.type('checkbox'), config.NoFirstTimeSenderDelay ? [] : attr.checked('')), ' ', dom.span('Delay deliveries from first-time senders.', attr.title('To slow down potential spammers, when the message is misclassified as non-junk. Turning off the delay can be useful when the account processes messages automatically and needs fast responses.')))), dom.submitbutton('Save')), async function submit(e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
fieldsetLimits.disabled = true;
|
fieldsetLimits.disabled = true;
|
||||||
try {
|
try {
|
||||||
await client.SetAccountLimits(name, parseInt(maxOutgoingMessagesPerDay.value) || 0, parseInt(maxFirstTimeRecipientsPerDay.value) || 0, xparseSize(quotaMessageSize.value));
|
await client.AccountSettingsSave(name, parseInt(maxOutgoingMessagesPerDay.value) || 0, parseInt(maxFirstTimeRecipientsPerDay.value) || 0, xparseSize(quotaMessageSize.value), firstTimeSenderDelay.checked);
|
||||||
window.alert('Limits saved.');
|
window.alert('Settings saved.');
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
console.log({ err });
|
console.log({ err });
|
||||||
|
|
|
@ -637,6 +637,7 @@ const account = async (name: string) => {
|
||||||
let maxOutgoingMessagesPerDay: HTMLInputElement
|
let maxOutgoingMessagesPerDay: HTMLInputElement
|
||||||
let maxFirstTimeRecipientsPerDay: HTMLInputElement
|
let maxFirstTimeRecipientsPerDay: HTMLInputElement
|
||||||
let quotaMessageSize: HTMLInputElement
|
let quotaMessageSize: HTMLInputElement
|
||||||
|
let firstTimeSenderDelay: HTMLInputElement
|
||||||
|
|
||||||
let formPassword: HTMLFormElement
|
let formPassword: HTMLFormElement
|
||||||
let fieldsetPassword: HTMLFieldSetElement
|
let fieldsetPassword: HTMLFieldSetElement
|
||||||
|
@ -769,7 +770,7 @@ const account = async (name: string) => {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
dom.br(),
|
dom.br(),
|
||||||
dom.h2('Limits'),
|
dom.h2('Settings'),
|
||||||
dom.form(
|
dom.form(
|
||||||
fieldsetLimits=dom.fieldset(
|
fieldsetLimits=dom.fieldset(
|
||||||
dom.label(
|
dom.label(
|
||||||
|
@ -791,6 +792,13 @@ const account = async (name: string) => {
|
||||||
quotaMessageSize=dom.input(attr.value(formatQuotaSize(config.QuotaMessageSize))),
|
quotaMessageSize=dom.input(attr.value(formatQuotaSize(config.QuotaMessageSize))),
|
||||||
' Current usage is ', formatQuotaSize(Math.floor(diskUsage/(1024*1024))*1024*1024), '.',
|
' Current usage is ', formatQuotaSize(Math.floor(diskUsage/(1024*1024))*1024*1024), '.',
|
||||||
),
|
),
|
||||||
|
dom.div(
|
||||||
|
style({display: 'block', marginBottom: '.5ex'}),
|
||||||
|
dom.label(
|
||||||
|
firstTimeSenderDelay=dom.input(attr.type('checkbox'), config.NoFirstTimeSenderDelay ? [] : attr.checked('')), ' ',
|
||||||
|
dom.span('Delay deliveries from first-time senders.', attr.title('To slow down potential spammers, when the message is misclassified as non-junk. Turning off the delay can be useful when the account processes messages automatically and needs fast responses.')),
|
||||||
|
),
|
||||||
|
),
|
||||||
dom.submitbutton('Save'),
|
dom.submitbutton('Save'),
|
||||||
),
|
),
|
||||||
async function submit(e: SubmitEvent) {
|
async function submit(e: SubmitEvent) {
|
||||||
|
@ -798,8 +806,8 @@ const account = async (name: string) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
fieldsetLimits.disabled = true
|
fieldsetLimits.disabled = true
|
||||||
try {
|
try {
|
||||||
await client.SetAccountLimits(name, parseInt(maxOutgoingMessagesPerDay.value) || 0, parseInt(maxFirstTimeRecipientsPerDay.value) || 0, xparseSize(quotaMessageSize.value))
|
await client.AccountSettingsSave(name, parseInt(maxOutgoingMessagesPerDay.value) || 0, parseInt(maxFirstTimeRecipientsPerDay.value) || 0, xparseSize(quotaMessageSize.value), firstTimeSenderDelay.checked)
|
||||||
window.alert('Limits saved.')
|
window.alert('Settings saved.')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log({err})
|
console.log({err})
|
||||||
window.alert('Error: ' + errmsg(err))
|
window.alert('Error: ' + errmsg(err))
|
||||||
|
|
|
@ -617,8 +617,8 @@
|
||||||
"Returns": []
|
"Returns": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "SetAccountLimits",
|
"Name": "AccountSettingsSave",
|
||||||
"Docs": "SetAccountLimits set new limits on outgoing messages for an account.",
|
"Docs": "AccountSettingsSave set new settings for an account that only an admin can set.",
|
||||||
"Params": [
|
"Params": [
|
||||||
{
|
{
|
||||||
"Name": "accountName",
|
"Name": "accountName",
|
||||||
|
@ -643,6 +643,12 @@
|
||||||
"Typewords": [
|
"Typewords": [
|
||||||
"int64"
|
"int64"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "firstTimeSenderDelay",
|
||||||
|
"Typewords": [
|
||||||
|
"bool"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Returns": []
|
"Returns": []
|
||||||
|
|
|
@ -1276,12 +1276,12 @@ export class Client {
|
||||||
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params) as void
|
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params) as void
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAccountLimits set new limits on outgoing messages for an account.
|
// AccountSettingsSave set new settings for an account that only an admin can set.
|
||||||
async SetAccountLimits(accountName: string, maxOutgoingMessagesPerDay: number, maxFirstTimeRecipientsPerDay: number, maxMsgSize: number): Promise<void> {
|
async AccountSettingsSave(accountName: string, maxOutgoingMessagesPerDay: number, maxFirstTimeRecipientsPerDay: number, maxMsgSize: number, firstTimeSenderDelay: boolean): Promise<void> {
|
||||||
const fn: string = "SetAccountLimits"
|
const fn: string = "AccountSettingsSave"
|
||||||
const paramTypes: string[][] = [["string"],["int32"],["int32"],["int64"]]
|
const paramTypes: string[][] = [["string"],["int32"],["int32"],["int64"],["bool"]]
|
||||||
const returnTypes: string[][] = []
|
const returnTypes: string[][] = []
|
||||||
const params: any[] = [accountName, maxOutgoingMessagesPerDay, maxFirstTimeRecipientsPerDay, maxMsgSize]
|
const params: any[] = [accountName, maxOutgoingMessagesPerDay, maxFirstTimeRecipientsPerDay, maxMsgSize, firstTimeSenderDelay]
|
||||||
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params) as void
|
return await _sherpaCall(this.baseURL, this.authState, { ...this.options }, paramTypes, returnTypes, fn, params) as void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue