@upyo/smtp 0.6.0-dev.299 → 0.6.0-dev.301

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.
package/dist/index.cjs CHANGED
@@ -563,6 +563,37 @@ var SmtpPipelineTerminatedError = class extends Error {
563
563
  }
564
564
  };
565
565
  /**
566
+ * An authentication failure backed by an SMTP server reply.
567
+ *
568
+ * This keeps {@link SmtpAuthError} as the public authentication error while
569
+ * retaining the reply fields needed to build structured transport receipts.
570
+ *
571
+ * @since 0.6.0
572
+ */
573
+ var SmtpAuthResponseError = class extends SmtpAuthError {
574
+ /** The numeric SMTP reply code returned by the server. */
575
+ code;
576
+ /** The authentication command that produced the reply. */
577
+ command;
578
+ /** The textual SMTP reply returned by the server. */
579
+ response;
580
+ /**
581
+ * Creates an authentication response error.
582
+ *
583
+ * @param message A human-readable description of the authentication failure.
584
+ * @param code The numeric SMTP reply code.
585
+ * @param command The authentication command that produced the reply.
586
+ * @param response The textual SMTP reply returned by the server.
587
+ */
588
+ constructor(message, code, command, response) {
589
+ super(message);
590
+ this.name = "SmtpAuthResponseError";
591
+ this.code = code;
592
+ this.command = command;
593
+ this.response = response;
594
+ }
595
+ };
596
+ /**
566
597
  * The maximum length of an SMTP command line, including the terminating CRLF,
567
598
  * as specified by RFC 5321 §4.5.3.1.4.
568
599
  */
@@ -951,16 +982,16 @@ var SmtpConnection = class {
951
982
  const { user, pass } = auth;
952
983
  const credentials = btoa(`\0${user}\0${pass}`);
953
984
  const response = await this.sendCommand(`AUTH PLAIN ${credentials}`, signal);
954
- if (response.code !== 235) throw new Error(`Authentication failed: ${response.message}`);
985
+ if (response.code !== 235) throw new SmtpAuthResponseError(`Authentication failed: ${response.message}`, response.code, "AUTH PLAIN", response.message);
955
986
  }
956
987
  async authLogin(auth, signal) {
957
988
  const { user, pass } = auth;
958
989
  let response = await this.sendCommand("AUTH LOGIN", signal);
959
- if (response.code !== 334) throw new Error(`AUTH LOGIN failed: ${response.message}`);
990
+ if (response.code !== 334) throw new SmtpAuthResponseError(`AUTH LOGIN failed: ${response.message}`, response.code, "AUTH LOGIN", response.message);
960
991
  response = await this.sendCommand(btoa(user), signal);
961
- if (response.code !== 334) throw new Error(`Username authentication failed: ${response.message}`);
992
+ if (response.code !== 334) throw new SmtpAuthResponseError(`Username authentication failed: ${response.message}`, response.code, "AUTH LOGIN", response.message);
962
993
  response = await this.sendCommand(btoa(pass), signal);
963
- if (response.code !== 235) throw new Error(`Password authentication failed: ${response.message}`);
994
+ if (response.code !== 235) throw new SmtpAuthResponseError(`Password authentication failed: ${response.message}`, response.code, "AUTH LOGIN", response.message);
964
995
  }
