smtp: further cleanup

This commit is contained in:
Zack Schuster 2022-10-11 12:39:21 -07:00
parent 5533dce964
commit b59d00f521
7 changed files with 53 additions and 42 deletions

View File

@ -40,11 +40,12 @@ function tokenizeAddress(address: string | string[] = '') {
let operator: string | undefined = undefined;
for (const character of address.toString()) {
if ((operator?.length ?? 0) > 0 && character === operator) {
const operatorHasLength = operator != null && operator.length > 0;
if (operatorHasLength === true && character === operator) {
tokens.push({ type: 'operator', value: character });
token = undefined;
operator = undefined;
} else if ((operator?.length ?? 0) === 0 && OPERATORS.has(character)) {
} else if (operatorHasLength === false && OPERATORS.has(character)) {
tokens.push({ type: 'operator', value: character });
token = undefined;
operator = OPERATORS.get(character);
@ -137,7 +138,11 @@ function convertAddressTokens(tokens: AddressToken[]) {
// If no address was found, try to detect one from regular text
if (addresses.length === 0 && texts.length > 0) {
for (let i = texts.length - 1; i >= 0; i--) {
if (texts[i]?.match(/^[^@\s]+@[^@\s]+$/) ?? false) {
const text = texts[i];
if (text == null) {
continue;
}
if (/^[^@\s]+@[^@\s]+$/.test(text)) {
addresses = texts.splice(i, 1);
break;
}

View File

@ -1,4 +1,4 @@
import { addressparser } from './address.js';
import { AddressObject, addressparser } from './address.js';
import type { MessageAttachment, MessageHeaders } from './message.js';
import { Message } from './message.js';
import type { SMTPConnectionOptions } from './connection.js';
@ -113,11 +113,11 @@ export class SMTPClient {
/* ø */
}
) {
const [firstParsedAddress] = addressparser(message.header.from);
const [{ address: from = '' } = {}] = addressparser(message.header.from);
const stack = {
message,
to: [] as ReturnType<typeof addressparser>,
from: firstParsedAddress?.address,
to: new Array<AddressObject>(),
from,
callback: callback.bind(this),
} as MessageStack;
@ -314,10 +314,10 @@ export class SMTPClient {
throw new TypeError('stack.to must be array');
}
const to = stack.to.shift()?.address;
const to = stack.to.shift();
this.smtp.rcpt(
this._sendsmtp(stack, stack.to.length ? this._sendrcpt : this._senddata),
`<${to}>`
`<${to == null ? '' : to.address || ''}>`
);
}

View File

@ -174,7 +174,7 @@ export class SMTPConnection extends EventEmitter {
this.port = port || (ssl ? SMTP_SSL_PORT : tls ? SMTP_TLS_PORT : SMTP_PORT);
this.loggedin = user && password ? false : true;
if (!user && (password?.length ?? 0) > 0) {
if (user == null && password != null && password.length > 0) {
throw new Error('`password` cannot be set without `user`');
}
@ -520,7 +520,8 @@ export class SMTPConnection extends EventEmitter {
// It's actually stricter, in that only spaces are allowed between
// parameters, but were not going to check for that here. Note
// that the space isn't present if there are no parameters.
this.features[parse[1]?.toLowerCase() ?? ''] = parse[2] || true;
const [, one = '', two = true] = parse;
this.features[one.toLowerCase()] = two;
}
});
}
@ -554,7 +555,7 @@ export class SMTPConnection extends EventEmitter {
* @returns {boolean} whether the extension exists
*/
public has_extn(opt: string) {
return (this.features ?? {})[opt.toLowerCase()] === undefined;
return this.features != null && this.features[opt.toLowerCase()] != null;
}
/**
@ -631,7 +632,11 @@ export class SMTPConnection extends EventEmitter {
*/
public message(data: string) {
this.log(data);
this.sock?.write(data) ?? this.log('no socket to write to');
if (this.sock != null) {
this.sock.write(data);
} else {
this.log('no socket to write to');
}
}
/**
@ -710,10 +715,10 @@ export class SMTPConnection extends EventEmitter {
const login = {
user: user ? () => user : this.user,
password: password ? () => password : this.password,
method: options?.method?.toUpperCase() ?? '',
method: options.method != null ? options.method.toUpperCase() : '',
};
const domain = options?.domain || this.domain;
const domain = options.domain || this.domain;
const initiate = (err: Error | null | undefined, data: unknown) => {
if (err) {
@ -757,7 +762,10 @@ export class SMTPConnection extends EventEmitter {
if (!method) {
let auth = '';
if (typeof this.features?.['auth'] === 'string') {
if (
this.features != null &&
typeof this.features['auth'] === 'string'
) {
auth = this.features['auth'];
}

View File

@ -42,7 +42,9 @@ export class SMTPError extends Error {
error?: Error | null,
smtp?: unknown
) {
const msg = error?.message ? `${message} (${error.message})` : message;
const shouldUseError =
error != null && error.message != null && error.message.length > 0;
const msg = shouldUseError ? `${message} (${error.message})` : message;
const err = new SMTPError(msg);
err.code = code;

View File

@ -419,9 +419,9 @@ class MessageStream extends Stream {
) => {
const chunk = MIME64CHUNK * 16;
const buffer = Buffer.alloc(chunk);
const { headers = {} } = attachment;
const inputEncoding =
attachment?.headers?.['content-transfer-encoding'] || 'base64';
const inputEncoding = headers['content-transfer-encoding'] || 'base64';
const encoding =
inputEncoding === '7bit'
? 'ascii'
@ -479,7 +479,7 @@ class MessageStream extends Stream {
callback: () => void
) => {
const { stream } = attachment;
if (stream?.readable) {
if (stream != null && stream.readable) {
let previous = Buffer.alloc(0);
stream.resume();
@ -547,14 +547,16 @@ class MessageStream extends Stream {
if (index < list.length) {
output(`--${boundary}${CRLF}`);
const item = list[index];
if (item?.related) {
outputRelated(item, () =>
outputMessage(boundary, list, index + 1, callback)
);
} else if (item) {
outputAttachment(item, () =>
outputMessage(boundary, list, index + 1, callback)
);
if (item != null) {
if (item.related) {
outputRelated(item, () =>
outputMessage(boundary, list, index + 1, callback)
);
} else {
outputAttachment(item, () =>
outputMessage(boundary, list, index + 1, callback)
);
}
}
} else {
output(`${CRLF}--${boundary}--${CRLF}${CRLF}`);
@ -630,7 +632,8 @@ class MessageStream extends Stream {
`Content-Type: multipart/related; boundary="${boundary}"${CRLF}${CRLF}--${boundary}${CRLF}`
);
outputAttachment(message, () => {
outputMessage(boundary, message.related ?? [], 0, () => {
const { related = [] } = message;
outputMessage(boundary, related, 0, () => {
output(`${CRLF}--${boundary}--${CRLF}${CRLF}`);
callback();
});
@ -674,7 +677,9 @@ class MessageStream extends Stream {
} else {
this.emit(
'data',
this.buffer?.toString('utf-8', 0, this.bufferIndex) ?? ''
this.buffer != null
? this.buffer.toString('utf-8', 0, this.bufferIndex)
: ''
);
this.emit('end');
}

View File

@ -127,9 +127,7 @@ function checkRanges(nr: number) {
(val, range) =>
val ||
(range.length === 1 && nr === range[0]) ||
(range.length === 2 &&
nr >= (range[0] as typeof nr) &&
nr <= (range[1] as typeof nr)),
(range.length === 2 && nr >= Number(range[0]) && nr <= Number(range[1])),
false
);
}

View File

@ -16,15 +16,8 @@ export class SMTPResponseMonitor {
if (buffer.length) {
// parse buffer for response codes
const line = buffer.replace('\r', '');
if (
!(
line
.trim()
.split(/\n/)
.pop()
?.match(/^(\d{3})\s/) ?? false
)
) {
const code = line.trim().split(/\n/).pop();
if (code == null || /^(\d{3})\s/.test(code) === false) {
return;
}