@nocobase/plugin-workflow-mailer 2.4.0-alpha.1 → 2.4.0-alpha.11

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 (187) hide show
  1. package/dist/externalVersion.js +6 -6
  2. package/dist/node_modules/joi/dist/joi-browser.min.js +1 -1
  3. package/dist/node_modules/joi/lib/index.js +1 -1
  4. package/dist/node_modules/joi/lib/messages.js +35 -6
  5. package/dist/node_modules/joi/lib/types/keys.js +18 -1
  6. package/dist/node_modules/joi/lib/types/link.js +18 -2
  7. package/dist/node_modules/joi/lib/types/string.js +2 -2
  8. package/dist/node_modules/joi/package.json +1 -1
  9. package/dist/node_modules/nodemailer/dist/cjs/addressparser/index.d.ts +59 -0
  10. package/dist/node_modules/nodemailer/dist/cjs/addressparser/index.js +790 -0
  11. package/dist/node_modules/nodemailer/dist/cjs/base64/index.d.ts +36 -0
  12. package/dist/node_modules/nodemailer/dist/cjs/base64/index.js +119 -0
  13. package/dist/node_modules/nodemailer/dist/cjs/dkim/index.d.ts +52 -0
  14. package/dist/node_modules/nodemailer/dist/cjs/dkim/index.js +228 -0
  15. package/dist/node_modules/nodemailer/dist/cjs/dkim/message-parser.d.ts +48 -0
  16. package/dist/node_modules/nodemailer/dist/cjs/dkim/message-parser.js +180 -0
  17. package/dist/node_modules/nodemailer/dist/cjs/dkim/relaxed-body.d.ts +36 -0
  18. package/dist/node_modules/nodemailer/dist/cjs/dkim/relaxed-body.js +148 -0
  19. package/dist/node_modules/nodemailer/dist/cjs/dkim/sign.d.ts +52 -0
  20. package/dist/node_modules/nodemailer/dist/cjs/dkim/sign.js +165 -0
  21. package/dist/node_modules/nodemailer/dist/cjs/errors.d.ts +96 -0
  22. package/dist/node_modules/nodemailer/dist/cjs/errors.js +70 -0
  23. package/dist/node_modules/nodemailer/dist/cjs/fetch/cookies.d.ts +107 -0
  24. package/dist/node_modules/nodemailer/dist/cjs/fetch/cookies.js +282 -0
  25. package/dist/node_modules/nodemailer/dist/cjs/fetch/index.d.ts +65 -0
  26. package/dist/node_modules/nodemailer/dist/cjs/fetch/index.js +384 -0
  27. package/dist/node_modules/nodemailer/dist/cjs/json-transport/index.d.ts +64 -0
  28. package/dist/node_modules/nodemailer/dist/cjs/json-transport/index.js +99 -0
  29. package/dist/node_modules/nodemailer/dist/cjs/mail-composer/index.d.ts +174 -0
  30. package/dist/node_modules/nodemailer/dist/cjs/mail-composer/index.js +613 -0
  31. package/dist/node_modules/nodemailer/dist/cjs/mailer/index.d.ts +237 -0
  32. package/dist/node_modules/nodemailer/dist/cjs/mailer/index.js +415 -0
  33. package/dist/node_modules/nodemailer/dist/cjs/mailer/mail-message.d.ts +97 -0
  34. package/dist/node_modules/nodemailer/dist/cjs/mailer/mail-message.js +342 -0
  35. package/dist/node_modules/nodemailer/dist/cjs/mime-funcs/index.d.ts +161 -0
  36. package/dist/node_modules/nodemailer/dist/cjs/mime-funcs/index.js +787 -0
  37. package/dist/node_modules/nodemailer/dist/cjs/mime-funcs/mime-types.d.ts +2 -0
  38. package/dist/node_modules/nodemailer/dist/cjs/mime-funcs/mime-types.js +2103 -0
  39. package/dist/node_modules/nodemailer/dist/cjs/mime-node/index.d.ts +333 -0
  40. package/dist/node_modules/nodemailer/dist/cjs/mime-node/index.js +1493 -0
  41. package/dist/node_modules/nodemailer/dist/cjs/mime-node/last-newline.d.ts +5 -0
  42. package/dist/node_modules/nodemailer/dist/cjs/mime-node/last-newline.js +32 -0
  43. package/dist/node_modules/nodemailer/dist/cjs/mime-node/le-unix.d.ts +9 -0
  44. package/dist/node_modules/nodemailer/dist/cjs/mime-node/le-unix.js +40 -0
  45. package/dist/node_modules/nodemailer/dist/cjs/mime-node/le-windows.d.ts +10 -0
  46. package/dist/node_modules/nodemailer/dist/cjs/mime-node/le-windows.js +47 -0
  47. package/dist/node_modules/nodemailer/dist/cjs/nodemailer.d.ts +124 -0
  48. package/dist/node_modules/nodemailer/dist/cjs/nodemailer.js +1 -0
  49. package/dist/node_modules/nodemailer/dist/cjs/package-info.d.ts +3 -0
  50. package/dist/node_modules/nodemailer/dist/cjs/package-info.js +7 -0
  51. package/dist/node_modules/nodemailer/dist/cjs/package.json +3 -0
  52. package/dist/node_modules/nodemailer/dist/cjs/punycode/index.d.ts +73 -0
  53. package/dist/node_modules/nodemailer/{lib → dist/cjs}/punycode/index.js +63 -112
  54. package/dist/node_modules/nodemailer/dist/cjs/qp/index.d.ts +32 -0
  55. package/dist/node_modules/nodemailer/dist/cjs/qp/index.js +207 -0
  56. package/dist/node_modules/nodemailer/dist/cjs/sendmail-transport/index.d.ts +69 -0
  57. package/dist/node_modules/nodemailer/dist/cjs/sendmail-transport/index.js +210 -0
  58. package/dist/node_modules/nodemailer/dist/cjs/ses-transport/index.d.ts +112 -0
  59. package/dist/node_modules/nodemailer/dist/cjs/ses-transport/index.js +252 -0
  60. package/dist/node_modules/nodemailer/dist/cjs/shared/index.d.ts +260 -0
  61. package/dist/node_modules/nodemailer/dist/cjs/shared/index.js +680 -0
  62. package/dist/node_modules/nodemailer/dist/cjs/shared/objects.d.ts +23 -0
  63. package/dist/node_modules/nodemailer/dist/cjs/shared/objects.js +43 -0
  64. package/dist/node_modules/nodemailer/dist/cjs/shared/url.d.ts +21 -0
  65. package/dist/node_modules/nodemailer/dist/cjs/shared/url.js +255 -0
  66. package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/data-stream.d.ts +15 -0
  67. package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/data-stream.js +108 -0
  68. package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/http-proxy-client.d.ts +47 -0
  69. package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/http-proxy-client.js +189 -0
  70. package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/index.d.ts +416 -0
  71. package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/index.js +1837 -0
  72. package/dist/node_modules/nodemailer/dist/cjs/smtp-pool/index.d.ts +133 -0
  73. package/dist/node_modules/nodemailer/dist/cjs/smtp-pool/index.js +569 -0
  74. package/dist/node_modules/nodemailer/dist/cjs/smtp-pool/pool-resource.d.ts +62 -0
  75. package/dist/node_modules/nodemailer/dist/cjs/smtp-pool/pool-resource.js +257 -0
  76. package/dist/node_modules/nodemailer/dist/cjs/smtp-transport/index.d.ts +156 -0
  77. package/dist/node_modules/nodemailer/dist/cjs/smtp-transport/index.js +371 -0
  78. package/dist/node_modules/nodemailer/dist/cjs/stream-transport/index.d.ts +65 -0
  79. package/dist/node_modules/nodemailer/dist/cjs/stream-transport/index.js +146 -0
  80. package/dist/node_modules/nodemailer/dist/cjs/well-known/index.d.ts +35 -0
  81. package/dist/node_modules/nodemailer/dist/cjs/well-known/index.js +41 -0
  82. package/dist/node_modules/nodemailer/dist/cjs/well-known/services.d.ts +2 -0
  83. package/dist/node_modules/nodemailer/dist/cjs/well-known/services.js +674 -0
  84. package/dist/node_modules/nodemailer/dist/cjs/xoauth2/index.d.ts +201 -0
  85. package/dist/node_modules/nodemailer/dist/cjs/xoauth2/index.js +426 -0
  86. package/dist/node_modules/nodemailer/dist/esm/addressparser/index.d.ts +59 -0
  87. package/dist/node_modules/nodemailer/dist/esm/addressparser/index.js +786 -0
  88. package/dist/node_modules/nodemailer/dist/esm/base64/index.d.ts +36 -0
  89. package/dist/node_modules/nodemailer/{lib → dist/esm}/base64/index.js +39 -68
  90. package/dist/node_modules/nodemailer/dist/esm/dkim/index.d.ts +52 -0
  91. package/dist/node_modules/nodemailer/{lib → dist/esm}/dkim/index.js +62 -92
  92. package/dist/node_modules/nodemailer/dist/esm/dkim/message-parser.d.ts +48 -0
  93. package/dist/node_modules/nodemailer/dist/esm/dkim/message-parser.js +176 -0
  94. package/dist/node_modules/nodemailer/dist/esm/dkim/relaxed-body.d.ts +36 -0
  95. package/dist/node_modules/nodemailer/dist/esm/dkim/relaxed-body.js +141 -0
  96. package/dist/node_modules/nodemailer/dist/esm/dkim/sign.d.ts +52 -0
  97. package/dist/node_modules/nodemailer/dist/esm/dkim/sign.js +125 -0
  98. package/dist/node_modules/nodemailer/dist/esm/errors.d.ts +96 -0
  99. package/dist/node_modules/nodemailer/dist/esm/errors.js +67 -0
  100. package/dist/node_modules/nodemailer/dist/esm/fetch/cookies.d.ts +107 -0
  101. package/dist/node_modules/nodemailer/dist/esm/fetch/cookies.js +242 -0
  102. package/dist/node_modules/nodemailer/dist/esm/fetch/index.d.ts +65 -0
  103. package/dist/node_modules/nodemailer/dist/esm/fetch/index.js +344 -0
  104. package/dist/node_modules/nodemailer/dist/esm/json-transport/index.d.ts +64 -0
  105. package/dist/node_modules/nodemailer/dist/esm/json-transport/index.js +62 -0
  106. package/dist/node_modules/nodemailer/dist/esm/mail-composer/index.d.ts +174 -0
  107. package/dist/node_modules/nodemailer/{lib → dist/esm}/mail-composer/index.js +283 -275
  108. package/dist/node_modules/nodemailer/dist/esm/mailer/index.d.ts +237 -0
  109. package/dist/node_modules/nodemailer/{lib → dist/esm}/mailer/index.js +151 -205
  110. package/dist/node_modules/nodemailer/dist/esm/mailer/mail-message.d.ts +97 -0
  111. package/dist/node_modules/nodemailer/{lib → dist/esm}/mailer/mail-message.js +111 -125
  112. package/dist/node_modules/nodemailer/dist/esm/mime-funcs/index.d.ts +161 -0
  113. package/dist/node_modules/nodemailer/dist/esm/mime-funcs/index.js +738 -0
  114. package/dist/node_modules/nodemailer/dist/esm/mime-funcs/mime-types.d.ts +2 -0
  115. package/dist/node_modules/nodemailer/{lib → dist/esm}/mime-funcs/mime-types.js +43 -49
  116. package/dist/node_modules/nodemailer/dist/esm/mime-node/index.d.ts +333 -0
  117. package/dist/node_modules/nodemailer/{lib → dist/esm}/mime-node/index.js +576 -437
  118. package/dist/node_modules/nodemailer/dist/esm/mime-node/last-newline.d.ts +5 -0
  119. package/dist/node_modules/nodemailer/{lib → dist/esm}/mime-node/last-newline.js +4 -10
  120. package/dist/node_modules/nodemailer/dist/esm/mime-node/le-unix.d.ts +9 -0
  121. package/dist/node_modules/nodemailer/{lib → dist/esm}/mime-node/le-unix.js +7 -15
  122. package/dist/node_modules/nodemailer/dist/esm/mime-node/le-windows.d.ts +10 -0
  123. package/dist/node_modules/nodemailer/{lib → dist/esm}/mime-node/le-windows.js +6 -16
  124. package/dist/node_modules/nodemailer/dist/esm/nodemailer.d.ts +124 -0
  125. package/dist/node_modules/nodemailer/dist/esm/nodemailer.js +166 -0
  126. package/dist/node_modules/nodemailer/dist/esm/package-info.d.ts +3 -0
  127. package/dist/node_modules/nodemailer/dist/esm/package-info.js +4 -0
  128. package/dist/node_modules/nodemailer/dist/esm/package.json +3 -0
  129. package/dist/node_modules/nodemailer/dist/esm/punycode/index.d.ts +73 -0
  130. package/dist/node_modules/nodemailer/dist/esm/punycode/index.js +405 -0
  131. package/dist/node_modules/nodemailer/dist/esm/qp/index.d.ts +32 -0
  132. package/dist/node_modules/nodemailer/{lib → dist/esm}/qp/index.js +59 -77
  133. package/dist/node_modules/nodemailer/dist/esm/sendmail-transport/index.d.ts +69 -0
  134. package/dist/node_modules/nodemailer/dist/esm/sendmail-transport/index.js +170 -0
  135. package/dist/node_modules/nodemailer/dist/esm/ses-transport/index.d.ts +112 -0
  136. package/dist/node_modules/nodemailer/dist/esm/ses-transport/index.js +212 -0
  137. package/dist/node_modules/nodemailer/dist/esm/shared/index.d.ts +260 -0
  138. package/dist/node_modules/nodemailer/dist/esm/shared/index.js +631 -0
  139. package/dist/node_modules/nodemailer/dist/esm/shared/objects.d.ts +23 -0
  140. package/dist/node_modules/nodemailer/dist/esm/shared/objects.js +38 -0
  141. package/dist/node_modules/nodemailer/dist/esm/shared/url.d.ts +21 -0
  142. package/dist/node_modules/nodemailer/dist/esm/shared/url.js +214 -0
  143. package/dist/node_modules/nodemailer/dist/esm/smtp-connection/data-stream.d.ts +15 -0
  144. package/dist/node_modules/nodemailer/dist/esm/smtp-connection/data-stream.js +103 -0
  145. package/dist/node_modules/nodemailer/dist/esm/smtp-connection/http-proxy-client.d.ts +47 -0
  146. package/dist/node_modules/nodemailer/dist/esm/smtp-connection/http-proxy-client.js +149 -0
  147. package/dist/node_modules/nodemailer/dist/esm/smtp-connection/index.d.ts +416 -0
  148. package/dist/node_modules/nodemailer/dist/esm/smtp-connection/index.js +1797 -0
  149. package/dist/node_modules/nodemailer/dist/esm/smtp-pool/index.d.ts +133 -0
  150. package/dist/node_modules/nodemailer/{lib → dist/esm}/smtp-pool/index.js +195 -314
  151. package/dist/node_modules/nodemailer/dist/esm/smtp-pool/pool-resource.d.ts +62 -0
  152. package/dist/node_modules/nodemailer/{lib → dist/esm}/smtp-pool/pool-resource.js +70 -107
  153. package/dist/node_modules/nodemailer/dist/esm/smtp-transport/index.d.ts +156 -0
  154. package/dist/node_modules/nodemailer/dist/esm/smtp-transport/index.js +331 -0
  155. package/dist/node_modules/nodemailer/dist/esm/stream-transport/index.d.ts +65 -0
  156. package/dist/node_modules/nodemailer/dist/esm/stream-transport/index.js +106 -0
  157. package/dist/node_modules/nodemailer/dist/esm/well-known/index.d.ts +35 -0
  158. package/dist/node_modules/nodemailer/{lib → dist/esm}/well-known/index.js +12 -23
  159. package/dist/node_modules/nodemailer/dist/esm/well-known/services.d.ts +2 -0
  160. package/dist/node_modules/nodemailer/dist/esm/well-known/services.js +671 -0
  161. package/dist/node_modules/nodemailer/dist/esm/xoauth2/index.d.ts +201 -0
  162. package/dist/node_modules/nodemailer/dist/esm/xoauth2/index.js +386 -0
  163. package/dist/node_modules/nodemailer/dist/well-known/services.json +640 -0
  164. package/dist/node_modules/nodemailer/package.json +1 -1
  165. package/package.json +4 -4
  166. package/dist/node_modules/nodemailer/.gitattributes +0 -6
  167. package/dist/node_modules/nodemailer/.ncurc.js +0 -7
  168. package/dist/node_modules/nodemailer/.prettierrc.js +0 -8
  169. package/dist/node_modules/nodemailer/lib/addressparser/index.js +0 -313
  170. package/dist/node_modules/nodemailer/lib/dkim/message-parser.js +0 -155
  171. package/dist/node_modules/nodemailer/lib/dkim/relaxed-body.js +0 -154
  172. package/dist/node_modules/nodemailer/lib/dkim/sign.js +0 -117
  173. package/dist/node_modules/nodemailer/lib/fetch/cookies.js +0 -281
  174. package/dist/node_modules/nodemailer/lib/fetch/index.js +0 -274
  175. package/dist/node_modules/nodemailer/lib/json-transport/index.js +0 -82
  176. package/dist/node_modules/nodemailer/lib/mime-funcs/index.js +0 -625
  177. package/dist/node_modules/nodemailer/lib/nodemailer.js +0 -1
  178. package/dist/node_modules/nodemailer/lib/sendmail-transport/index.js +0 -210
  179. package/dist/node_modules/nodemailer/lib/ses-transport/index.js +0 -349
  180. package/dist/node_modules/nodemailer/lib/shared/index.js +0 -688
  181. package/dist/node_modules/nodemailer/lib/smtp-connection/data-stream.js +0 -108
  182. package/dist/node_modules/nodemailer/lib/smtp-connection/http-proxy-client.js +0 -143
  183. package/dist/node_modules/nodemailer/lib/smtp-connection/index.js +0 -1825
  184. package/dist/node_modules/nodemailer/lib/smtp-transport/index.js +0 -416
  185. package/dist/node_modules/nodemailer/lib/stream-transport/index.js +0 -135
  186. package/dist/node_modules/nodemailer/lib/well-known/services.json +0 -343
  187. package/dist/node_modules/nodemailer/lib/xoauth2/index.js +0 -376