965
996
  /**
966
997
  * Resolves an OAuth 2.0 access token via the connection's token manager,
@@ -1012,16 +1043,19 @@ var SmtpConnection = class {
1012
1043
  async finishOAuth2(response, mechanism, continuation, signal) {
1013
1044
  if (response.code === 235) return;
1014
1045
  if (response.code === 334) {
1046
+ let finalResponse;
1015
1047
  let finalMessage = "";
1016
1048
  try {
1017
- const final = await this.sendCommand(continuation, signal);
1018
- finalMessage = ` (${final.message})`;
1049
+ finalResponse = await this.sendCommand(continuation, signal);
1050
+ finalMessage = ` (${finalResponse.message})`;
1019
1051
  } catch {
1020
1052
  signal?.throwIfAborted();
1021
1053
  }
1022
- throw new SmtpAuthError(`${mechanism} authentication failed: ${decodeOAuth2Challenge(response.message)}${finalMessage}`);
1054
+ const message = `${mechanism} authentication failed: ${decodeOAuth2Challenge(response.message)}${finalMessage}`;
1055
+ if (finalResponse != null) throw new SmtpAuthResponseError(message, finalResponse.code, `AUTH ${mechanism}`, finalResponse.message);
1056
+ throw new SmtpAuthError(message);
1023
1057
  }
1024
- throw new SmtpAuthError(`${mechanism} authentication failed: ${response.message}`);
1058
+ throw new SmtpAuthResponseError(`${mechanism} authentication failed: ${response.message}`, response.code, `AUTH ${mechanism}`, response.message);
1025
1059
  }
1026
1060
  async sendMessage(message, signal) {
1027
1061
  signal?.throwIfAborted();
@@ -2049,7 +2083,7 @@ function createSmtpFailure(message, error) {
2049
2083
  attempts: 1,
2050
2084
  providerDetails: { missingCapability: error.missingCapability }
2051
2085
  });
2052
- if (error instanceof SmtpResponseError) {
2086
+ if (error instanceof SmtpResponseError || error instanceof SmtpAuthResponseError) {
2053
2087
  const enhancedStatusCode = parseEnhancedSmtpStatusCode(error.code, error.response);
2054
2088
  const classification = classifySmtpReply(error.code, enhancedStatusCode);
2055
2089
  return (0, __upyo_core.createFailedReceipt)(message, {
@@ -2061,7 +2095,7 @@ function createSmtpFailure(message, error) {
2061
2095
  providerDetails: {
2062
2096
  command: error.command,
2063
2097
  response: error.response,
2064
- rejectedRecipients: error.rejectedRecipients,
2098
+ rejectedRecipients: error instanceof SmtpResponseError ? error.rejectedRecipients : void 0,
2065
2099
  ...enhancedStatusCode == null ? {} : { enhancedStatusCode }
2066
2100
  }
2067
2101
  });
package/dist/index.js CHANGED
@@ -540,6 +540,37 @@ var SmtpPipelineTerminatedError = class extends Error {
540
540
  }
541
541
  };
542
542
  /**
543
+ * An authentication failure backed by an SMTP server reply.
544
+ *
545
+ * This keeps {@link SmtpAuthError} as the public authentication error while
546
+ * retaining the reply fields needed to build structured transport receipts.
547
+ *
548
+ * @since 0.6.0
549
+ */
550
+ var SmtpAuthResponseError = class extends SmtpAuthError {
551
+ /** The numeric SMTP reply code returned by the server. */
552
+ code;
553
+ /** The authentication command that produced the reply. */
554
+ command;
555
+ /** The textual SMTP reply returned by the server. */
556
+ response;
557
+ /**
558
+ * Creates an authentication response error.
559
+ *
560
+ * @param message A human-readable description of the authentication failure.
561
+ * @param code The numeric SMTP reply code.
562
+ * @param command The authentication command that produced the reply.
563
+ * @param response The textual SMTP reply returned by the server.
564
+ */
565
+ constructor(message, code, command, response) {
566
+ super(message);
567
+ this.name = "SmtpAuthResponseError";
568
+ this.code = code;
569
+ this.command = command;
570
+ this.response = response;
571
+ }
572
+ };
573
+ /**
543
574
  * The maximum length of an SMTP command line, including the terminating CRLF,
544
575
  * as specified by RFC 5321 §4.5.3.1.4.
545
576
  */
@@ -928,16 +959,16 @@ var SmtpConnection = class {
928
959
  const { user, pass } = auth;
929
960
  const credentials = btoa(`\0${user}\0${pass}`);
930
961
  const response = await this.sendCommand(`AUTH PLAIN ${credentials}`, signal);
931
- if (response.code !== 235) throw new Error(`Authentication failed: ${response.message}`);
962
+ if (response.code !== 235) throw new SmtpAuthResponseError(`Authentication failed: ${response.message}`, response.code, "AUTH PLAIN", response.message);
932
963
  }
