@social-mail/social-mail-web-server 1.4.800 → 1.4.802

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/common/BufferStream.d.ts +9 -6
  2. package/dist/common/BufferStream.d.ts.map +1 -1
  3. package/dist/common/BufferStream.js +117 -13
  4. package/dist/common/BufferStream.js.map +1 -1
  5. package/dist/protocols/core/Queue.d.ts +4 -0
  6. package/dist/protocols/core/Queue.d.ts.map +1 -1
  7. package/dist/protocols/core/Queue.js +19 -0
  8. package/dist/protocols/core/Queue.js.map +1 -1
  9. package/dist/protocols/imap/client/ImapClient.js +1 -1
  10. package/dist/protocols/imap/client/ImapClient.js.map +1 -1
  11. package/dist/protocols/smtp/ESmtpClient.d.ts.map +1 -1
  12. package/dist/protocols/smtp/ESmtpClient.js +5 -4
  13. package/dist/protocols/smtp/ESmtpClient.js.map +1 -1
  14. package/dist/protocols/socket/client/SocketClient.d.ts +4 -7
  15. package/dist/protocols/socket/client/SocketClient.d.ts.map +1 -1
  16. package/dist/protocols/socket/client/SocketClient.js +15 -189
  17. package/dist/protocols/socket/client/SocketClient.js.map +1 -1
  18. package/dist/server/model/events/EmailLogEvents.d.ts.map +1 -1
  19. package/dist/server/model/events/EmailLogEvents.js.map +1 -1
  20. package/dist/server/seed/ui/seed-ui.js +1 -1
  21. package/dist/tests/core/buffer/buffer-stream.test.d.ts +2 -0
  22. package/dist/tests/core/buffer/buffer-stream.test.d.ts.map +1 -0
  23. package/dist/tests/core/buffer/buffer-stream.test.js +75 -0
  24. package/dist/tests/core/buffer/buffer-stream.test.js.map +1 -0
  25. package/dist/tests/protocols/parsers/email-parser.test.d.ts.map +1 -1
  26. package/dist/tests/protocols/parsers/email-parser.test.js +0 -32
  27. package/dist/tests/protocols/parsers/email-parser.test.js.map +1 -1
  28. package/dist/tests/services/smtp/auth.d.ts +1 -1
  29. package/dist/tests/services/smtp/auth.d.ts.map +1 -1
  30. package/dist/tests/services/smtp/auth.js +3 -3
  31. package/dist/tests/services/smtp/auth.js.map +1 -1
  32. package/dist/tsconfig.tsbuildinfo +1 -1
  33. package/package.json +1 -1
  34. package/src/common/BufferStream.ts +137 -10
  35. package/src/protocols/core/Queue.ts +23 -1
  36. package/src/protocols/imap/client/ImapClient.ts +1 -1
  37. package/src/protocols/smtp/ESmtpClient.ts +5 -4
  38. package/src/protocols/socket/client/SocketClient.ts +13 -130
  39. package/src/server/model/events/EmailLogEvents.ts +0 -4
  40. package/src/server/seed/ui/seed-ui.ts +1 -1
  41. package/src/tests/core/buffer/buffer-stream.test.ts +106 -0
  42. package/src/tests/protocols/parsers/email-parser.test.ts +0 -36
  43. package/src/tests/services/smtp/auth.ts +3 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@social-mail/social-mail-web-server",
3
- "version": "1.4.800",
3
+ "version": "1.4.802",
4
4
  "description": "## Phase 1",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -1,18 +1,145 @@
1
- import { Readable } from "node:stream";
1
+ import Queue from "../protocols/core/Queue.js";
2
2
 