@@ -0,0 +1,201 @@
1
+ import { Stream } from 'node:stream';
2
+ import crypto from 'node:crypto';
3
+ import * as shared from '../shared/index.js';
4
+ import type { ResultCallback } from '../errors.js';
5
+ import type { OutgoingHttpHeaders } from 'node:http';
6
+ /**
7
+ * Receives the result of a provisionCallback run: an error, or the new access token and
8
+ * an optional expire time in milliseconds
9
+ */
10
+ export type XOAuth2ProvisionResultCallback = (err: Error | null, accessToken?: string, expires?: number) => void;
11
+ /**
12
+ * Custom access token provider. `renew` is true when the existing token failed and a new
13
+ * one is needed
14
+ */
15
+ export type XOAuth2ProvisionCallback = (user: string, renew: boolean, callback: XOAuth2ProvisionResultCallback) => void;
16
+ /**
17
+ * Receives an access token, or the error that prevented generating one. Declared with a
18
+ * required token, the way @types/nodemailer declared it, the error path hands over the
19
+ * error alone
20
+ */
21
+ export type XOAuth2TokenCallback = (err: Error | null, accessToken: string) => void;
22
+ /**
23
+ * A private key accepted by crypto.createSign().sign()
24
+ */
25
+ export type XOAuth2PrivateKey = crypto.KeyLike | crypto.SignKeyObjectInput | crypto.SignPrivateKeyInput;
26
+ /**
27
+ * Client information for token generation
28
+ */
29
+ export interface XOAuth2Options {
30
+ /** User e-mail address */
31
+ user?: string | undefined;
32
+ /** Client ID value */
33
+ clientId?: string | undefined;
34
+ /** Client secret value */
35
+ clientSecret?: string | undefined;
36
+ /** Refresh token for an user */
37
+ refreshToken?: string | undefined;
38
+ /** Endpoint for token generation, defaults to 'https://accounts.google.com/o/oauth2/token' */
39
+ accessUrl?: string | undefined;
40
+ /** An existing valid accessToken */
41
+ accessToken?: string | undefined;
42
+ /** Private key for JSW */
43
+ privateKey?: XOAuth2PrivateKey | undefined;
44
+ /** Optional Access Token expire time in ms */
45
+ expires?: number | undefined;
46
+ /** Optional TTL for Access Token in seconds */
47
+ timeout?: number | undefined;
48
+ /** Function to run when a new access token is required */
49
+ provisionCallback?: XOAuth2ProvisionCallback | undefined;
50
+ /** Optional TLS options forwarded to the HTTPS token request. Defaults to strict cert validation; supply { rejectUnauthorized: false } only for self-hosted OAuth providers on private CAs. */
51
+ tls?: {
52
+ [key: string]: any;
53
+ } | undefined;
54
+ /** Service account client id (the JWT issuer), switches to the JWT bearer flow */
55
+ serviceClient?: string | undefined;
56
+ /** Lifetime of the service account JWT in seconds, defaults to 5 minutes, capped at an hour */
57
+ serviceRequestTimeout?: number | undefined;
58
+ /** OAuth2 scope for the service account flow, defaults to 'https://mail.google.com/' */
59
+ scope?: string | undefined;
60
+ /** Logger component name, defaults to 'OAuth2' */
61
+ component?: string | undefined;
62
+ /** Extra headers for the token request */
63
+ customHeaders?: OutgoingHttpHeaders | undefined;
64
+ /** Timeout for the token request in milliseconds, defaults to 60000, 0 disables it */
65
+ requestTimeout?: number | undefined;
66
+ /** Extra form fields for the token request */
67
+ customParams?: {
68
+ [key: string]: any;
69
+ } | undefined;
70
+ }
71
+ /**
72
+ * The object emitted with the 'token' event once a new access token has been generated
73
+ */
74
+ export interface XOAuth2Token {
75
+ /** User e-mail address */
76
+ user?: string | undefined;
77
+ /** The new access token */
78
+ accessToken: string;
79
+ /** Expire time as a timestamp in milliseconds, 0 when unknown */
80
+ expires: number;
81
+ }
82
+ /**
83
+ * A getToken request waiting for an in-flight renewal to complete
84
+ */
85
+ export interface XOAuth2QueuedRequest {
86
+ renew: boolean;
87
+ callback: ResultCallback<string>;
88
+ }
89
+ /**
90
+ * XOAUTH2 access_token generator for Gmail.
91
+ * Create client ID for web applications in Google API console to use it.
92
+ * See Offline Access for receiving the needed refreshToken for an user
93
+ * https://developers.google.com/accounts/docs/OAuth2WebServer#offline
94
+ *
95
+ * Usage for generating access tokens with a custom method using provisionCallback:
96
+ * provisionCallback(user, renew, callback)
97
+ * * user is the username to get the token for
98
+ * * renew is a boolean that if true indicates that existing token failed and needs to be renewed
99
+ * * callback is the callback to run with (error, accessToken [, expires])
100
+ * * accessToken is a string
101
+ * * expires is an optional expire time in milliseconds
102
+ * If provisionCallback is used, then Nodemailer does not try to attempt generating the token by itself
103
+ *
104
+ * @constructor
105
+ * @param options Client information for token generation
106
+ * @param options.user User e-mail address
107
+ * @param options.clientId Client ID value
108
+ * @param options.clientSecret Client secret value
109
+ * @param options.refreshToken Refresh token for an user
110
+ * @param options.accessUrl Endpoint for token generation, defaults to 'https://accounts.google.com/o/oauth2/token'
111
+ * @param options.accessToken An existing valid accessToken
112
+ * @param options.privateKey Private key for JSW
113
+ * @param options.expires Optional Access Token expire time in ms
114
+ * @param options.timeout Optional TTL for Access Token in seconds
115
+ * @param options.provisionCallback Function to run when a new access token is required
116
+ * @param options.tls Optional TLS options forwarded to the HTTPS token request. Defaults to strict cert validation; supply { rejectUnauthorized: false } only for self-hosted OAuth providers on private CAs.
117
+ */
118
+ declare class XOAuth2 extends Stream {
119
+ options: XOAuth2Options;
120
+ logger: shared.Logger;
121
+ provisionCallback: XOAuth2ProvisionCallback | false;
122
+ accessToken: string | false;
123
+ expires: number;
124
+ renewing: boolean;
125
+ renewalQueue: XOAuth2QueuedRequest[];
126
+ constructor(options?: XOAuth2Options, logger?: shared.ExternalLogger | boolean);
127
+ /**
128
+ * Returns or generates (if previous has expired) a XOAuth2 token
129
+ *
130
+ * @param renew If false then use cached access token (if available)
131
+ * @param callback Callback function with error object and token string
132
+ */
133
+ getToken(renew: boolean, callback: XOAuth2TokenCallback): void;
134
+ /**
135
+ * Updates token values
136
+ *
137
+ * @param accessToken New access token
138
+ * @param timeout Access token lifetime in seconds
139
+ *
140
+ * Emits 'token': { user: User email-address, accessToken: the new accessToken, timeout: TTL in seconds}
141
+ */
142
+ updateToken(accessToken: string, timeout?: number | string): void;
143
+ /**
144
+ * Generates a new XOAuth2 token with the credentials provided at initialization
145
+ *
146
+ * @param callback Callback function with error object and token string
147
+ */
148
+ generateToken(callback: XOAuth2TokenCallback): void;
149
+ /**
150
+ * Converts an access_token and user id into a base64 encoded XOAuth2 token
151
+ *
152
+ * @param [accessToken] Access token string
153
+ * @return Base64 encoded token for IMAP or SMTP login
154
+ */
155
+ buildXOAuth2Token(accessToken?: string): string;
156
+ /**
157
+ * Custom POST request handler.
158
+ * This is only needed to keep paths short in Windows, usually this module
159
+ * is a dependency of a dependency and if it tries to require something
160
+ * like the request module the paths get way too long to handle for Windows.
161
+ * As we do only a simple POST request we do not actually require complicated
162
+ * logic support (no redirects, no nothing) anyway.
163
+ *
164
+ * @param url Url to POST to
165
+ * @param payload Payload to POST
166
+ * @param params Client options, the customHeaders and tls values are used for the request
167
+ * @param callback Callback function with (err, buff)
168
+ */
169
+ postRequest(url: string, payload: {
170
+ [key: string]: any;
171
+ } | string | Buffer, params: XOAuth2Options, callback: (err: Error | null, buff?: Buffer) => void): void;
172
+ /**
173
+ * Encodes a buffer or a string into Base64url format
174
+ *
175
+ * @param data The data to convert
176
+ * @return The encoded string
177
+ */
178
+ toBase64URL(data: Buffer | string): string;
179
+ /**
180
+ * Creates a JSON Web Token signed with RS256 (SHA256 + RSA)
181
+ *
182
+ * @param payload The payload to include in the generated token
183
+ * @return The generated and signed token
184
+ */
185
+ jwtSignRS256(payload: {
186
+ [key: string]: any;
187
+ }): string;
188
+ }
189
+ /** The extra request settings of the token request, the customHeaders and customParams options */
190
+ export type XOAuth2RequestParams = Pick<XOAuth2Options, 'customHeaders' | 'customParams'>;
191
+ /**
192
+ * Type aliases in the layout of @types/nodemailer, so `XOAuth2.Options` style references keep working
193
+ */
194
+ declare namespace XOAuth2 {
195
+ type Options = XOAuth2Options;
196
+ type Token = XOAuth2Token;
197
+ type RequestParams = XOAuth2RequestParams;
198
+ }
199
+ /** The same aliases as module level exports, for `import * as XOAuth2` and `import XOAuth2 = require()` */
200
+ export type { XOAuth2Options as Options, XOAuth2Token as Token, XOAuth2RequestParams as RequestParams };
201
+ export default XOAuth2;
@@ -0,0 +1,386 @@
1
+ import { Stream } from 'node:stream';
2
+ import nmfetch from '../fetch/index.js';
3
+ import crypto from 'node:crypto';
4
+ import * as shared from '../shared/index.js';
5
+ import * as errors from '../errors.js';
6
+ /**
7
+ * XOAUTH2 access_token generator for Gmail.
8
+ * Create client ID for web applications in Google API console to use it.
9
+ * See Offline Access for receiving the needed refreshToken for an user
10
+ * https://developers.google.com/accounts/docs/OAuth2WebServer#offline
11
+ *
12
+ * Usage for generating access tokens with a custom method using provisionCallback:
13
+ * provisionCallback(user, renew, callback)
14
+ * * user is the username to get the token for
15
+ * * renew is a boolean that if true indicates that existing token failed and needs to be renewed
16
+ * * callback is the callback to run with (error, accessToken [, expires])
17
+ * * accessToken is a string
18
+ * * expires is an optional expire time in milliseconds
19
+ * If provisionCallback is used, then Nodemailer does not try to attempt generating the token by itself
20
+ *
21
+ * @constructor
22
+ * @param options Client information for token generation
23
+ * @param options.user User e-mail address
24
+ * @param options.clientId Client ID value
25
+ * @param options.clientSecret Client secret value
26
+ * @param options.refreshToken Refresh token for an user
27
+ * @param options.accessUrl Endpoint for token generation, defaults to 'https://accounts.google.com/o/oauth2/token'
28
+ * @param options.accessToken An existing valid accessToken
29
+ * @param options.privateKey Private key for JSW
30
+ * @param options.expires Optional Access Token expire time in ms
31
+ * @param options.timeout Optional TTL for Access Token in seconds
32
+ * @param options.provisionCallback Function to run when a new access token is required
33
+ * @param options.tls Optional TLS options forwarded to the HTTPS token request. Defaults to strict cert validation; supply { rejectUnauthorized: false } only for self-hosted OAuth providers on private CAs.
34
+ */
35
+ class XOAuth2 extends Stream {
36
+ constructor(options, logger) {
37
+ super();
38
+ this.options = options || {};
39
+ this.configError = false;
40
+ if (options && options.serviceClient) {
41
+ if (!options.privateKey || !options.user) {
42
+ // reported through getToken() rather than an 'error' event: the transports forward
43
+ // that event up to the Mail object, where nothing may be listening
44
+ const err = new Error('Options "privateKey" and "user" are required for service account!');
45
+ err.code = errors.EOAUTH2;
46
+ this.configError = err;
47
+ }
48
+ const serviceRequestTimeout = Math.min(Math.max(Number(this.options.serviceRequestTimeout) || 0, 0), 3600);
49
+ this.options.serviceRequestTimeout = serviceRequestTimeout || 5 * 60;
50
+ }
51
+ this.logger = shared.getLogger({
52
+ logger
53
+ }, {
54
+ component: this.options.component || 'OAuth2'
55
+ });
56
+ this.provisionCallback = typeof this.options.provisionCallback === 'function' ? this.options.provisionCallback : false;
57
+ this.options.accessUrl = this.options.accessUrl || 'https://accounts.google.com/o/oauth2/token';
58
+ this.options.customHeaders = this.options.customHeaders || {};
59
+ this.options.customParams = this.options.customParams || {};
60
+ this.accessToken = this.options.accessToken || false;
61
+ if (this.options.expires && Number(this.options.expires)) {
62
+ this.expires = this.options.expires;
63
+ }
64
+ else {
65
+ const timeout = Math.max(Number(this.options.timeout) || 0, 0);
66
+ this.expires = (timeout && Date.now() + timeout * 1000) || 0;
67
+ }
68
+ this.renewing = false; // Track if renewal is in progress
69
+ this.renewalQueue = []; // Queue for pending requests during renewal
70
+ }
71
+ /**
72
+ * Returns or generates (if previous has expired) a XOAuth2 token
73
+ *
74
+ * @param renew If false then use cached access token (if available)
75
+ * @param callback Callback function with error object and token string
76
+ */
77
+ getToken(renew, callback) {
78
+ // the error paths hand over the error alone
79
+ const done = callback;
80
+ if (this.configError) {
81
+ return done(this.configError);
82
+ }
83
+ if (!renew && this.accessToken && (!this.expires || this.expires > Date.now())) {
84
+ this.logger.debug({
85
+ tnx: 'OAUTH2',
86
+ user: this.options.user,
87
+ action: 'reuse'
88
+ }, 'Reusing existing access token for %s', this.options.user);
89
+ return callback(null, this.accessToken);
90
+ }
91
+ // check if it is possible to renew, if not, return the current token or error
92
+ if (!this.provisionCallback && !this.options.refreshToken && !this.options.serviceClient) {
93
+ if (this.accessToken) {
94
+ this.logger.debug({
95
+ tnx: 'OAUTH2',
96
+ user: this.options.user,
97
+ action: 'reuse'
98
+ }, 'Reusing existing access token (no refresh capability) for %s', this.options.user);
99
+ return callback(null, this.accessToken);
100
+ }
101
+ this.logger.error({
102
+ tnx: 'OAUTH2',
103
+ user: this.options.user,
104
+ action: 'renew'
105
+ }, 'Cannot renew access token for %s: No refresh mechanism available', this.options.user);
106
+ const err = new Error("Can't create new access token for user");
107
+ err.code = errors.EOAUTH2;
108
+ return done(err);
109
+ }
110
+ // If renewal already in progress, queue this request instead of starting another
111
+ if (this.renewing) {
112
+ this.renewalQueue.push({ renew, callback: done });
113
+ return;
114
+ }
115
+ this.renewing = true;
116
+ // Handles token renewal completion - processes queued requests and cleans up
117
+ const generateCallback = (err, accessToken) => {
118
+ this.renewalQueue.forEach(item => item.callback(err, accessToken));
119
+ this.renewalQueue = [];
120
+ this.renewing = false;
121
+ if (err) {
122
+ this.logger.error({
123
+ err,
124
+ tnx: 'OAUTH2',
125
+ user: this.options.user,
126
+ action: 'renew'
127
+ }, 'Failed generating new Access Token for %s', this.options.user);
128
+ }
129
+ else {
130
+ this.logger.info({
131
+ tnx: 'OAUTH2',
132
+ user: this.options.user,
133
+ action: 'renew'
134
+ }, 'Generated new Access Token for %s', this.options.user);
135
+ }
136
+ // Complete original request
137
+ done(err, accessToken);
138
+ };
139
+ if (this.provisionCallback) {
140
+ this.provisionCallback(this.options.user, !!renew, (err, accessToken, expires) => {
141
+ if (!err && accessToken) {
142
+ this.accessToken = accessToken;
143
+ this.expires = expires || 0;
144
+ }
145
+ generateCallback(err, accessToken);
146
+ });
147
+ }
148
+ else {
149
+ this.generateToken(generateCallback);
150
+ }
151
+ }
152
+ /**
153
+ * Updates token values
154
+ *
155
+ * @param accessToken New access token
156
+ * @param timeout Access token lifetime in seconds
157
+ *
158
+ * Emits 'token': { user: User email-address, accessToken: the new accessToken, timeout: TTL in seconds}
159
+ */
160
+ updateToken(accessToken, timeout) {
161
+ this.accessToken = accessToken;
162
+ timeout = Math.max(Number(timeout) || 0, 0);
163
+ this.expires = (timeout && Date.now() + timeout * 1000) || 0;
164
+ this.emit('token', {
165
+ user: this.options.user,
166
+ accessToken: accessToken || '',
167
+ expires: this.expires
168
+ });
169
+ }
170
+ /**
171
+ * Generates a new XOAuth2 token with the credentials provided at initialization
172
+ *
173
+ * @param callback Callback function with error object and token string
174
+ */
175
+ generateToken(callback) {
176
+ // the error paths hand over the error alone
177
+ const done = callback;
178
+ let urlOptions;
179
+ let loggedUrlOptions;
180
+ if (this.options.serviceClient) {
181
+ // service account - https://developers.google.com/identity/protocols/OAuth2ServiceAccount
182
+ const iat = Math.floor(Date.now() / 1000); // unix time
183
+ const tokenData = {
184
+ iss: this.options.serviceClient,
185
+ scope: this.options.scope || 'https://mail.google.com/',
186
+ sub: this.options.user,
187
+ aud: this.options.accessUrl,
188
+ iat,
189
+ exp: iat + this.options.serviceRequestTimeout
190
+ };
191
+ let token;
192
+ try {
193
+ token = this.jwtSignRS256(tokenData);
194
+ }
195
+ catch (_err) {
196
+ const err = new Error("Can't generate token. Check your auth options");
197
+ err.code = errors.EOAUTH2;
198
+ return done(err);
199
+ }
200
+ urlOptions = {
201
+ grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
202
+ assertion: token
203
+ };
204
+ loggedUrlOptions = {
205
+ grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
206
+ assertion: tokenData
207
+ };
208
+ }
209
+ else {
210
+ if (!this.options.refreshToken) {
211
+ const err = new Error("Can't create new access token for user");
212
+ err.code = errors.EOAUTH2;
213
+ return done(err);
214
+ }
215
+ // web app - https://developers.google.com/identity/protocols/OAuth2WebServer
216
+ urlOptions = {
217
+ client_id: this.options.clientId || '',
218
+ client_secret: this.options.clientSecret || '',
219
+ refresh_token: this.options.refreshToken,
220
+ grant_type: 'refresh_token'
221
+ };
222
+ loggedUrlOptions = {
223
+ client_id: this.options.clientId || '',
224
+ client_secret: (this.options.clientSecret || '').substr(0, 6) + '...',
225
+ refresh_token: (this.options.refreshToken || '').substr(0, 6) + '...',
226
+ grant_type: 'refresh_token'
227
+ };
228
+ }
229
+ Object.assign(urlOptions, this.options.customParams);
230
+ Object.assign(loggedUrlOptions, this.options.customParams);
231
+ this.logger.debug({
232
+ tnx: 'OAUTH2',
233
+ user: this.options.user,
234
+ action: 'generate'
235
+ }, 'Requesting token using: %s', JSON.stringify(loggedUrlOptions));
236
+ this.postRequest(this.options.accessUrl, urlOptions, this.options, (error, body) => {
237
+ let data;
238
+ if (error) {
239
+ return done(error);
240
+ }
241
+ try {
242
+ data = JSON.parse(body.toString());
243
+ }
244
+ catch (E) {
245
+ return done(E);
246
+ }
247
+ if (!data || typeof data !== 'object') {
248
+ this.logger.debug({
249
+ tnx: 'OAUTH2',
250
+ user: this.options.user,
251
+ action: 'post'
252
+ }, 'Response: %s', (body || '').toString());
253
+ const err = new Error('Invalid authentication response');
254
+ err.code = errors.EOAUTH2;
255
+ return done(err);
256
+ }
257
+ const logData = Object.assign({}, data);
258
+ if (logData.access_token) {
259
+ logData.access_token = (logData.access_token || '').toString().substr(0, 6) + '...';
260
+ }
261
+ this.logger.debug({
262
+ tnx: 'OAUTH2',
263
+ user: this.options.user,
264
+ action: 'post'
265
+ }, 'Response: %s', JSON.stringify(logData));
266
+ if (data.error) {
267
+ // Error Response : https://tools.ietf.org/html/rfc6749#section-5.2
268
+ let errorMessage = data.error;
269
+ if (data.error_description) {
270
+ errorMessage += ': ' + data.error_description;
271
+ }
272
+ if (data.error_uri) {
273
+ errorMessage += ' (' + data.error_uri + ')';
274
+ }
275
+ const err = new Error(errorMessage);
276
+ err.code = errors.EOAUTH2;
277
+ return done(err);
278
+ }
279
+ if (data.access_token) {
280
+ this.updateToken(data.access_token, data.expires_in);
281
+ return callback(null, this.accessToken);
282
+ }
283
+ const err = new Error('No access token');
284
+ err.code = errors.EOAUTH2;
285
+ return done(err);
286
+ });
287
+ }
288
+ /**
289
+ * Converts an access_token and user id into a base64 encoded XOAuth2 token
290
+ *
291
+ * @param [accessToken] Access token string
292
+ * @return Base64 encoded token for IMAP or SMTP login
293
+ */
294
+ buildXOAuth2Token(accessToken) {
295
+ const authData = ['user=' + (this.options.user || ''), 'auth=Bearer ' + (accessToken || this.accessToken), '', ''];
296
+ return Buffer.from(authData.join('\x01'), 'utf-8').toString('base64');
297
+ }
298
+ /**
299
+ * Custom POST request handler.
300
+ * This is only needed to keep paths short in Windows, usually this module
301
+ * is a dependency of a dependency and if it tries to require something
302
+ * like the request module the paths get way too long to handle for Windows.
303
+ * As we do only a simple POST request we do not actually require complicated
304
+ * logic support (no redirects, no nothing) anyway.
305
+ *
306
+ * @param url Url to POST to
307
+ * @param payload Payload to POST
308
+ * @param params Client options, the customHeaders and tls values are used for the request
309
+ * @param callback Callback function with (err, buff)
310
+ */
311
+ postRequest(url, payload, params, callback) {
312
+ let returned = false;
313
+ const chunks = [];
314
+ let chunklen = 0;
315
+ const fetchOptions = {
316
+ method: 'post',
317
+ headers: params.customHeaders,
318
+ body: payload,
319
+ allowErrorResponse: true,
320
+ // unset falls back to the fetch default, a stalled token endpoint would otherwise keep
321
+ // `renewing` set and queue every later request
322
+ timeout: params.requestTimeout
323
+ };
324
+ // OAuth2 token endpoints are credential-bearing. src/fetch already
325
+ // validates certs by default; pin rejectUnauthorized:true here so the
326
+ // token fetch stays strict, while still layering params.tls (the
327
+ // user's options.tls) on top so callers with a self-hosted provider on
328
+ // a private CA can override.
329
+ if (/^https:/i.test(url)) {
330
+ fetchOptions.tls = Object.assign({ rejectUnauthorized: true }, params.tls || {});
331
+ }
332
+ const req = nmfetch(url, fetchOptions);
333
+ req.on('readable', () => {
334
+ let chunk;
335
+ while ((chunk = req.read()) !== null) {
336
+ chunks.push(chunk);
337
+ chunklen += chunk.length;
338
+ }
339
+ });
340
+ req.once('error', err => {
341
+ if (returned) {
342
+ return;
343
+ }
344
+ returned = true;
345
+ return callback(err);
346
+ });
347
+ req.once('end', () => {
348
+ if (returned) {
349
+ return;
350
+ }
351
+ returned = true;
352
+ return callback(null, Buffer.concat(chunks, chunklen));
353
+ });
354
+ }
355
+ /**
356
+ * Encodes a buffer or a string into Base64url format
357
+ *
358
+ * @param data The data to convert
359
+ * @return The encoded string
360
+ */
361
+ toBase64URL(data) {
362
+ if (typeof data === 'string') {
363
+ data = Buffer.from(data);
364
+ }
365
+ return data
366
+ .toString('base64')
367
+ .replace(/[=]+/g, '') // remove '='s
368
+ .replace(/\+/g, '-') // '+' → '-'
369
+ .replace(/\//g, '_'); // '/' → '_'
370
+ }
371
+ /**
372
+ * Creates a JSON Web Token signed with RS256 (SHA256 + RSA)
373
+ *
374
+ * @param payload The payload to include in the generated token
375
+ * @return The generated and signed token
376
+ */
377
+ jwtSignRS256(payload) {
378
+ const signedPayload = ['{"alg":"RS256","typ":"JWT"}', JSON.stringify(payload)].map(val => this.toBase64URL(val)).join('.');
379
+ const signature = crypto
380
+ .createSign('RSA-SHA256')
381
+ .update(signedPayload)
382
+ .sign(this.options.privateKey);
383
+ return signedPayload + '.' + this.toBase64URL(signature);
384
+ }
385
+ }
386
+ export default XOAuth2;