933
964
  async authLogin(auth, signal) {
934
965
  const { user, pass } = auth;
935
966
  let response = await this.sendCommand("AUTH LOGIN", signal);
936
- if (response.code !== 334) throw new Error(`AUTH LOGIN failed: ${response.message}`);
967
+ if (response.code !== 334) throw new SmtpAuthResponseError(`AUTH LOGIN failed: ${response.message}`, response.code, "AUTH LOGIN", response.message);
937
968
  response = await this.sendCommand(btoa(user), signal);
938
- if (response.code !== 334) throw new Error(`Username authentication failed: ${response.message}`);
969
+ if (response.code !== 334) throw new SmtpAuthResponseError(`Username authentication failed: ${response.message}`, response.code, "AUTH LOGIN", response.message);
939
970
  response = await this.sendCommand(btoa(pass), signal);
940
- if (response.code !== 235) throw new Error(`Password authentication failed: ${response.message}`);
971
+ if (response.code !== 235) throw new SmtpAuthResponseError(`Password authentication failed: ${response.message}`, response.code, "AUTH LOGIN", response.message);
941
972
  }
942
973
  /**
943
974
  * Resolves an OAuth 2.0 access token via the connection's token manager,
@@ -989,16 +1020,19 @@ var SmtpConnection = class {
989
1020
  async finishOAuth2(response, mechanism, continuation, signal) {
990
1021
  if (response.code === 235) return;
991
1022
  if (response.code === 334) {
1023
+ let finalResponse;
992
1024
  let finalMessage = "";
993
1025
  try {
994
- const final = await this.sendCommand(continuation, signal);
995
- finalMessage = ` (${final.message})`;
1026
+ finalResponse = await this.sendCommand(continuation, signal);
1027
+ finalMessage = ` (${finalResponse.message})`;
996
1028
  } catch {
997
1029
  signal?.throwIfAborted();
998
1030
  }
999
- throw new SmtpAuthError(`${mechanism} authentication failed: ${decodeOAuth2Challenge(response.message)}${finalMessage}`);
1031
+ const message = `${mechanism} authentication failed: ${decodeOAuth2Challenge(response.message)}${finalMessage}`;
1032
+ if (finalResponse != null) throw new SmtpAuthResponseError(message, finalResponse.code, `AUTH ${mechanism}`, finalResponse.message);
1033
+ throw new SmtpAuthError(message);
1000
1034
  }
1001
- throw new SmtpAuthError(`${mechanism} authentication failed: ${response.message}`);
1035
+ throw new SmtpAuthResponseError(`${mechanism} authentication failed: ${response.message}`, response.code, `AUTH ${mechanism}`, response.message);
1002
1036
  }
1003
1037
  async sendMessage(message, signal) {
1004
1038
  signal?.throwIfAborted();
@@ -2026,7 +2060,7 @@ function createSmtpFailure(message, error) {
2026
2060
  attempts: 1,
2027
2061
  providerDetails: { missingCapability: error.missingCapability }
2028
2062
  });
2029
- if (error instanceof SmtpResponseError) {
2063
+ if (error instanceof SmtpResponseError || error instanceof SmtpAuthResponseError) {
2030
2064
  const enhancedStatusCode = parseEnhancedSmtpStatusCode(error.code, error.response);
2031
2065
  const classification = classifySmtpReply(error.code, enhancedStatusCode);
2032
2066
  return createFailedReceipt(message, {
@@ -2038,7 +2072,7 @@ function createSmtpFailure(message, error) {
2038
2072
  providerDetails: {
2039
2073
  command: error.command,
2040
2074
  response: error.response,
2041
- rejectedRecipients: error.rejectedRecipients,
2075
+ rejectedRecipients: error instanceof SmtpResponseError ? error.rejectedRecipients : void 0,
2042
2076
  ...enhancedStatusCode == null ? {} : { enhancedStatusCode }
2043
2077
  }
2044
2078
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@upyo/smtp",
3
- "version": "0.6.0-dev.299",
3
+ "version": "0.6.0-dev.301",
4
4
  "description": "SMTP transport for Upyo email library",
5
5
  "keywords": [
6
6
  "email",
@@ -53,7 +53,7 @@
53
53
  },
54
54
  "sideEffects": false,
55
55
  "peerDependencies": {
56
- "@upyo/core": "0.6.0-dev.299+9e97f9f2"
56
+ "@upyo/core": "0.6.0-dev.301+877ca1c9"
57
57
  },
58
58
  "devDependencies": {
59
59
  "tsdown": "^0.12.7",