3
- export class BufferStream extends Readable {
3
+ const empty = Buffer.alloc(0);
4
4
 
5
- public static from(buffer: Buffer) {
6
- return new BufferStream(buffer);
5
+ class BufferList {
6
+
7
+ get size() {
8
+ return this.length;
9
+ }
10
+
11
+ private list =[];
12
+ private length = 0;
13
+
14
+ add(buffer: Buffer) {
15
+ this.list.push(buffer);
16
+ this.length += buffer.length;
17
+ return this;
18
+ }
19
+
20
+ asBuffer() {
21
+ return Buffer.concat(this.list);
22
+ }
23
+
24
+ toString(encoding: BufferEncoding) {
25
+ return this.asBuffer().toString(encoding);
26
+ }
27
+
28
+ clear() {
29
+ this.length = 0;
30
+ this.list.length = 0;
31
+ }
32
+
33
+ }
34
+
35
+ export class BufferStream {
36
+
37
+ store: Queue<Buffer> = new Queue();
38
+ start: number = 0;
39
+ unread: Buffer = empty;
40
+
41
+ get isDataAvailable() {
42
+ return !!this.store.peek;
43
+ }
44
+
45
+ enqueue(buffer: Buffer) {
46
+ this.store.enqueue(buffer);
47
+ return this;
7
48
  }
8
49
 
9
- constructor ( private buffer ){
10
- super();
11
- this.buffer = buffer;
50
+ async read(size: number, signal?: AbortSignal) {
51
+
52
+ if (size <= this.unread.length) {
53
+ // read this...
54
+ const slice = this.unread.subarray(0, size);
55
+ this.unread = size === this.unread.length
56
+ ? empty
57
+ : this.unread.subarray(size);
58
+ return slice;
59
+ }
60
+
61
+ const pending = new BufferList();
62
+ pending.add(this.unread);
63
+ this.unread = empty;
64
+
65
+ size -= pending.size;
66
+
67
+ for(;;) {
68
+
69
+ if (signal?.aborted) {
70
+ throw new Error("aborted");
71
+ }
72
+
73
+ const peek = await this.store.waitForPeek(signal);
74
+
75
+ const bufLen = this.start + size;
76
+
77
+ if (bufLen <= peek.length) {
78
+ pending.add(peek.subarray(this.start, bufLen));
79
+ const buffer = pending.asBuffer();
80
+ this.start = bufLen;
81
+ size -= bufLen;
82
+ this.unread = empty;
83
+ pending.clear();
84
+
85
+ if (bufLen === peek.length) {
86
+ this.store.dequeue();
87
+ this.start = 0;
88
+ }
89
+
90
+ return buffer;
91
+ }
92
+
93
+ const remaining = this.start ? peek.subarray(this.start) : peek;
94
+ pending.add(remaining);
95
+ size -= remaining.length;
96
+ this.store.dequeue();
97
+ this.start = 0;
98
+ }
12
99
  }
13
100
 
14
- _read (){
15
- this.push( this.buffer );
16
- this.push( null );
101
+ async readTill(sep : string | number | Buffer = 10, encoding: BufferEncoding = "utf8", trimR = false, signal?: AbortSignal) {
102
+ for(;;) {
103
+ const peek = await this.store.waitForPeek(signal);
104
+
105
+ if (signal?.aborted) {
106
+ throw new Error("aborted");
107
+ }
108
+
109
+ const index = peek.indexOf(sep, this.start);
110
+ if (index === -1) {
111
+ const remaining = this.start ? peek.subarray(this.start) : peek;
112
+ this.unread = Buffer.concat([ this.unread, remaining ]);
113
+ this.start = 0;
114
+ this.store.dequeue();
115
+ continue;
116
+ }
117
+
118
+ if (index === 0) {
119
+ // this is a special case...
120
+ const last = this.unread.length - 1;
121
+ if (trimR && this.unread.at(last) === 13) {
122
+ const t = this.unread.toString(encoding, 0, last);
123
+ this.unread = empty;
124
+ this.start = 1;
125
+ return t;
126
+ }
127
+ }
128
+
129
+ const subarray = peek.subarray(this.start, trimR && index && peek.at(index-1) === 13 ? index -1 : index);
130
+ const token = this.unread.length === 0
131
+ ? subarray
132
+ : Buffer.concat([this.unread, subarray]);
133
+ // this is last...
134
+ if (index + 1 === peek.length) {
135
+ this.start = 0;
136
+ this.store.dequeue();
137
+ } else {
138
+ this.start = index + 1;
139
+ }
140
+ this.unread = empty;
141
+ return token.toString(encoding);
142
+ }
17
143
  }
144
+
18
145
  }
@@ -6,15 +6,37 @@ export default class Queue<T> {
6
6
 
7
7
  public readonly eventItemAdded: EventSet<T> = new EventSet(this);
8
8
 
9
-
10
9
  get peek() {
11
10
  return this.store.get(this.head);
12
11
  }
13
12
 
13
+ get isEmpty() {
14
+ return this.head === this.tail;
15
+ }
16
+
17
+ get signal() {
18
+ return this.abortController.signal;
19
+ }
20
+
21
+ private readonly abortController: AbortController = new AbortController();
22
+
14
23
  private head = 0;
15
24
  private tail = 0;
16
25
  private readonly store: Map<number,T> = new Map();
17
26
 
27
+ public async waitForPeek(signal?: AbortSignal) {
28
+ if (this.isEmpty) {
29
+ await new Promise<any>((resolve, reject)=> {
30
+ this.eventItemAdded.listenOnce(resolve);
31
+ signal?.addEventListener("abort", () => {
32
+ this.abortController.abort("abort");
33
+ reject("abort");
34
+ });
35
+ });
36
+ }
37
+ return this.peek;
38
+ }
39
+
18
40
  public enqueue(item: T) {
19
41
  this.store.set(this.tail,item);
20
42
  this.tail++;
@@ -206,7 +206,7 @@ export default class ImapClient {
206
206
  // read these many bytes...
207
207
 
208
208
  // lastLine = lastLine.substring(0, index);
209
- const literal = await this.socket.readChars(length);
209
+ const literal = (await this.socket.readChars(length)).toString("ascii");
210
210
  // parser will take care of literal
211
211
  // data.push(`${lastLine}\r\n${current}`);
212
212
  // we will inject literal as an object with toString so
@@ -63,7 +63,7 @@ export default class ESmtpClient {
63
63
  }
64
64
 
65
65
  const eSmtpClient = new ESmtpClient(client, logger);
66
- await eSmtpClient.init(helo, greeting.toLocaleLowerCase().includes("esmtp"), host);
66
+ await eSmtpClient.init(helo, greeting.toLocaleLowerCase().includes("esmtp"), host, startTLS);
67
67
  const login = auth?.login;
68
68
  if (login) {
69
69
  await eSmtpClient.sendCommand("AUTH LOGIN",334);
@@ -148,17 +148,17 @@ export default class ESmtpClient {
148
148
  await this.sendCommand(".");
149
149
  }
150
150
 
151
- private async init(name: string, eSmtp = false, host?: string) {
151
+ private async init(name: string, eSmtp = false, host?: string, startTLS?: boolean) {
152
152
 
153
153
  let startTLSSupported = false;
154
154
 
155
155
  if (eSmtp) {
156
- await this.sendCommand(`EHLO ${name ?? os.hostname() }`, 250, (t) => startTLSSupported ||= /-STARTTLS$/i.test(t) );
156
+ await this.sendCommand(`EHLO ${name ?? os.hostname() }`, 250, (t) => startTLSSupported ||= /-STARTTLS/i.test(t) );
157
157
  } else {
158
158
  await this.sendCommand(`HELO ${name ?? os.hostname() }`);
159
159
  }
160
160
 
161
- if (startTLSSupported) {
161
+ if (startTLSSupported && startTLS) {
162
162
  await this.sendCommand("STARTTLS", 220);
163
163
  await this.client.upgradeTLS( { servername: host, rejectUnauthorized: false });
164
164
  await this.sendCommand(`EHLO ${name ?? os.hostname() }`);
@@ -175,6 +175,7 @@ export default class ESmtpClient {
175
175
  const lines = [];
176
176
  do {
177
177
  const response = await this.client.readLine();
178
+ this.logger?.(response);
178
179
  if (/^\d+\-/.test(response)) {
179
180
  parse?.(response);
180
181
  lines.push(response);
@@ -3,6 +3,7 @@ import Queue from "../../core/Queue.js";
3
3
  import EventSet from "@entity-access/entity-access/dist/common/EventSet.js";
4
4
  import tls, { TLSSocket } from "tls";
5
5
  import { AsyncDisposableScope } from "@entity-access/entity-access/dist/common/usingAsync.js";
6
+ import { BufferStream } from "../../../common/BufferStream.js";
6
7
 
7
8
  export default class SocketClient {
8
9
 
@@ -12,22 +13,17 @@ export default class SocketClient {
12
13
  const c = ssl
13
14
  ? tls.connect({ port, host, rejectUnauthorized: false })
14
15
  : host ? net.connect({ host, port }) : net.connect(port);
15
- const asc = new AbortController();
16
16
  c.once("error", (error) => {
17
17
  logger?.(error);
18
18
  reject(error);
19
19
  });
20
- c.on("close", () => {
21
- logger?.(`Connection closed`);
22
- asc.abort();
23
- });
24
- const q = new Queue<{ data: Buffer }>();
20
+ const bs = new BufferStream();
25
21
  c.on("data", (data) => {
26
- q.enqueue({ data });
22
+ bs.enqueue(data);
27
23
  });
28
24
  c.on("connect", () => {
29
25
  logger?.("Socket connected");
30
- resolve(new SocketClient(c, q, asc.signal, logger));
26
+ resolve(new SocketClient(c, bs , logger));
31
27
  });
32
28
  });
33
29
  logger?.(`Connection established`);
@@ -39,7 +35,7 @@ export default class SocketClient {
39
35
  eventClosed = new EventSet(this);
40
36
 
41
37
  get isDataAvailable() {
42
- return this.queue.peek;
38
+ return this.bufferStream.isDataAvailable;
43
39
  }
44
40
 
45
41
  /**
@@ -59,8 +55,8 @@ export default class SocketClient {
59
55
 
60
56
  private constructor(
61
57
  private client: net.Socket,
62
- private queue: Queue<{ data: Buffer }>,
63
- private signal: AbortSignal,
58
+ // private queue: Queue<{ data: Buffer }>,
59
+ private bufferStream: BufferStream,
64
60
  private logger: (data) => void = () => void 0,
65
61
  ) {
66
62
  this.client.setTimeout(30000);
@@ -111,121 +107,12 @@ export default class SocketClient {
111
107
  });
112
108
  }
113
109
 
114
- async readLine() {
115
-
116
- if (this.signal.aborted) {
117
- throw new Error("Aborted");
118
- }
119
-
120
- await using scope = new AsyncDisposableScope();
121
- return await new Promise<string>((resolve, reject) => {
122
-
123
- let start = "";
124
-
125
- this.signal.onabort = reject;
126
-
127
- const processPeek = () => {
128
- for(;;) {
129
- if (this.signal.aborted) {
130
- reject();
131
- return;
132
- }
133
- if (!this.queue.peek) {
134
- return;
135
- }
136
- const { data } = this.queue.peek;
137
- if (data.length === 0) {
138
- this.queue.dequeue();
139
- continue;
140
- }
141
- // This is edge case if \r was the last character
142
- // read and first character in buffer is \n (ASCII 10)
143
- if (start.endsWith("\r") && data.at(0) === 10 ) {
144
- start = start.substring(0, start.length-1);
145
- if (data.length === 1) {
146
- this.queue.dequeue();
147
- } else {
148
- this.queue.peek.data = data.subarray(1);
149
- }
150
- this.logger(`<< ${start}`);
151
- resolve(start);
152
- return;
153
- }
154
-
155
- // search for `\r\n`
156
- const index = data.indexOf('\r\n');
157
- if (index === -1) {
158
-
159
- start += data.toString("ascii");
160
- this.queue.dequeue();
161
- continue;
162
- }
163
-
164
- // it is last
165
- if (index === data.length - 2) {
166
- this.queue.dequeue();
167
- start += data.toString("ascii", 0, index);
168
- this.logger(`<< ${start}`);
169
- resolve(start);
170
- return;
171
- }
172
-
173
- this.queue.peek.data = data.subarray(index + 2);
174
- start += data.toString("ascii", 0, index);
175
- this.logger(`<< ${start}`);
176
- resolve(start);
177
- return;
178
- }
179
- };
180
-
181
- scope.register(this.queue.eventItemAdded.listen(processPeek));
182
-
183
- processPeek();
184
-
185
- });
110
+ readLine(signal?: AbortSignal) {
111
+ return this.bufferStream.readTill("\n", "ascii", true, signal);
186
112
  }
187
113
 
188
- public async readChars(length: number) {
189
- length = Number(length);
190
- let text = "";
191
- await using scope = new AsyncDisposableScope();
192
- return await new Promise<string>((resolve, reject) => {
193
- this.signal.onabort = reject;
194
- const processPeek = () => {
195
- for(;;) {
196
- if (this.signal.aborted) {
197
- reject(new Error("Aborted"));
198
- return;
199
- }
200
- if (!this.queue.peek) {
201
- return;
202
- }
203
- const { data } = this.queue.peek;
204
- if (data.length === 0) {
205
- this.queue.dequeue();
206
- continue;
207
- }
208
- if (data.length > length) {
209
- text += data.toString("ascii", 0, length);
210
- this.queue.peek.data = data.subarray(length);
211
- resolve(text);
212
- return;
213
- }
214
-
215
- text += data.toString("ascii");
216
- this.queue.dequeue();
217
- length -= data.length;
218
- if (length === 0) {
219
- resolve(text);
220
- return;
221
- }
222
- }
223
- };
224
-
225
- scope.register(this.queue.eventItemAdded.listen(processPeek));
226
-
227
- processPeek();
228
- });
114
+ public async readChars(length: number, signal?: AbortSignal) {
115
+ return this.bufferStream.read(length, signal);
229
116
  }
230
117
 
231
118
  public async upgradeTLS(options: tls.ConnectionOptions = { }) {
@@ -250,12 +137,8 @@ export default class SocketClient {
250
137
  ts.setTimeout(this.client.timeout);
251
138
  this.client.setTimeout(0);
252
139
  this.client = ts;
253
- this.queue = new Queue<{ data: Buffer}>();
254
- this.client.on("data", (data) => this.queue.enqueue({ data }));
255
- const ac = new AbortController();
256
- this.client.on("close", () => ac.abort());
257
- this.signal = ac.signal;
258
-
140
+ this.bufferStream = new BufferStream();
141
+ this.client.on("data", (data) => this.bufferStream.enqueue(data));
259
142
  this.client.on("close", this.eventClosed.dispatcher);
260
143
  this.client.on("timeout", this._onTimeout);
261
144
  this.client.on("error", this.eventError.dispatcher);
@@ -1,11 +1,7 @@
1
1
  import { IEntityQuery } from "@entity-access/entity-access/dist/model/IFilterWithParameter.js";
2
2
  import BaseEvents from "./BaseEvents.js";
3
- import ChangeEntry from "@entity-access/entity-access/dist/model/changes/ChangeEntry.js";
4
3
  import Inject from "@entity-access/entity-access/dist/di/di.js";
5
4
  import BaseStorage from "../../storage/BaseStorage.js";
6
- import { Readable, Stream } from "stream";
7
- import { BufferStream } from "../../../common/BufferStream.js";
8
- import DateTime from "@entity-access/entity-access/dist/types/DateTime.js";
9
5
  import TempFileService from "../../storage/TempFileService.js";
10
6
  import { EmailLog } from "../entities/Email.js";
11
7
 
@@ -3,7 +3,7 @@ import semver from "semver";
3
3
 
4
4
  export default async function seedUI(config: DBConfig) {
5
5
 
6
- const version = "1.2.312";
6
+ const version = "1.2.314";
7
7
 
8
8
  const existing = await config.get(UIPackageConfig, false);
9
9
  if (existing) {
@@ -0,0 +1,106 @@
1
+ import assert from "assert";
2
+ import { BufferStream } from "../../../common/BufferStream.js";
3
+
4
+ export default async function() {
5
+
6
+ await readSizes();
7
+
8
+ await readLines();
9
+ }
10
+
11
+ async function readLines() {
12
+ const bf = new BufferStream();
13
+
14
+ setTimeout(() => bf.enqueue(Buffer.from("1234")), 10);
15
+
16
+ setTimeout(() => bf.enqueue(Buffer.from("5678")), 10);
17
+ setTimeout(() => bf.enqueue(Buffer.from("90\n12")), 10);
18
+
19
+ let line = await bf.readTill("\n");
20
+ assert.equal("1234567890", line);
21
+
22
+ setTimeout(() => bf.enqueue(Buffer.from("12\n34")), 10);
23
+
24
+ setTimeout(() => bf.enqueue(Buffer.from("5678")), 10);
25
+ setTimeout(() => bf.enqueue(Buffer.from("90\n12")), 10);
26
+
27
+ line = await bf.readTill("\n");
28
+ assert.equal("1212", line);
29
+ line = await bf.readTill("\n");
30
+ assert.equal("34567890", line);
31
+
32
+ line = (await bf.read(2)).toString("utf8");
33
+ assert.equal("12", line);
34
+
35
+ setTimeout(() => bf.enqueue(Buffer.from("12\n1234\n12345")), 10);
36
+ setTimeout(() => bf.enqueue(Buffer.from("6\n")), 10);
37
+ setTimeout(() => bf.enqueue(Buffer.from("123456\r\n")), 10);
38
+
39
+ line = await bf.readTill("\n");
40
+ assert.equal("12", line);
41
+ line = await bf.readTill("\n");
42
+ assert.equal("1234", line);
43
+ line = await bf.readTill("\n");
44
+ assert.equal("123456", line);
45
+
46
+ line = await bf.readTill("\n", "ascii", true);
47
+ assert.equal("123456", line);
48
+ setTimeout(() => bf.enqueue(Buffer.from("123456\r")), 10);
49
+ setTimeout(() => bf.enqueue(Buffer.from("\n123456\r\n")), 10);
50
+ line = await bf.readTill("\n", "ascii", true);
51
+ assert.equal("123456", line);
52
+ line = await bf.readTill("\n", "ascii", true);
53
+ assert.equal("123456", line);
54
+ }
55
+
56
+ async function readSizes() {
57
+ const bf = new BufferStream();
58
+
59
+ setTimeout(() => bf.enqueue(Buffer.from("1234")), 10);
60
+
61
+ let b1 = await bf.read(1);
62
+ assert.equal("1", b1.toString("utf8"));
63
+
64
+ b1 = await bf.read(2);
65
+ assert.equal("23", b1.toString("utf8"));
66
+
67
+ b1 = await bf.read(1);
68
+ assert.equal("4", b1.toString("utf8"));
69
+
70
+ setTimeout(() => bf.enqueue(Buffer.from("1234")), 10);
71
+
72
+ b1 = await bf.read(1);
73
+ assert.equal("1", b1.toString("utf8"));
74
+
75
+ setTimeout(() => bf.enqueue(Buffer.from("1234")), 10);
76
+ setTimeout(() => bf.enqueue(Buffer.from("1234")), 10);
77
+
78
+ b1 = await bf.read(2);
79
+ assert.equal("23", b1.toString("utf8"));
80
+
81
+ b1 = await bf.read(2);
82
+ assert.equal("41", b1.toString("utf8"));
83
+
84
+ b1 = await bf.read(7);
85
+ assert.equal("2341234", b1.toString("utf8"));
86
+
87
+ setTimeout(() => bf.enqueue(Buffer.from("1234567890")), 10);
88
+ setTimeout(() => bf.enqueue(Buffer.from("1234567890")), 10);
89
+
90
+ b1 = await bf.read(1);
91
+ assert.equal("1", b1.toString("utf8"));
92
+
93
+ b1 = await bf.read(2);
94
+ assert.equal("23", b1.toString("utf8"));
95
+
96
+ b1 = await bf.read(1);
97
+ assert.equal("4", b1.toString("utf8"));
98
+
99
+ b1 = await bf.read(10);
100
+ assert.equal("5678901234", b1.toString("utf8"));
101
+
102
+ b1 = await bf.read(6);
103
+ assert.equal("567890", b1.toString("utf8"));
104
+
105
+ assert.equal(0, bf.start);
106
+ }
@@ -3,42 +3,6 @@ import { MimeNode, ReadableLineStream, LineStream } from "@social-mail/shared/in
3
3
  import { LocalFile } from "@entity-access/server-pages/dist/core/LocalFile.js";
4
4
  import { tmpName } from "tmp-promise";
5
5
 
6
- class FileLineStream extends LineStream {
7
-
8
- constructor(private file: LocalFile) {
9
- super();
10
- }
11
-
12
- async *lines() {
13
- let line = "";
14
- const trimEndR = (t: string) => {
15
- if (t.endsWith("\r")) {
16
- return t.substring(0, t.length - 1);
17
- }
18
- return t;
19
- };
20
- for await(const buffer of this.file.readBuffers(4 * 1024 * 1024)) {
21
- let start = 0;
22
- do {
23
-
24
- const index = buffer.indexOf("\n", start);
25
- if (index === -1) {
26
- line += buffer.toString("utf8", start);
27
- break;
28
- }
29
-
30
- yield trimEndR(line + buffer.toString("utf8", start, index));
31
- start = index + 1;
32
- line = "";
33
- } while (true);
34
- }
35
- line = trimEndR(line);
36
- if (line) {
37
- yield line;
38
- }
39
- }
40
- }
41
-
42
6
  export default async function() {
43
7
 
44
8
  const tmp = await tmpName();
@@ -3,7 +3,7 @@ import ESmtpClient from "../../../protocols/smtp/ESmtpClient.js";
3
3
 
4
4
  export default async function () {
5
5
 
6
- return true;
6
+ // return true;
7
7
 
8
8
  using c = await ESmtpClient.connect({
9
9
  port: 25,
@@ -11,8 +11,8 @@ export default async function () {
11
11
  helo: "localhost",
12
12
  auth: {
13
13
  login: {
14
- username: "",
15
- password: ""
14
+ username: "a",
15
+ password: "b"
16
16
  }
17
17
  },
18
18
  logger: console.log