@vsaas/loopback 10.0.0
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/LICENSE +25 -0
- package/README.md +91 -0
- package/common/models/README.md +109 -0
- package/common/models/access-token.json +37 -0
- package/common/models/acl.json +17 -0
- package/common/models/application.json +130 -0
- package/common/models/change.json +25 -0
- package/common/models/checkpoint.json +14 -0
- package/common/models/email.json +11 -0
- package/common/models/key-value-model.json +4 -0
- package/common/models/role-mapping.json +26 -0
- package/common/models/role.json +30 -0
- package/common/models/scope.json +14 -0
- package/common/models/user.json +118 -0
- package/dist/_virtual/_rolldown/runtime.cjs +32 -0
- package/dist/common/models/access-token.cjs +144 -0
- package/dist/common/models/access-token2.cjs +43 -0
- package/dist/common/models/acl.cjs +428 -0
- package/dist/common/models/acl2.cjs +27 -0
- package/dist/common/models/application.cjs +100 -0
- package/dist/common/models/application2.cjs +118 -0
- package/dist/common/models/change.cjs +404 -0
- package/dist/common/models/change2.cjs +25 -0
- package/dist/common/models/checkpoint.cjs +43 -0
- package/dist/common/models/checkpoint2.cjs +18 -0
- package/dist/common/models/email.cjs +18 -0
- package/dist/common/models/email2.cjs +30 -0
- package/dist/common/models/key-value-model.cjs +140 -0
- package/dist/common/models/key-value-model2.cjs +14 -0
- package/dist/common/models/role-mapping.cjs +57 -0
- package/dist/common/models/role-mapping2.cjs +34 -0
- package/dist/common/models/role.cjs +396 -0
- package/dist/common/models/role2.cjs +38 -0
- package/dist/common/models/scope.cjs +30 -0
- package/dist/common/models/scope2.cjs +21 -0
- package/dist/common/models/user.cjs +810 -0
- package/dist/common/models/user2.cjs +118 -0
- package/dist/index.cjs +16 -0
- package/dist/lib/access-context.cjs +228 -0
- package/dist/lib/application.cjs +450 -0
- package/dist/lib/builtin-models.cjs +60 -0
- package/dist/lib/configure-shared-methods.cjs +41 -0
- package/dist/lib/connectors/base-connector.cjs +23 -0
- package/dist/lib/connectors/mail-direct-transport.cjs +375 -0
- package/dist/lib/connectors/mail-stub-transport.cjs +86 -0
- package/dist/lib/connectors/mail.cjs +128 -0
- package/dist/lib/connectors/memory.cjs +19 -0
- package/dist/lib/current-context.cjs +22 -0
- package/dist/lib/globalize.cjs +29 -0
- package/dist/lib/loopback.cjs +313 -0
- package/dist/lib/model.cjs +1009 -0
- package/dist/lib/persisted-model.cjs +1835 -0
- package/dist/lib/registry.cjs +291 -0
- package/dist/lib/runtime.cjs +25 -0
- package/dist/lib/server-app.cjs +231 -0
- package/dist/lib/utils.cjs +154 -0
- package/dist/package.cjs +124 -0
- package/dist/server/middleware/context.cjs +7 -0
- package/dist/server/middleware/error-handler.cjs +6 -0
- package/dist/server/middleware/favicon.cjs +13 -0
- package/dist/server/middleware/rest.cjs +44 -0
- package/dist/server/middleware/static.cjs +14 -0
- package/dist/server/middleware/status.cjs +28 -0
- package/dist/server/middleware/token.cjs +66 -0
- package/dist/server/middleware/url-not-found.cjs +20 -0
- package/favicon.ico +0 -0
- package/package.json +121 -0
- package/templates/reset-form.ejs +3 -0
- package/templates/verify.ejs +9 -0
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//#region src/lib/connectors/mail-direct-transport.ts
|
|
3
|
+
var require_mail_direct_transport = /* @__PURE__ */ require("../../_virtual/_rolldown/runtime.cjs").__commonJSMin(((exports, module) => {
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const debug = require("debug")("loopback:connector:mail:direct");
|
|
6
|
+
const dns = require("dns");
|
|
7
|
+
const EventEmitter = require("events");
|
|
8
|
+
const net = require("net");
|
|
9
|
+
const os = require("os");
|
|
10
|
+
const SMTPConnection = require("nodemailer/lib/smtp-connection/index.js");
|
|
11
|
+
const packageData = require(path.join(__dirname, "..", "..", "..", "node_modules", "nodemailer", "package.json"));
|
|
12
|
+
function createDirectTransport(options) {
|
|
13
|
+
return new DirectTransport(options);
|
|
14
|
+
}
|
|
15
|
+
var MessageQueue = class {
|
|
16
|
+
_instantQueue;
|
|
17
|
+
_sortedQueue;
|
|
18
|
+
_shiftTimer;
|
|
19
|
+
_callbackQueue;
|
|
20
|
+
constructor() {
|
|
21
|
+
this._instantQueue = [];
|
|
22
|
+
this._sortedQueue = [];
|
|
23
|
+
this._shiftTimer = null;
|
|
24
|
+
this._callbackQueue = [];
|
|
25
|
+
}
|
|
26
|
+
get(callback) {
|
|
27
|
+
if (this._instantQueue.length) {
|
|
28
|
+
callback(this._instantQueue.pop());
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
this._callbackQueue.unshift(callback);
|
|
32
|
+
}
|
|
33
|
+
insert(data, delay) {
|
|
34
|
+
if (typeof delay !== "number") {
|
|
35
|
+
this._instantQueue.unshift(data);
|
|
36
|
+
this._processInsert();
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
const container = {
|
|
40
|
+
data,
|
|
41
|
+
available: Date.now() + delay
|
|
42
|
+
};
|
|
43
|
+
let insertedIndex = -1;
|
|
44
|
+
for (let index = 0; index < this._sortedQueue.length; index++) if (this._sortedQueue[index].available >= container.available) {
|
|
45
|
+
this._sortedQueue.splice(index, 0, container);
|
|
46
|
+
insertedIndex = index;
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
if (insertedIndex === -1) {
|
|
50
|
+
this._sortedQueue.push(container);
|
|
51
|
+
insertedIndex = 0;
|
|
52
|
+
}
|
|
53
|
+
if (insertedIndex === 0) this._updateShiftTimer();
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
_updateShiftTimer() {
|
|
57
|
+
clearTimeout(this._shiftTimer);
|
|
58
|
+
if (!this._sortedQueue.length) return;
|
|
59
|
+
const nextShift = this._sortedQueue[0].available;
|
|
60
|
+
if (nextShift <= Date.now()) {
|
|
61
|
+
this._shiftSorted();
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
this._shiftTimer = setTimeout(this._shiftSorted.bind(this), nextShift - Date.now() + 15);
|
|
65
|
+
if (this._shiftTimer && typeof this._shiftTimer.unref === "function") this._shiftTimer.unref();
|
|
66
|
+
}
|
|
67
|
+
_shiftSorted() {
|
|
68
|
+
if (!this._sortedQueue.length) return;
|
|
69
|
+
if (this._sortedQueue[0].available <= Date.now()) {
|
|
70
|
+
const container = this._sortedQueue.shift();
|
|
71
|
+
this.insert(container.data);
|
|
72
|
+
}
|
|
73
|
+
this._updateShiftTimer();
|
|
74
|
+
}
|
|
75
|
+
_processInsert() {
|
|
76
|
+
if (this._instantQueue.length && this._callbackQueue.length) this._callbackQueue.pop()(this._instantQueue.pop());
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
var DirectTransport = class extends EventEmitter {
|
|
80
|
+
options;
|
|
81
|
+
_queue;
|
|
82
|
+
_started;
|
|
83
|
+
_lastId;
|
|
84
|
+
name;
|
|
85
|
+
version;
|
|
86
|
+
constructor(options) {
|
|
87
|
+
super();
|
|
88
|
+
this.options = options || {};
|
|
89
|
+
this._queue = new MessageQueue();
|
|
90
|
+
this._started = false;
|
|
91
|
+
this._lastId = 0;
|
|
92
|
+
if (typeof this.options.getSocket === "function") this.getSocket = this.options.getSocket;
|
|
93
|
+
const connection = new SMTPConnection({});
|
|
94
|
+
this.name = "SMTP (direct)";
|
|
95
|
+
this.version = packageData.version + "[client:" + connection.version + "]";
|
|
96
|
+
}
|
|
97
|
+
get length() {
|
|
98
|
+
return this._queue._instantQueue.length + this._queue._sortedQueue.length;
|
|
99
|
+
}
|
|
100
|
+
getSocket(options, callback) {
|
|
101
|
+
callback(null, false);
|
|
102
|
+
}
|
|
103
|
+
send(mail, callback) {
|
|
104
|
+
const envelope = mail.message.getEnvelope();
|
|
105
|
+
const domainEnvelopes = {};
|
|
106
|
+
if (!envelope.from) {
|
|
107
|
+
callback(/* @__PURE__ */ new Error("\"From\" address missing"));
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
envelope.to = [].concat(envelope.to || []);
|
|
111
|
+
if (!envelope.to.length) {
|
|
112
|
+
callback("\"Recipients\" addresses missing");
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
this._clearStreams(mail, (err) => {
|
|
116
|
+
if (err) {
|
|
117
|
+
callback(err);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
this._formatMessage(mail.message);
|
|
121
|
+
envelope.to.forEach(function(recipient) {
|
|
122
|
+
recipient = (recipient || "").toString();
|
|
123
|
+
const domain = (recipient.split("@").pop() || "").toLowerCase().trim();
|
|
124
|
+
if (!domainEnvelopes[domain]) domainEnvelopes[domain] = {
|
|
125
|
+
from: envelope.from,
|
|
126
|
+
to: [recipient]
|
|
127
|
+
};
|
|
128
|
+
else if (domainEnvelopes[domain].to.indexOf(recipient) === -1) domainEnvelopes[domain].to.push(recipient);
|
|
129
|
+
});
|
|
130
|
+
let returned = 0;
|
|
131
|
+
const domains = Object.keys(domainEnvelopes);
|
|
132
|
+
const combinedInfo = {
|
|
133
|
+
accepted: [],
|
|
134
|
+
rejected: [],
|
|
135
|
+
pending: [],
|
|
136
|
+
errors: [],
|
|
137
|
+
envelope: mail.message.getEnvelope()
|
|
138
|
+
};
|
|
139
|
+
domains.forEach((domain) => {
|
|
140
|
+
let called = false;
|
|
141
|
+
const id = ++this._lastId;
|
|
142
|
+
const item = {
|
|
143
|
+
envelope: domainEnvelopes[domain],
|
|
144
|
+
data: mail.data,
|
|
145
|
+
message: mail.message,
|
|
146
|
+
domain,
|
|
147
|
+
id,
|
|
148
|
+
callback: (err, info) => {
|
|
149
|
+
if (called) {
|
|
150
|
+
debug("Callback for #%s already called. Updated values: %o", id, err || info);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
called = true;
|
|
154
|
+
returned++;
|
|
155
|
+
if (err) {
|
|
156
|
+
combinedInfo.errors.push(err);
|
|
157
|
+
if (err.recipients) combinedInfo.rejected = combinedInfo.rejected.concat(err.recipients || []);
|
|
158
|
+
} else if (info) {
|
|
159
|
+
combinedInfo.accepted = combinedInfo.accepted.concat(info.accepted || []);
|
|
160
|
+
combinedInfo.rejected = combinedInfo.rejected.concat(info.rejected || []);
|
|
161
|
+
combinedInfo.pending = combinedInfo.pending.concat(info.pending || []);
|
|
162
|
+
combinedInfo.messageId = info.messageId;
|
|
163
|
+
}
|
|
164
|
+
if (returned >= domains.length) if (combinedInfo.errors.length === domains.length) {
|
|
165
|
+
const sendError = /* @__PURE__ */ new Error("Sending failed");
|
|
166
|
+
sendError.errors = combinedInfo.errors;
|
|
167
|
+
callback(sendError);
|
|
168
|
+
} else callback(null, combinedInfo);
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
this._queue.insert(item);
|
|
172
|
+
});
|
|
173
|
+
if (!this._started) {
|
|
174
|
+
this._started = true;
|
|
175
|
+
setImmediate(this._loop.bind(this));
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
_loop() {
|
|
180
|
+
this._queue.get((data) => {
|
|
181
|
+
debug("Retrieved message #%s from the queue, resolving %s", data.id, data.domain);
|
|
182
|
+
this._resolveMx(data.domain, (err, list) => {
|
|
183
|
+
if (err || !list || !list.length) {
|
|
184
|
+
data.callback(err || /* @__PURE__ */ new Error("Could not resolve MX for " + data.domain));
|
|
185
|
+
setImmediate(this._loop.bind(this));
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
list.sort(function(a, b) {
|
|
189
|
+
return (a && a.priority || 0) - (b && b.priority || 0);
|
|
190
|
+
});
|
|
191
|
+
const exchanges = list.map(function(item) {
|
|
192
|
+
return item.exchange;
|
|
193
|
+
});
|
|
194
|
+
this._process([].concat(exchanges), data, (processErr, response) => {
|
|
195
|
+
if (processErr) if (processErr.responseCode && processErr.responseCode >= 500) {
|
|
196
|
+
processErr.domain = data.domain;
|
|
197
|
+
processErr.exchange = exchanges[0];
|
|
198
|
+
processErr.recipients = data.envelope.to;
|
|
199
|
+
data.callback(processErr);
|
|
200
|
+
} else {
|
|
201
|
+
data.replies = (data.replies || 0) + 1;
|
|
202
|
+
if (data.replies <= 5) {
|
|
203
|
+
this._queue.insert(data, this.options.retryDelay || data.replies * 15 * 60 * 1e3);
|
|
204
|
+
data.callback(null, { pending: {
|
|
205
|
+
domain: data.domain,
|
|
206
|
+
exchange: exchanges[0],
|
|
207
|
+
recipients: data.envelope.to,
|
|
208
|
+
response: processErr.response
|
|
209
|
+
} });
|
|
210
|
+
} else {
|
|
211
|
+
processErr.domain = data.domain;
|
|
212
|
+
processErr.exchange = exchanges[0];
|
|
213
|
+
processErr.recipients = data.envelope.to;
|
|
214
|
+
data.callback(processErr);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
else data.callback(null, response);
|
|
218
|
+
setImmediate(this._loop.bind(this));
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
_process(exchanges, data, callback) {
|
|
224
|
+
const options = {
|
|
225
|
+
host: exchanges[0],
|
|
226
|
+
port: this.options.port || 25,
|
|
227
|
+
requireTLS: !data.ignoreTLS,
|
|
228
|
+
ignoreTLS: !!data.ignoreTLS,
|
|
229
|
+
tls: { rejectUnauthorized: false }
|
|
230
|
+
};
|
|
231
|
+
Object.keys(this.options).forEach((key) => {
|
|
232
|
+
options[key] = this.options[key];
|
|
233
|
+
});
|
|
234
|
+
this.getSocket(options, (err, socketOptions) => {
|
|
235
|
+
if (err) {
|
|
236
|
+
exchanges.shift();
|
|
237
|
+
if (!exchanges.length) {
|
|
238
|
+
callback(err);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
this._process(exchanges, data, callback);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (socketOptions && socketOptions.connection) Object.keys(socketOptions).forEach(function(key) {
|
|
245
|
+
options[key] = socketOptions[key];
|
|
246
|
+
});
|
|
247
|
+
const connection = new SMTPConnection(options);
|
|
248
|
+
let returned = false;
|
|
249
|
+
let connected = false;
|
|
250
|
+
connection.once("error", (error) => {
|
|
251
|
+
if (returned) return;
|
|
252
|
+
returned = true;
|
|
253
|
+
if (error.code === "ETLS") {
|
|
254
|
+
data.ignoreTLS = true;
|
|
255
|
+
this._process(exchanges, data, callback);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
if (!connected) {
|
|
259
|
+
exchanges.shift();
|
|
260
|
+
if (!exchanges.length) {
|
|
261
|
+
callback(error);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
this._process(exchanges, data, callback);
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
callback(error);
|
|
268
|
+
});
|
|
269
|
+
const sendMessage = () => {
|
|
270
|
+
connection.send(data.envelope, data.message.createReadStream(), (sendErr, info) => {
|
|
271
|
+
if (returned) return;
|
|
272
|
+
returned = true;
|
|
273
|
+
connection.close();
|
|
274
|
+
if (sendErr) {
|
|
275
|
+
callback(sendErr);
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
info.messageId = (data.message.getHeader("message-id") || "").replace(/[<>\s]/g, "");
|
|
279
|
+
callback(null, info);
|
|
280
|
+
});
|
|
281
|
+
};
|
|
282
|
+
connection.connect(() => {
|
|
283
|
+
connected = true;
|
|
284
|
+
if (returned) return;
|
|
285
|
+
sendMessage();
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
_formatMessage(message) {
|
|
290
|
+
const hostname = this._resolveHostname(this.options.name);
|
|
291
|
+
message._headers.unshift({
|
|
292
|
+
key: "Received",
|
|
293
|
+
value: "from localhost (127.0.0.1) by " + hostname + " with SMTP; " + Date()
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
_clearStreams(mail, callback) {
|
|
297
|
+
const streamNodes = [];
|
|
298
|
+
function walkNode(node) {
|
|
299
|
+
if (node.content && typeof node.content.pipe === "function") streamNodes.push(node);
|
|
300
|
+
if (node.childNodes && node.childNodes.length) node.childNodes.forEach(walkNode);
|
|
301
|
+
}
|
|
302
|
+
walkNode(mail.message);
|
|
303
|
+
const resolveNodes = () => {
|
|
304
|
+
if (!streamNodes.length) {
|
|
305
|
+
callback();
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
const node = streamNodes.shift();
|
|
309
|
+
mail.resolveContent(node, "content", (err) => {
|
|
310
|
+
if (err) {
|
|
311
|
+
callback(err);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
setImmediate(resolveNodes);
|
|
315
|
+
});
|
|
316
|
+
};
|
|
317
|
+
resolveNodes();
|
|
318
|
+
}
|
|
319
|
+
_resolveMx(domain, callback) {
|
|
320
|
+
domain = domain.replace(/^\[(ipv6:)?|\]$/gi, "");
|
|
321
|
+
if (net.isIP(domain)) {
|
|
322
|
+
callback(null, [{
|
|
323
|
+
priority: 0,
|
|
324
|
+
exchange: domain
|
|
325
|
+
}]);
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
dns.resolveMx(domain, function(err, list) {
|
|
329
|
+
if (err) {
|
|
330
|
+
if (err.code === "ENODATA" || err.code === "ENOTFOUND") {
|
|
331
|
+
dns.resolve4(domain, function(resolve4Err, ipv4List) {
|
|
332
|
+
if (resolve4Err) {
|
|
333
|
+
if (resolve4Err.code === "ENODATA" || resolve4Err.code === "ENOTFOUND") {
|
|
334
|
+
dns.resolve6(domain, function(resolve6Err, ipv6List) {
|
|
335
|
+
if (resolve6Err) {
|
|
336
|
+
callback(resolve6Err);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
callback(null, [].concat(ipv6List || []).map(function(entry) {
|
|
340
|
+
return {
|
|
341
|
+
priority: 0,
|
|
342
|
+
exchange: entry
|
|
343
|
+
};
|
|
344
|
+
}).slice(0, 1));
|
|
345
|
+
});
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
callback(resolve4Err);
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
callback(null, [].concat(ipv4List || []).map(function(entry) {
|
|
352
|
+
return {
|
|
353
|
+
priority: 0,
|
|
354
|
+
exchange: entry
|
|
355
|
+
};
|
|
356
|
+
}).slice(0, 1));
|
|
357
|
+
});
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
callback(err);
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
callback(null, list);
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
_resolveHostname(name) {
|
|
367
|
+
if (!name || net.isIP(name.replace(/[\[\]]/g, "").trim())) name = os.hostname && os.hostname() || "";
|
|
368
|
+
if (!name || net.isIP(name.replace(/[\[\]]/g, "").trim())) name = "localhost";
|
|
369
|
+
return name.toLowerCase();
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
module.exports = createDirectTransport;
|
|
373
|
+
}));
|
|
374
|
+
//#endregion
|
|
375
|
+
module.exports = require_mail_direct_transport();
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//#region src/lib/connectors/mail-stub-transport.ts
|
|
3
|
+
var require_mail_stub_transport = /* @__PURE__ */ require("../../_virtual/_rolldown/runtime.cjs").__commonJSMin(((exports, module) => {
|
|
4
|
+
const EventEmitter = require("events");
|
|
5
|
+
const util = require("util");
|
|
6
|
+
const packageData = require("nodemailer/package.json");
|
|
7
|
+
function createStubTransport(options) {
|
|
8
|
+
return new StubTransport(options);
|
|
9
|
+
}
|
|
10
|
+
var StubTransport = class extends EventEmitter {
|
|
11
|
+
options;
|
|
12
|
+
name;
|
|
13
|
+
version;
|
|
14
|
+
constructor(options) {
|
|
15
|
+
super();
|
|
16
|
+
this.options = options || {};
|
|
17
|
+
this.name = "Stub";
|
|
18
|
+
this.version = packageData.version;
|
|
19
|
+
}
|
|
20
|
+
isIdle() {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
verify(callback) {
|
|
24
|
+
setImmediate(() => {
|
|
25
|
+
if (this.options.error) return callback(asError(this.options.error));
|
|
26
|
+
return callback(null, true);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
send(mail, callback) {
|
|
30
|
+
if (this.options.error) {
|
|
31
|
+
setImmediate(() => {
|
|
32
|
+
callback(asError(this.options.error));
|
|
33
|
+
});
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (this.options.keepBcc) mail.message.keepBcc = true;
|
|
37
|
+
const message = mail.message.createReadStream();
|
|
38
|
+
const chunks = [];
|
|
39
|
+
let chunkLength = 0;
|
|
40
|
+
const envelope = mail.data.envelope || mail.message.getEnvelope();
|
|
41
|
+
this._log("info", "envelope", JSON.stringify(envelope));
|
|
42
|
+
this.emit("envelope", envelope);
|
|
43
|
+
message.on("error", (err) => {
|
|
44
|
+
setImmediate(() => {
|
|
45
|
+
callback(err);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
message.on("data", (chunk) => {
|
|
49
|
+
chunks.push(chunk);
|
|
50
|
+
chunkLength += chunk.length;
|
|
51
|
+
this._log("verbose", "message", chunk.toString());
|
|
52
|
+
this.emit("data", chunk.toString());
|
|
53
|
+
});
|
|
54
|
+
message.on("end", () => {
|
|
55
|
+
setImmediate(() => {
|
|
56
|
+
const messageId = String(mail.message.getHeader("message-id") || "").replace(/[<>\s]/g, "");
|
|
57
|
+
const response = Buffer.concat(chunks, chunkLength);
|
|
58
|
+
const info = {
|
|
59
|
+
envelope: mail.data.envelope || mail.message.getEnvelope(),
|
|
60
|
+
messageId,
|
|
61
|
+
response
|
|
62
|
+
};
|
|
63
|
+
this._log("info", "end", "Processed <%s> (%sB)", messageId, response.length);
|
|
64
|
+
this.emit("end", info);
|
|
65
|
+
callback(null, info);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
_log(level, type, ...args) {
|
|
70
|
+
const message = util.format.apply(util, args);
|
|
71
|
+
this.emit("log", {
|
|
72
|
+
name: "loopback-stub-transport",
|
|
73
|
+
version: this.version,
|
|
74
|
+
level: (level || "info").toUpperCase(),
|
|
75
|
+
type: type || "",
|
|
76
|
+
message
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
function asError(error) {
|
|
81
|
+
return error instanceof Error ? error : new Error(error);
|
|
82
|
+
}
|
|
83
|
+
module.exports = createStubTransport;
|
|
84
|
+
}));
|
|
85
|
+
//#endregion
|
|
86
|
+
module.exports = require_mail_stub_transport();
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const require_runtime$1 = require("../../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_lib_globalize = require("../globalize.cjs");
|
|
4
|
+
const require_lib_runtime = require("../runtime.cjs");
|
|
5
|
+
const require_lib_connectors_mail_direct_transport = require("./mail-direct-transport.cjs");
|
|
6
|
+
const require_lib_connectors_mail_stub_transport = require("./mail-stub-transport.cjs");
|
|
7
|
+
//#region src/lib/connectors/mail.ts
|
|
8
|
+
/**
|
|
9
|
+
* Dependencies.
|
|
10
|
+
*/
|
|
11
|
+
var require_mail = /* @__PURE__ */ require_runtime$1.__commonJSMin(((exports, module) => {
|
|
12
|
+
const g = require_lib_globalize;
|
|
13
|
+
const mailer = require("nodemailer");
|
|
14
|
+
const createDirectTransport = require_lib_connectors_mail_direct_transport;
|
|
15
|
+
const createStubTransport = require_lib_connectors_mail_stub_transport;
|
|
16
|
+
const assert = require("assert");
|
|
17
|
+
const debug = require("debug")("loopback:connector:mail");
|
|
18
|
+
const runtime = require_lib_runtime;
|
|
19
|
+
function MailConnector(settings) {
|
|
20
|
+
assert(typeof settings === "object", "cannot initialize MailConnector without a settings object");
|
|
21
|
+
let transports = settings.transports;
|
|
22
|
+
if (!transports && settings.transport) transports = [settings.transport];
|
|
23
|
+
if (!transports) transports = [];
|
|
24
|
+
this.transportsIndex = {};
|
|
25
|
+
this.transports = [];
|
|
26
|
+
if (runtime.isServer) transports.forEach(this.setupTransport.bind(this));
|
|
27
|
+
}
|
|
28
|
+
MailConnector.initialize = function(dataSource, callback) {
|
|
29
|
+
dataSource.connector = new MailConnector(dataSource.settings);
|
|
30
|
+
callback();
|
|
31
|
+
};
|
|
32
|
+
MailConnector.prototype.DataAccessObject = Mailer;
|
|
33
|
+
MailConnector.prototype.setupTransport = function(setting) {
|
|
34
|
+
const connector = this;
|
|
35
|
+
connector.transports = connector.transports || [];
|
|
36
|
+
connector.transportsIndex = connector.transportsIndex || {};
|
|
37
|
+
let transport;
|
|
38
|
+
const transportType = (setting.type || "STUB").toLowerCase();
|
|
39
|
+
if (transportType === "smtp") transport = mailer.createTransport(setting);
|
|
40
|
+
else if (transportType === "direct") transport = mailer.createTransport(createDirectTransport(setting));
|
|
41
|
+
else if (transportType === "stub") transport = mailer.createTransport(createStubTransport(setting));
|
|
42
|
+
else if (transportType === "ses" && supportsBuiltinSesTransport(setting)) transport = mailer.createTransport(createBuiltinSesTransportConfig(setting));
|
|
43
|
+
else {
|
|
44
|
+
const transportModuleName = "nodemailer-" + transportType + "-transport";
|
|
45
|
+
const transportModule = require(transportModuleName);
|
|
46
|
+
transport = mailer.createTransport(transportModule(setting));
|
|
47
|
+
}
|
|
48
|
+
connector.transportsIndex[setting.alias || setting.type] = transport;
|
|
49
|
+
connector.transports.push(transport);
|
|
50
|
+
};
|
|
51
|
+
function supportsBuiltinSesTransport(setting) {
|
|
52
|
+
return !!(setting.SES || setting.sesClient && setting.SendEmailCommand || hasLegacySesCredentials(setting));
|
|
53
|
+
}
|
|
54
|
+
function createBuiltinSesTransportConfig(setting) {
|
|
55
|
+
const transportConfig = Object.assign({}, setting);
|
|
56
|
+
delete transportConfig.alias;
|
|
57
|
+
delete transportConfig.type;
|
|
58
|
+
if (!transportConfig.SES) transportConfig.SES = createSesTransportOptions(transportConfig);
|
|
59
|
+
delete transportConfig.sesClient;
|
|
60
|
+
delete transportConfig.SendEmailCommand;
|
|
61
|
+
delete transportConfig.accessKeyId;
|
|
62
|
+
delete transportConfig.secretAccessKey;
|
|
63
|
+
delete transportConfig.sessionToken;
|
|
64
|
+
delete transportConfig.region;
|
|
65
|
+
return transportConfig;
|
|
66
|
+
}
|
|
67
|
+
function hasLegacySesCredentials(setting) {
|
|
68
|
+
return !!(setting && setting.accessKeyId && setting.secretAccessKey && setting.region);
|
|
69
|
+
}
|
|
70
|
+
function createSesTransportOptions(setting) {
|
|
71
|
+
if (setting.sesClient && setting.SendEmailCommand) return {
|
|
72
|
+
sesClient: setting.sesClient,
|
|
73
|
+
SendEmailCommand: setting.SendEmailCommand
|
|
74
|
+
};
|
|
75
|
+
if (!hasLegacySesCredentials(setting)) return setting.SES;
|
|
76
|
+
const ses = require("@aws-sdk/client-sesv2");
|
|
77
|
+
const clientConfig = { region: setting.region };
|
|
78
|
+
clientConfig.credentials = {
|
|
79
|
+
accessKeyId: setting.accessKeyId,
|
|
80
|
+
secretAccessKey: setting.secretAccessKey
|
|
81
|
+
};
|
|
82
|
+
if (setting.sessionToken) clientConfig.credentials.sessionToken = setting.sessionToken;
|
|
83
|
+
return {
|
|
84
|
+
sesClient: new ses.SESv2Client(clientConfig),
|
|
85
|
+
SendEmailCommand: ses.SendEmailCommand
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function Mailer() {}
|
|
89
|
+
MailConnector.prototype.transportForName = function(name) {
|
|
90
|
+
return this.transportsIndex[name];
|
|
91
|
+
};
|
|
92
|
+
MailConnector.prototype.defaultTransport = function() {
|
|
93
|
+
return this.transports[0] || this.stubTransport;
|
|
94
|
+
};
|
|
95
|
+
Mailer.send = function(options, fn) {
|
|
96
|
+
const dataSource = this.dataSource;
|
|
97
|
+
const settings = dataSource && dataSource.settings;
|
|
98
|
+
const connector = dataSource.connector;
|
|
99
|
+
assert(connector, "Cannot send mail without a connector!");
|
|
100
|
+
let transport = connector.transportForName(options.transport);
|
|
101
|
+
if (!transport) transport = connector.defaultTransport();
|
|
102
|
+
if (debug.enabled || settings && settings.debug) {
|
|
103
|
+
g.log("Sending Mail:");
|
|
104
|
+
if (options.transport) console.log(g.f(" TRANSPORT:%s", options.transport));
|
|
105
|
+
g.log(" TO:%s", options.to);
|
|
106
|
+
g.log(" FROM:%s", options.from);
|
|
107
|
+
g.log(" SUBJECT:%s", options.subject);
|
|
108
|
+
g.log(" TEXT:%s", options.text);
|
|
109
|
+
g.log(" HTML:%s", options.html);
|
|
110
|
+
}
|
|
111
|
+
if (transport) {
|
|
112
|
+
assert(transport.sendMail, "You must supply an Email.settings.transports containing a valid transport");
|
|
113
|
+
transport.sendMail(options, fn);
|
|
114
|
+
} else {
|
|
115
|
+
g.warn("Warning: No email transport specified for sending email. Setup a transport to send mail messages.");
|
|
116
|
+
process.nextTick(function() {
|
|
117
|
+
fn(null, options);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
Mailer.prototype.send = function(fn) {
|
|
122
|
+
this.constructor.send(this, fn);
|
|
123
|
+
};
|
|
124
|
+
MailConnector.mailer = MailConnector.prototype.mailer = Mailer.mailer = Mailer.prototype.mailer = mailer;
|
|
125
|
+
module.exports = MailConnector;
|
|
126
|
+
}));
|
|
127
|
+
//#endregion
|
|
128
|
+
module.exports = require_mail();
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const require_runtime = require("../../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_lib_connectors_base_connector = require("./base-connector.cjs");
|
|
4
|
+
//#region src/lib/connectors/memory.ts
|
|
5
|
+
/**
|
|
6
|
+
* Expose `Memory`.
|
|
7
|
+
*/
|
|
8
|
+
var require_memory = /* @__PURE__ */ require_runtime.__commonJSMin(((exports, module) => {
|
|
9
|
+
require("debug")("memory");
|
|
10
|
+
const inherits = require("util").inherits;
|
|
11
|
+
const JdbMemory = require("@vsaas/loopback-datasource-juggler/connectors/memory");
|
|
12
|
+
const Connector = require_lib_connectors_base_connector;
|
|
13
|
+
function Memory() {}
|
|
14
|
+
inherits(Memory, Connector);
|
|
15
|
+
Memory.initialize = JdbMemory.initialize;
|
|
16
|
+
module.exports = Memory;
|
|
17
|
+
}));
|
|
18
|
+
//#endregion
|
|
19
|
+
module.exports = require_memory();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
const require_lib_globalize = require("./globalize.cjs");
|
|
3
|
+
//#region src/lib/current-context.ts
|
|
4
|
+
var require_current_context = /* @__PURE__ */ require_runtime.__commonJSMin(((exports, module) => {
|
|
5
|
+
const g = require_lib_globalize;
|
|
6
|
+
const juggler = require("@vsaas/loopback-datasource-juggler");
|
|
7
|
+
const remoting = require("@vsaas/remoting");
|
|
8
|
+
function currentContext(loopback) {
|
|
9
|
+
juggler.getCurrentContext = remoting.getCurrentContext = loopback.getCurrentContext = function() {
|
|
10
|
+
throw new Error(g.f("%s was removed in version 3.0. See %s for more details.", "loopback.getCurrentContext()", "http://loopback.io/doc/en/lb2/Using-current-context.html"));
|
|
11
|
+
};
|
|
12
|
+
loopback.runInContext = function(fn) {
|
|
13
|
+
throw new Error(g.f("%s was removed in version 3.0. See %s for more details.", "loopback.runInContext()", "http://loopback.io/doc/en/lb2/Using-current-context.html"));
|
|
14
|
+
};
|
|
15
|
+
loopback.createContext = function(scopeName) {
|
|
16
|
+
throw new Error(g.f("%s was removed in version 3.0. See %s for more details.", "loopback.createContext()", "http://loopback.io/doc/en/lb2/Using-current-context.html"));
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
module.exports = currentContext;
|
|
20
|
+
}));
|
|
21
|
+
//#endregion
|
|
22
|
+
module.exports = require_current_context();
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region src/lib/globalize.ts
|
|
2
|
+
var require_globalize = /* @__PURE__ */ require("../_virtual/_rolldown/runtime.cjs").__commonJSMin(((exports, module) => {
|
|
3
|
+
const format = require("util").format;
|
|
4
|
+
function f(message) {
|
|
5
|
+
const args = Array.prototype.slice.call(arguments, 1);
|
|
6
|
+
return format.apply(null, [normalizeMessage(message)].concat(args));
|
|
7
|
+
}
|
|
8
|
+
function log(message) {
|
|
9
|
+
console.log(formatWithArgs.apply(null, arguments));
|
|
10
|
+
}
|
|
11
|
+
function warn(message) {
|
|
12
|
+
console.warn(formatWithArgs.apply(null, arguments));
|
|
13
|
+
}
|
|
14
|
+
function formatWithArgs(message) {
|
|
15
|
+
const args = Array.prototype.slice.call(arguments, 1);
|
|
16
|
+
return format.apply(null, [normalizeMessage(message)].concat(args));
|
|
17
|
+
}
|
|
18
|
+
function normalizeMessage(message) {
|
|
19
|
+
if (typeof message !== "string") return message;
|
|
20
|
+
return message.replace(/\{\{([^{}]+)\}\}/g, "$1");
|
|
21
|
+
}
|
|
22
|
+
module.exports = {
|
|
23
|
+
f,
|
|
24
|
+
log,
|
|
25
|
+
warn
|
|
26
|
+
};
|
|
27
|
+
}));
|
|
28
|
+
//#endregion
|
|
29
|
+
module.exports = require_globalize();
|