@momentumcms/auth 0.4.1 → 0.5.1
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/CHANGELOG.md +8 -0
- package/index.cjs +1309 -116
- package/index.js +1313 -114
- package/package.json +9 -1
- package/src/lib/auth.d.ts +7 -4
- package/src/lib/email-components/password-reset-email.component.d.ts +11 -0
- package/src/lib/email-components/verification-email.component.d.ts +11 -0
- package/src/lib/email-templates.d.ts +28 -8
- package/src/lib/plugins/admin.d.ts +3 -6
- package/src/lib/plugins/organization.d.ts +3 -6
package/index.cjs
CHANGED
|
@@ -5,6 +5,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __esm = (fn, res) => function __init() {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
};
|
|
8
11
|
var __export = (target, all) => {
|
|
9
12
|
for (var name in all)
|
|
10
13
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -26,10 +29,1238 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
29
|
mod
|
|
27
30
|
));
|
|
28
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
33
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
34
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
35
|
+
if (decorator = decorators[i])
|
|
36
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
37
|
+
if (kind && result)
|
|
38
|
+
__defProp(target, key, result);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
29
41
|
|
|
30
|
-
// libs/
|
|
42
|
+
// libs/email/src/lib/utils/css-inliner.ts
|
|
43
|
+
function inlineCss(html) {
|
|
44
|
+
return (0, import_juice.default)(html, {
|
|
45
|
+
removeStyleTags: true,
|
|
46
|
+
preserveMediaQueries: true,
|
|
47
|
+
preserveFontFaces: true,
|
|
48
|
+
insertPreservedExtraCss: true
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
var import_juice;
|
|
52
|
+
var init_css_inliner = __esm({
|
|
53
|
+
"libs/email/src/lib/utils/css-inliner.ts"() {
|
|
54
|
+
"use strict";
|
|
55
|
+
import_juice = __toESM(require("juice"));
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// libs/email/src/lib/utils/strip-artifacts.ts
|
|
60
|
+
function stripAngularArtifacts(html) {
|
|
61
|
+
return html.replace(/<!--[\s\S]*?-->/g, "").replace(/\s*ng-reflect-[\w-]+="[^"]*"/g, "").replace(/\s*_ng(?:host|content)-[\w-]+(?:="")?/g, "").replace(/\s*ng-version="[^"]*"/g, "").replace(/\s*ng-server-context="[^"]*"/g, "").replace(/\s*ngh="[^"]*"/g, "").replace(/\n\s*\n/g, "\n");
|
|
62
|
+
}
|
|
63
|
+
var init_strip_artifacts = __esm({
|
|
64
|
+
"libs/email/src/lib/utils/strip-artifacts.ts"() {
|
|
65
|
+
"use strict";
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// libs/email/src/lib/render/render-types.ts
|
|
70
|
+
function injectEmailData() {
|
|
71
|
+
return (0, import_core.inject)(EMAIL_DATA);
|
|
72
|
+
}
|
|
73
|
+
var import_core, EMAIL_DATA;
|
|
74
|
+
var init_render_types = __esm({
|
|
75
|
+
"libs/email/src/lib/render/render-types.ts"() {
|
|
76
|
+
"use strict";
|
|
77
|
+
import_core = require("@angular/core");
|
|
78
|
+
EMAIL_DATA = new import_core.InjectionToken("EMAIL_DATA");
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// libs/email/src/lib/render/render-email.ts
|
|
83
|
+
function buildDocument(selector) {
|
|
84
|
+
return `<!DOCTYPE html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"></head><body><${selector}></${selector}></body></html>`;
|
|
85
|
+
}
|
|
86
|
+
async function renderEmail(component, data, options) {
|
|
87
|
+
const shouldInlineCss = options?.inlineCss ?? true;
|
|
88
|
+
const shouldStripArtifacts = options?.stripArtifacts ?? true;
|
|
89
|
+
const extraProviders = options?.providers ?? [];
|
|
90
|
+
const mirror = (0, import_core2.reflectComponentType)(component);
|
|
91
|
+
if (!mirror) {
|
|
92
|
+
throw new Error(
|
|
93
|
+
`Cannot reflect component type: ${component.name}. Ensure it has a @Component decorator.`
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
const providers = [...extraProviders, { provide: EMAIL_DATA, useValue: data ?? {} }];
|
|
97
|
+
let html = await (0, import_platform_server.renderApplication)(
|
|
98
|
+
(context) => (0, import_platform_browser.bootstrapApplication)(component, { providers }, context),
|
|
99
|
+
{
|
|
100
|
+
document: buildDocument(mirror.selector),
|
|
101
|
+
url: "/"
|
|
102
|
+
}
|
|
103
|
+
);
|
|
104
|
+
if (shouldStripArtifacts) {
|
|
105
|
+
html = stripAngularArtifacts(html);
|
|
106
|
+
}
|
|
107
|
+
if (shouldInlineCss) {
|
|
108
|
+
html = inlineCss(html);
|
|
109
|
+
}
|
|
110
|
+
return html;
|
|
111
|
+
}
|
|
112
|
+
var import_compiler, import_core2, import_platform_server, import_platform_browser;
|
|
113
|
+
var init_render_email = __esm({
|
|
114
|
+
"libs/email/src/lib/render/render-email.ts"() {
|
|
115
|
+
"use strict";
|
|
116
|
+
import_compiler = require("@angular/compiler");
|
|
117
|
+
import_core2 = require("@angular/core");
|
|
118
|
+
import_platform_server = require("@angular/platform-server");
|
|
119
|
+
import_platform_browser = require("@angular/platform-browser");
|
|
120
|
+
init_css_inliner();
|
|
121
|
+
init_strip_artifacts();
|
|
122
|
+
init_render_types();
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
// libs/email/src/lib/utils/escape-html.ts
|
|
127
|
+
function escapeHtml(unsafe) {
|
|
128
|
+
return unsafe.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
129
|
+
}
|
|
130
|
+
var init_escape_html = __esm({
|
|
131
|
+
"libs/email/src/lib/utils/escape-html.ts"() {
|
|
132
|
+
"use strict";
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// libs/email/src/lib/utils/replace-variables.ts
|
|
137
|
+
function replaceVariables(text2, variables) {
|
|
138
|
+
return text2.replace(/\{\{(\w+)\}\}/g, (_, key) => variables[key] ?? "");
|
|
139
|
+
}
|
|
140
|
+
function replaceBlockVariables(blocks2, variables) {
|
|
141
|
+
return blocks2.map((block) => ({
|
|
142
|
+
...block,
|
|
143
|
+
data: replaceDataVariables(block.data, variables)
|
|
144
|
+
}));
|
|
145
|
+
}
|
|
146
|
+
function replaceDataVariables(data, variables) {
|
|
147
|
+
const result = {};
|
|
148
|
+
for (const [key, value] of Object.entries(data)) {
|
|
149
|
+
if (typeof value === "string") {
|
|
150
|
+
result[key] = replaceVariables(value, variables);
|
|
151
|
+
} else if (Array.isArray(value)) {
|
|
152
|
+
result[key] = value.map((item) => {
|
|
153
|
+
if (typeof item === "object" && item !== null && "blocks" in item) {
|
|
154
|
+
const col = item;
|
|
155
|
+
const nestedBlocks = Array.isArray(col["blocks"]) ? col["blocks"] : [];
|
|
156
|
+
return { ...col, blocks: replaceBlockVariables(nestedBlocks, variables) };
|
|
157
|
+
}
|
|
158
|
+
return item;
|
|
159
|
+
});
|
|
160
|
+
} else {
|
|
161
|
+
result[key] = value;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
var init_replace_variables = __esm({
|
|
167
|
+
"libs/email/src/lib/utils/replace-variables.ts"() {
|
|
168
|
+
"use strict";
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// libs/email/src/lib/utils/sanitize.ts
|
|
173
|
+
function sanitizeAlignment(value) {
|
|
174
|
+
return VALID_ALIGNMENTS.has(value) ? value : "left";
|
|
175
|
+
}
|
|
176
|
+
function sanitizeCssValue(value) {
|
|
177
|
+
return value.replace(/[;{}()"'<>\\]/g, "");
|
|
178
|
+
}
|
|
179
|
+
function sanitizeFontFamily(value) {
|
|
180
|
+
return value.replace(/[;{}()"<>\\]/g, "");
|
|
181
|
+
}
|
|
182
|
+
function sanitizeCssNumber(value, fallback) {
|
|
183
|
+
if (value === null || value === void 0)
|
|
184
|
+
return String(fallback);
|
|
185
|
+
const num = Number(value);
|
|
186
|
+
return Number.isFinite(num) && num >= 0 ? String(num) : String(fallback);
|
|
187
|
+
}
|
|
188
|
+
function sanitizeUrl(url) {
|
|
189
|
+
const trimmed = url.trim();
|
|
190
|
+
if (!trimmed || trimmed === "#")
|
|
191
|
+
return trimmed || "#";
|
|
192
|
+
try {
|
|
193
|
+
const parsed = new URL(trimmed);
|
|
194
|
+
return SAFE_URL_PROTOCOLS.has(parsed.protocol) ? trimmed : "#";
|
|
195
|
+
} catch {
|
|
196
|
+
if (trimmed.startsWith("/") || trimmed.startsWith("#"))
|
|
197
|
+
return trimmed;
|
|
198
|
+
return "#";
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
var VALID_ALIGNMENTS, SAFE_URL_PROTOCOLS;
|
|
202
|
+
var init_sanitize = __esm({
|
|
203
|
+
"libs/email/src/lib/utils/sanitize.ts"() {
|
|
204
|
+
"use strict";
|
|
205
|
+
VALID_ALIGNMENTS = /* @__PURE__ */ new Set(["left", "center", "right"]);
|
|
206
|
+
SAFE_URL_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:", "mailto:"]);
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
// libs/email/src/types.ts
|
|
211
|
+
var DEFAULT_EMAIL_THEME;
|
|
212
|
+
var init_types = __esm({
|
|
213
|
+
"libs/email/src/types.ts"() {
|
|
214
|
+
"use strict";
|
|
215
|
+
DEFAULT_EMAIL_THEME = {
|
|
216
|
+
primaryColor: "#18181b",
|
|
217
|
+
backgroundColor: "#f4f4f5",
|
|
218
|
+
textColor: "#3f3f46",
|
|
219
|
+
mutedColor: "#71717a",
|
|
220
|
+
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif",
|
|
221
|
+
borderRadius: "8px"
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// libs/email/src/lib/render/render-blocks.ts
|
|
227
|
+
function renderEmailFromBlocks(template, options) {
|
|
228
|
+
const theme = { ...DEFAULT_EMAIL_THEME, ...template.theme };
|
|
229
|
+
const shouldInline = options?.inlineCss ?? true;
|
|
230
|
+
const blocks2 = options?.variables ? replaceBlockVariables(template.blocks, options.variables) : template.blocks;
|
|
231
|
+
const validBlocks = blocks2.filter((block) => {
|
|
232
|
+
if (!isValidBlock(block)) {
|
|
233
|
+
console.warn("[momentum:email] Skipping invalid email block:", block);
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
return true;
|
|
237
|
+
});
|
|
238
|
+
const blocksHtml = validBlocks.map((block) => renderBlock(block, theme, 0)).join("\n");
|
|
239
|
+
let html = wrapEmailDocument(blocksHtml, theme);
|
|
240
|
+
if (shouldInline) {
|
|
241
|
+
html = inlineCss(html);
|
|
242
|
+
}
|
|
243
|
+
return html;
|
|
244
|
+
}
|
|
245
|
+
function wrapEmailDocument(content, theme) {
|
|
246
|
+
const fontFamily = sanitizeFontFamily(theme.fontFamily);
|
|
247
|
+
const bgColor = sanitizeCssValue(theme.backgroundColor);
|
|
248
|
+
const borderRadius = sanitizeCssValue(theme.borderRadius);
|
|
249
|
+
return `<!DOCTYPE html>
|
|
250
|
+
<html lang="en">
|
|
251
|
+
<head>
|
|
252
|
+
<meta charset="UTF-8">
|
|
253
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
254
|
+
</head>
|
|
255
|
+
<body style="margin: 0; padding: 0; font-family: ${fontFamily}; background-color: ${bgColor}; line-height: 1.6;">
|
|
256
|
+
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="background-color: ${bgColor};">
|
|
257
|
+
<tr>
|
|
258
|
+
<td style="padding: 40px 20px;">
|
|
259
|
+
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="max-width: 480px; margin: 0 auto; background-color: #ffffff; border-radius: ${borderRadius}; box-shadow: 0 1px 3px rgba(0,0,0,0.1);">
|
|
260
|
+
<tr>
|
|
261
|
+
<td style="padding: 40px;">
|
|
262
|
+
${content}
|
|
263
|
+
</td>
|
|
264
|
+
</tr>
|
|
265
|
+
</table>
|
|
266
|
+
</td>
|
|
267
|
+
</tr>
|
|
268
|
+
</table>
|
|
269
|
+
</body>
|
|
270
|
+
</html>`;
|
|
271
|
+
}
|
|
272
|
+
function isValidBlock(block) {
|
|
273
|
+
const rec = block;
|
|
274
|
+
return typeof block === "object" && block !== null && typeof rec["id"] === "string" && rec["id"].length > 0 && typeof rec["type"] === "string" && typeof rec["data"] === "object" && rec["data"] !== null;
|
|
275
|
+
}
|
|
276
|
+
function renderBlock(block, theme, depth) {
|
|
277
|
+
switch (block.type) {
|
|
278
|
+
case "header":
|
|
279
|
+
return renderHeaderBlock(block.data, theme);
|
|
280
|
+
case "text":
|
|
281
|
+
return renderTextBlock(block.data, theme);
|
|
282
|
+
case "button":
|
|
283
|
+
return renderButtonBlock(block.data, theme);
|
|
284
|
+
case "image":
|
|
285
|
+
return renderImageBlock(block.data);
|
|
286
|
+
case "divider":
|
|
287
|
+
return renderDividerBlock(block.data);
|
|
288
|
+
case "spacer":
|
|
289
|
+
return renderSpacerBlock(block.data);
|
|
290
|
+
case "columns":
|
|
291
|
+
if (depth >= MAX_BLOCK_DEPTH) {
|
|
292
|
+
console.warn("[momentum:email] Max nesting depth reached, skipping columns block");
|
|
293
|
+
return "";
|
|
294
|
+
}
|
|
295
|
+
return renderColumnsBlock(block.data, theme, depth);
|
|
296
|
+
case "footer":
|
|
297
|
+
return renderFooterBlock(block.data, theme);
|
|
298
|
+
default:
|
|
299
|
+
return `<!-- unknown block type: ${escapeHtml(block.type)} -->`;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
function renderHeaderBlock(data, theme) {
|
|
303
|
+
const title = escapeHtml(String(data["title"] ?? ""));
|
|
304
|
+
const subtitle = data["subtitle"] ? escapeHtml(String(data["subtitle"])) : "";
|
|
305
|
+
const alignment = sanitizeAlignment(String(data["alignment"] ?? "left"));
|
|
306
|
+
return `<h1 style="margin: 0 0 8px; font-size: 24px; font-weight: 600; color: ${sanitizeCssValue(theme.textColor)}; text-align: ${alignment};">${title}</h1>${subtitle ? `<p style="margin: 0 0 16px; font-size: 16px; color: ${sanitizeCssValue(theme.mutedColor)}; text-align: ${alignment};">${subtitle}</p>` : ""}`;
|
|
307
|
+
}
|
|
308
|
+
function renderTextBlock(data, theme) {
|
|
309
|
+
const content = escapeHtml(String(data["content"] ?? ""));
|
|
310
|
+
const fontSize = sanitizeCssNumber(data["fontSize"], 16);
|
|
311
|
+
const color = sanitizeCssValue(String(data["color"] ?? theme.textColor));
|
|
312
|
+
const alignment = sanitizeAlignment(String(data["alignment"] ?? "left"));
|
|
313
|
+
return `<p style="margin: 0 0 16px; font-size: ${fontSize}px; color: ${color}; text-align: ${alignment}; line-height: 1.6;">${content}</p>`;
|
|
314
|
+
}
|
|
315
|
+
function renderButtonBlock(data, theme) {
|
|
316
|
+
const label = escapeHtml(String(data["label"] ?? "Click here"));
|
|
317
|
+
const href = escapeHtml(sanitizeUrl(String(data["href"] ?? "#")));
|
|
318
|
+
const bgColor = sanitizeCssValue(String(data["backgroundColor"] ?? theme.primaryColor));
|
|
319
|
+
const color = sanitizeCssValue(String(data["color"] ?? "#ffffff"));
|
|
320
|
+
const alignment = sanitizeAlignment(String(data["alignment"] ?? "left"));
|
|
321
|
+
return `<table role="presentation" width="100%" cellspacing="0" cellpadding="0">
|
|
322
|
+
<tr>
|
|
323
|
+
<td style="padding: 0 0 16px;" align="${alignment}">
|
|
324
|
+
<a href="${href}" style="display: inline-block; padding: 12px 24px; background-color: ${bgColor}; color: ${color}; text-decoration: none; border-radius: 6px; font-weight: 500; font-size: 16px;">${label}</a>
|
|
325
|
+
</td>
|
|
326
|
+
</tr>
|
|
327
|
+
</table>`;
|
|
328
|
+
}
|
|
329
|
+
function renderImageBlock(data) {
|
|
330
|
+
const rawSrc = String(data["src"] ?? "").trim();
|
|
331
|
+
if (!rawSrc)
|
|
332
|
+
return "<!-- image block: no src configured -->";
|
|
333
|
+
const src = escapeHtml(sanitizeUrl(rawSrc));
|
|
334
|
+
const alt = escapeHtml(String(data["alt"] ?? ""));
|
|
335
|
+
const width = sanitizeCssValue(String(data["width"] ?? "100%"));
|
|
336
|
+
const img = `<img src="${src}" alt="${alt}" width="${width}" style="display: block; max-width: 100%; height: auto; border: 0;">`;
|
|
337
|
+
if (data["href"]) {
|
|
338
|
+
const href = escapeHtml(sanitizeUrl(String(data["href"])));
|
|
339
|
+
return `<a href="${href}" style="display: block;">${img}</a>`;
|
|
340
|
+
}
|
|
341
|
+
return img;
|
|
342
|
+
}
|
|
343
|
+
function renderDividerBlock(data) {
|
|
344
|
+
const color = sanitizeCssValue(String(data["color"] ?? "#e4e4e7"));
|
|
345
|
+
const margin = sanitizeCssValue(String(data["margin"] ?? "24px 0"));
|
|
346
|
+
return `<hr style="border: none; border-top: 1px solid ${color}; margin: ${margin};">`;
|
|
347
|
+
}
|
|
348
|
+
function renderSpacerBlock(data) {
|
|
349
|
+
const height = sanitizeCssNumber(data["height"], 24);
|
|
350
|
+
return `<div style="height: ${height}px; line-height: ${height}px; font-size: 1px;"> </div>`;
|
|
351
|
+
}
|
|
352
|
+
function renderColumnsBlock(data, theme, depth) {
|
|
353
|
+
const rawColumns = data["columns"];
|
|
354
|
+
const columns = Array.isArray(rawColumns) ? rawColumns : [];
|
|
355
|
+
const width = Math.floor(100 / (columns.length || 1));
|
|
356
|
+
const tds = columns.map((col) => {
|
|
357
|
+
const colObj = (
|
|
358
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- narrowing unknown column objects
|
|
359
|
+
typeof col === "object" && col !== null ? col : {}
|
|
360
|
+
);
|
|
361
|
+
const rawBlocks = colObj["blocks"];
|
|
362
|
+
const colContent = (Array.isArray(rawBlocks) ? rawBlocks : []).filter(isValidBlock).map((b) => renderBlock(b, theme, depth + 1)).join("\n");
|
|
363
|
+
return `<td style="width: ${width}%; vertical-align: top; padding: 0 8px;">${colContent}</td>`;
|
|
364
|
+
}).join("\n");
|
|
365
|
+
return `<table role="presentation" width="100%" cellspacing="0" cellpadding="0"><tr>${tds}</tr></table>`;
|
|
366
|
+
}
|
|
367
|
+
function renderFooterBlock(data, theme) {
|
|
368
|
+
const text2 = escapeHtml(String(data["text"] ?? ""));
|
|
369
|
+
const color = sanitizeCssValue(String(data["color"] ?? theme.mutedColor));
|
|
370
|
+
return `<p style="margin: 16px 0 0; font-size: 12px; color: ${color}; text-align: center;">${text2}</p>`;
|
|
371
|
+
}
|
|
372
|
+
var MAX_BLOCK_DEPTH;
|
|
373
|
+
var init_render_blocks = __esm({
|
|
374
|
+
"libs/email/src/lib/render/render-blocks.ts"() {
|
|
375
|
+
"use strict";
|
|
376
|
+
init_escape_html();
|
|
377
|
+
init_css_inliner();
|
|
378
|
+
init_replace_variables();
|
|
379
|
+
init_sanitize();
|
|
380
|
+
init_types();
|
|
381
|
+
MAX_BLOCK_DEPTH = 5;
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
// libs/email/src/lib/templates/default-templates.ts
|
|
386
|
+
var DEFAULT_PASSWORD_RESET_BLOCKS, DEFAULT_VERIFICATION_BLOCKS;
|
|
387
|
+
var init_default_templates = __esm({
|
|
388
|
+
"libs/email/src/lib/templates/default-templates.ts"() {
|
|
389
|
+
"use strict";
|
|
390
|
+
DEFAULT_PASSWORD_RESET_BLOCKS = [
|
|
391
|
+
{
|
|
392
|
+
id: "pr-header",
|
|
393
|
+
type: "header",
|
|
394
|
+
data: {
|
|
395
|
+
title: "Reset Your Password",
|
|
396
|
+
subtitle: "",
|
|
397
|
+
alignment: "left"
|
|
398
|
+
}
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
id: "pr-greeting",
|
|
402
|
+
type: "text",
|
|
403
|
+
data: {
|
|
404
|
+
content: "{{greeting}}",
|
|
405
|
+
fontSize: 16,
|
|
406
|
+
color: "#3f3f46",
|
|
407
|
+
alignment: "left"
|
|
408
|
+
}
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
id: "pr-body",
|
|
412
|
+
type: "text",
|
|
413
|
+
data: {
|
|
414
|
+
content: "We received a request to reset your password. Click the button below to choose a new password:",
|
|
415
|
+
fontSize: 16,
|
|
416
|
+
color: "#3f3f46",
|
|
417
|
+
alignment: "left"
|
|
418
|
+
}
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
id: "pr-button",
|
|
422
|
+
type: "button",
|
|
423
|
+
data: {
|
|
424
|
+
label: "Reset Password",
|
|
425
|
+
href: "{{url}}",
|
|
426
|
+
backgroundColor: "#18181b",
|
|
427
|
+
color: "#ffffff",
|
|
428
|
+
alignment: "center"
|
|
429
|
+
}
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
id: "pr-expiry",
|
|
433
|
+
type: "text",
|
|
434
|
+
data: {
|
|
435
|
+
content: "This link will expire in {{expiresIn}}.",
|
|
436
|
+
fontSize: 14,
|
|
437
|
+
color: "#71717a",
|
|
438
|
+
alignment: "left"
|
|
439
|
+
}
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
id: "pr-ignore",
|
|
443
|
+
type: "text",
|
|
444
|
+
data: {
|
|
445
|
+
content: "If you didn't request a password reset, you can safely ignore this email. Your password will remain unchanged.",
|
|
446
|
+
fontSize: 14,
|
|
447
|
+
color: "#71717a",
|
|
448
|
+
alignment: "left"
|
|
449
|
+
}
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
id: "pr-divider",
|
|
453
|
+
type: "divider",
|
|
454
|
+
data: {
|
|
455
|
+
color: "#e4e4e7",
|
|
456
|
+
margin: "24px 0"
|
|
457
|
+
}
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
id: "pr-footer",
|
|
461
|
+
type: "footer",
|
|
462
|
+
data: {
|
|
463
|
+
text: "The {{appName}} Team",
|
|
464
|
+
color: "#71717a"
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
];
|
|
468
|
+
DEFAULT_VERIFICATION_BLOCKS = [
|
|
469
|
+
{
|
|
470
|
+
id: "ev-header",
|
|
471
|
+
type: "header",
|
|
472
|
+
data: {
|
|
473
|
+
title: "Verify Your Email",
|
|
474
|
+
subtitle: "",
|
|
475
|
+
alignment: "left"
|
|
476
|
+
}
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
id: "ev-greeting",
|
|
480
|
+
type: "text",
|
|
481
|
+
data: {
|
|
482
|
+
content: "{{greeting}}",
|
|
483
|
+
fontSize: 16,
|
|
484
|
+
color: "#3f3f46",
|
|
485
|
+
alignment: "left"
|
|
486
|
+
}
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
id: "ev-body",
|
|
490
|
+
type: "text",
|
|
491
|
+
data: {
|
|
492
|
+
content: "Welcome to {{appName}}! Please verify your email address by clicking the button below:",
|
|
493
|
+
fontSize: 16,
|
|
494
|
+
color: "#3f3f46",
|
|
495
|
+
alignment: "left"
|
|
496
|
+
}
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
id: "ev-button",
|
|
500
|
+
type: "button",
|
|
501
|
+
data: {
|
|
502
|
+
label: "Verify Email",
|
|
503
|
+
href: "{{url}}",
|
|
504
|
+
backgroundColor: "#18181b",
|
|
505
|
+
color: "#ffffff",
|
|
506
|
+
alignment: "center"
|
|
507
|
+
}
|
|
508
|
+
},
|
|
509
|
+
{
|
|
510
|
+
id: "ev-expiry",
|
|
511
|
+
type: "text",
|
|
512
|
+
data: {
|
|
513
|
+
content: "This link will expire in {{expiresIn}}.",
|
|
514
|
+
fontSize: 14,
|
|
515
|
+
color: "#71717a",
|
|
516
|
+
alignment: "left"
|
|
517
|
+
}
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
id: "ev-ignore",
|
|
521
|
+
type: "text",
|
|
522
|
+
data: {
|
|
523
|
+
content: "If you didn't create an account, you can safely ignore this email.",
|
|
524
|
+
fontSize: 14,
|
|
525
|
+
color: "#71717a",
|
|
526
|
+
alignment: "left"
|
|
527
|
+
}
|
|
528
|
+
},
|
|
529
|
+
{
|
|
530
|
+
id: "ev-divider",
|
|
531
|
+
type: "divider",
|
|
532
|
+
data: {
|
|
533
|
+
color: "#e4e4e7",
|
|
534
|
+
margin: "24px 0"
|
|
535
|
+
}
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
id: "ev-footer",
|
|
539
|
+
type: "footer",
|
|
540
|
+
data: {
|
|
541
|
+
text: "The {{appName}} Team",
|
|
542
|
+
color: "#71717a"
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
];
|
|
546
|
+
}
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
// libs/email/src/lib/components/eml-body.component.ts
|
|
550
|
+
var import_core3, EmlBody;
|
|
551
|
+
var init_eml_body_component = __esm({
|
|
552
|
+
"libs/email/src/lib/components/eml-body.component.ts"() {
|
|
553
|
+
"use strict";
|
|
554
|
+
import_core3 = require("@angular/core");
|
|
555
|
+
EmlBody = class {
|
|
556
|
+
constructor() {
|
|
557
|
+
this.backgroundColor = (0, import_core3.input)("#f4f4f5");
|
|
558
|
+
this.fontFamily = (0, import_core3.input)(
|
|
559
|
+
"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif"
|
|
560
|
+
);
|
|
561
|
+
this.padding = (0, import_core3.input)("40px 20px");
|
|
562
|
+
this.tableStyle = (0, import_core3.computed)(
|
|
563
|
+
() => `background-color: ${this.backgroundColor()}; font-family: ${this.fontFamily()}; line-height: 1.6; margin: 0; padding: 0;`
|
|
564
|
+
);
|
|
565
|
+
this.cellStyle = (0, import_core3.computed)(() => `padding: ${this.padding()};`);
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
EmlBody = __decorateClass([
|
|
569
|
+
(0, import_core3.Component)({
|
|
570
|
+
selector: "eml-body",
|
|
571
|
+
template: `
|
|
572
|
+
<table
|
|
573
|
+
role="presentation"
|
|
574
|
+
width="100%"
|
|
575
|
+
cellspacing="0"
|
|
576
|
+
cellpadding="0"
|
|
577
|
+
[attr.style]="tableStyle()"
|
|
578
|
+
>
|
|
579
|
+
<tr>
|
|
580
|
+
<td [attr.style]="cellStyle()">
|
|
581
|
+
<ng-content />
|
|
582
|
+
</td>
|
|
583
|
+
</tr>
|
|
584
|
+
</table>
|
|
585
|
+
`,
|
|
586
|
+
changeDetection: import_core3.ChangeDetectionStrategy.OnPush
|
|
587
|
+
})
|
|
588
|
+
], EmlBody);
|
|
589
|
+
}
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
// libs/email/src/lib/components/eml-container.component.ts
|
|
593
|
+
var import_core4, EmlContainer;
|
|
594
|
+
var init_eml_container_component = __esm({
|
|
595
|
+
"libs/email/src/lib/components/eml-container.component.ts"() {
|
|
596
|
+
"use strict";
|
|
597
|
+
import_core4 = require("@angular/core");
|
|
598
|
+
EmlContainer = class {
|
|
599
|
+
constructor() {
|
|
600
|
+
this.maxWidth = (0, import_core4.input)("480px");
|
|
601
|
+
this.backgroundColor = (0, import_core4.input)("#ffffff");
|
|
602
|
+
this.borderRadius = (0, import_core4.input)("8px");
|
|
603
|
+
this.padding = (0, import_core4.input)("40px");
|
|
604
|
+
this.shadow = (0, import_core4.input)("0 1px 3px rgba(0,0,0,0.1)");
|
|
605
|
+
this.tableStyle = (0, import_core4.computed)(
|
|
606
|
+
() => `max-width: ${this.maxWidth()}; margin: 0 auto; background-color: ${this.backgroundColor()}; border-radius: ${this.borderRadius()}; box-shadow: ${this.shadow()};`
|
|
607
|
+
);
|
|
608
|
+
this.cellStyle = (0, import_core4.computed)(() => `padding: ${this.padding()};`);
|
|
609
|
+
}
|
|
610
|
+
};
|
|
611
|
+
EmlContainer = __decorateClass([
|
|
612
|
+
(0, import_core4.Component)({
|
|
613
|
+
selector: "eml-container",
|
|
614
|
+
template: `
|
|
615
|
+
<table
|
|
616
|
+
role="presentation"
|
|
617
|
+
width="100%"
|
|
618
|
+
cellspacing="0"
|
|
619
|
+
cellpadding="0"
|
|
620
|
+
[attr.style]="tableStyle()"
|
|
621
|
+
>
|
|
622
|
+
<tr>
|
|
623
|
+
<td [attr.style]="cellStyle()">
|
|
624
|
+
<ng-content />
|
|
625
|
+
</td>
|
|
626
|
+
</tr>
|
|
627
|
+
</table>
|
|
628
|
+
`,
|
|
629
|
+
changeDetection: import_core4.ChangeDetectionStrategy.OnPush
|
|
630
|
+
})
|
|
631
|
+
], EmlContainer);
|
|
632
|
+
}
|
|
633
|
+
});
|
|
634
|
+
|
|
635
|
+
// libs/email/src/lib/components/eml-section.component.ts
|
|
636
|
+
var import_core5, EmlSection;
|
|
637
|
+
var init_eml_section_component = __esm({
|
|
638
|
+
"libs/email/src/lib/components/eml-section.component.ts"() {
|
|
639
|
+
"use strict";
|
|
640
|
+
import_core5 = require("@angular/core");
|
|
641
|
+
EmlSection = class {
|
|
642
|
+
constructor() {
|
|
643
|
+
this.padding = (0, import_core5.input)("0");
|
|
644
|
+
this.cellStyle = (0, import_core5.computed)(() => `padding: ${this.padding()};`);
|
|
645
|
+
}
|
|
646
|
+
};
|
|
647
|
+
EmlSection = __decorateClass([
|
|
648
|
+
(0, import_core5.Component)({
|
|
649
|
+
selector: "eml-section",
|
|
650
|
+
template: `
|
|
651
|
+
<table role="presentation" width="100%" cellspacing="0" cellpadding="0">
|
|
652
|
+
<tr>
|
|
653
|
+
<td [attr.style]="cellStyle()">
|
|
654
|
+
<ng-content />
|
|
655
|
+
</td>
|
|
656
|
+
</tr>
|
|
657
|
+
</table>
|
|
658
|
+
`,
|
|
659
|
+
changeDetection: import_core5.ChangeDetectionStrategy.OnPush
|
|
660
|
+
})
|
|
661
|
+
], EmlSection);
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
// libs/email/src/lib/components/eml-row.component.ts
|
|
666
|
+
var import_core6, EmlRow;
|
|
667
|
+
var init_eml_row_component = __esm({
|
|
668
|
+
"libs/email/src/lib/components/eml-row.component.ts"() {
|
|
669
|
+
"use strict";
|
|
670
|
+
import_core6 = require("@angular/core");
|
|
671
|
+
EmlRow = class {
|
|
672
|
+
};
|
|
673
|
+
EmlRow = __decorateClass([
|
|
674
|
+
(0, import_core6.Component)({
|
|
675
|
+
selector: "eml-row",
|
|
676
|
+
template: `
|
|
677
|
+
<table role="presentation" width="100%" cellspacing="0" cellpadding="0">
|
|
678
|
+
<tr>
|
|
679
|
+
<ng-content />
|
|
680
|
+
</tr>
|
|
681
|
+
</table>
|
|
682
|
+
`,
|
|
683
|
+
changeDetection: import_core6.ChangeDetectionStrategy.OnPush
|
|
684
|
+
})
|
|
685
|
+
], EmlRow);
|
|
686
|
+
}
|
|
687
|
+
});
|
|
688
|
+
|
|
689
|
+
// libs/email/src/lib/components/eml-column.component.ts
|
|
690
|
+
var import_core7, EmlColumn;
|
|
691
|
+
var init_eml_column_component = __esm({
|
|
692
|
+
"libs/email/src/lib/components/eml-column.component.ts"() {
|
|
693
|
+
"use strict";
|
|
694
|
+
import_core7 = require("@angular/core");
|
|
695
|
+
EmlColumn = class {
|
|
696
|
+
constructor() {
|
|
697
|
+
this.width = (0, import_core7.input)(void 0);
|
|
698
|
+
this.padding = (0, import_core7.input)("0");
|
|
699
|
+
this.verticalAlign = (0, import_core7.input)("top");
|
|
700
|
+
this.cellStyle = (0, import_core7.computed)(
|
|
701
|
+
() => `padding: ${this.padding()}; vertical-align: ${this.verticalAlign()};`
|
|
702
|
+
);
|
|
703
|
+
}
|
|
704
|
+
};
|
|
705
|
+
EmlColumn = __decorateClass([
|
|
706
|
+
(0, import_core7.Component)({
|
|
707
|
+
selector: "eml-column",
|
|
708
|
+
template: `
|
|
709
|
+
<td [attr.style]="cellStyle()" [attr.width]="width()" valign="top">
|
|
710
|
+
<ng-content />
|
|
711
|
+
</td>
|
|
712
|
+
`,
|
|
713
|
+
changeDetection: import_core7.ChangeDetectionStrategy.OnPush
|
|
714
|
+
})
|
|
715
|
+
], EmlColumn);
|
|
716
|
+
}
|
|
717
|
+
});
|
|
718
|
+
|
|
719
|
+
// libs/email/src/lib/components/eml-text.component.ts
|
|
720
|
+
var import_core8, EmlText;
|
|
721
|
+
var init_eml_text_component = __esm({
|
|
722
|
+
"libs/email/src/lib/components/eml-text.component.ts"() {
|
|
723
|
+
"use strict";
|
|
724
|
+
import_core8 = require("@angular/core");
|
|
725
|
+
EmlText = class {
|
|
726
|
+
constructor() {
|
|
727
|
+
this.color = (0, import_core8.input)("#3f3f46");
|
|
728
|
+
this.fontSize = (0, import_core8.input)("16px");
|
|
729
|
+
this.lineHeight = (0, import_core8.input)("1.6");
|
|
730
|
+
this.margin = (0, import_core8.input)("0 0 16px");
|
|
731
|
+
this.textAlign = (0, import_core8.input)("left");
|
|
732
|
+
this.pStyle = (0, import_core8.computed)(
|
|
733
|
+
() => `margin: ${this.margin()}; color: ${this.color()}; font-size: ${this.fontSize()}; line-height: ${this.lineHeight()}; text-align: ${this.textAlign()};`
|
|
734
|
+
);
|
|
735
|
+
}
|
|
736
|
+
};
|
|
737
|
+
EmlText = __decorateClass([
|
|
738
|
+
(0, import_core8.Component)({
|
|
739
|
+
selector: "eml-text",
|
|
740
|
+
template: `
|
|
741
|
+
<p [attr.style]="pStyle()">
|
|
742
|
+
<ng-content />
|
|
743
|
+
</p>
|
|
744
|
+
`,
|
|
745
|
+
changeDetection: import_core8.ChangeDetectionStrategy.OnPush
|
|
746
|
+
})
|
|
747
|
+
], EmlText);
|
|
748
|
+
}
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
// libs/email/src/lib/components/eml-heading.component.ts
|
|
752
|
+
var import_core9, EmlHeading;
|
|
753
|
+
var init_eml_heading_component = __esm({
|
|
754
|
+
"libs/email/src/lib/components/eml-heading.component.ts"() {
|
|
755
|
+
"use strict";
|
|
756
|
+
import_core9 = require("@angular/core");
|
|
757
|
+
EmlHeading = class {
|
|
758
|
+
constructor() {
|
|
759
|
+
this.level = (0, import_core9.input)(1);
|
|
760
|
+
this.color = (0, import_core9.input)("#18181b");
|
|
761
|
+
this.margin = (0, import_core9.input)("0 0 24px");
|
|
762
|
+
this.textAlign = (0, import_core9.input)("left");
|
|
763
|
+
this.fontSizeMap = {
|
|
764
|
+
1: "24px",
|
|
765
|
+
2: "20px",
|
|
766
|
+
3: "16px"
|
|
767
|
+
};
|
|
768
|
+
this.headingStyle = (0, import_core9.computed)(
|
|
769
|
+
() => `margin: ${this.margin()}; font-size: ${this.fontSizeMap[this.level()] ?? "24px"}; font-weight: 600; color: ${this.color()}; text-align: ${this.textAlign()};`
|
|
770
|
+
);
|
|
771
|
+
}
|
|
772
|
+
};
|
|
773
|
+
EmlHeading = __decorateClass([
|
|
774
|
+
(0, import_core9.Component)({
|
|
775
|
+
selector: "eml-heading",
|
|
776
|
+
template: `<div [attr.style]="headingStyle()" [attr.role]="'heading'" [attr.aria-level]="level()">
|
|
777
|
+
<ng-content />
|
|
778
|
+
</div>`,
|
|
779
|
+
changeDetection: import_core9.ChangeDetectionStrategy.OnPush
|
|
780
|
+
})
|
|
781
|
+
], EmlHeading);
|
|
782
|
+
}
|
|
783
|
+
});
|
|
784
|
+
|
|
785
|
+
// libs/email/src/lib/components/eml-button.component.ts
|
|
786
|
+
var import_core10, EmlButton;
|
|
787
|
+
var init_eml_button_component = __esm({
|
|
788
|
+
"libs/email/src/lib/components/eml-button.component.ts"() {
|
|
789
|
+
"use strict";
|
|
790
|
+
import_core10 = require("@angular/core");
|
|
791
|
+
EmlButton = class {
|
|
792
|
+
constructor() {
|
|
793
|
+
this.href = (0, import_core10.input)("");
|
|
794
|
+
this.backgroundColor = (0, import_core10.input)("#18181b");
|
|
795
|
+
this.color = (0, import_core10.input)("#ffffff");
|
|
796
|
+
this.borderRadius = (0, import_core10.input)("6px");
|
|
797
|
+
this.padding = (0, import_core10.input)("12px 24px");
|
|
798
|
+
this.textAlign = (0, import_core10.input)("left");
|
|
799
|
+
this.alignStyle = (0, import_core10.computed)(() => `padding: 0; text-align: ${this.textAlign()};`);
|
|
800
|
+
this.linkStyle = (0, import_core10.computed)(
|
|
801
|
+
() => `display: inline-block; padding: ${this.padding()}; background-color: ${this.backgroundColor()}; color: ${this.color()}; text-decoration: none; border-radius: ${this.borderRadius()}; font-weight: 500;`
|
|
802
|
+
);
|
|
803
|
+
}
|
|
804
|
+
};
|
|
805
|
+
EmlButton = __decorateClass([
|
|
806
|
+
(0, import_core10.Component)({
|
|
807
|
+
selector: "eml-button",
|
|
808
|
+
template: `
|
|
809
|
+
<table role="presentation" width="100%" cellspacing="0" cellpadding="0">
|
|
810
|
+
<tr>
|
|
811
|
+
<td [attr.style]="alignStyle()">
|
|
812
|
+
<a [attr.href]="href()" [attr.style]="linkStyle()" target="_blank">
|
|
813
|
+
<ng-content />
|
|
814
|
+
</a>
|
|
815
|
+
</td>
|
|
816
|
+
</tr>
|
|
817
|
+
</table>
|
|
818
|
+
`,
|
|
819
|
+
changeDetection: import_core10.ChangeDetectionStrategy.OnPush
|
|
820
|
+
})
|
|
821
|
+
], EmlButton);
|
|
822
|
+
}
|
|
823
|
+
});
|
|
824
|
+
|
|
825
|
+
// libs/email/src/lib/components/eml-link.component.ts
|
|
826
|
+
var import_core11, EmlLink;
|
|
827
|
+
var init_eml_link_component = __esm({
|
|
828
|
+
"libs/email/src/lib/components/eml-link.component.ts"() {
|
|
829
|
+
"use strict";
|
|
830
|
+
import_core11 = require("@angular/core");
|
|
831
|
+
EmlLink = class {
|
|
832
|
+
constructor() {
|
|
833
|
+
this.href = (0, import_core11.input)("");
|
|
834
|
+
this.color = (0, import_core11.input)("#18181b");
|
|
835
|
+
this.textDecoration = (0, import_core11.input)("underline");
|
|
836
|
+
this.linkStyle = (0, import_core11.computed)(
|
|
837
|
+
() => `color: ${this.color()}; text-decoration: ${this.textDecoration()};`
|
|
838
|
+
);
|
|
839
|
+
}
|
|
840
|
+
};
|
|
841
|
+
EmlLink = __decorateClass([
|
|
842
|
+
(0, import_core11.Component)({
|
|
843
|
+
selector: "eml-link",
|
|
844
|
+
template: `
|
|
845
|
+
<a [attr.href]="href()" [attr.style]="linkStyle()" target="_blank">
|
|
846
|
+
<ng-content />
|
|
847
|
+
</a>
|
|
848
|
+
`,
|
|
849
|
+
changeDetection: import_core11.ChangeDetectionStrategy.OnPush
|
|
850
|
+
})
|
|
851
|
+
], EmlLink);
|
|
852
|
+
}
|
|
853
|
+
});
|
|
854
|
+
|
|
855
|
+
// libs/email/src/lib/components/eml-image.component.ts
|
|
856
|
+
var import_core12, EmlImage;
|
|
857
|
+
var init_eml_image_component = __esm({
|
|
858
|
+
"libs/email/src/lib/components/eml-image.component.ts"() {
|
|
859
|
+
"use strict";
|
|
860
|
+
import_core12 = require("@angular/core");
|
|
861
|
+
EmlImage = class {
|
|
862
|
+
constructor() {
|
|
863
|
+
this.src = (0, import_core12.input)("");
|
|
864
|
+
this.alt = (0, import_core12.input)("");
|
|
865
|
+
this.width = (0, import_core12.input)(void 0);
|
|
866
|
+
this.height = (0, import_core12.input)(void 0);
|
|
867
|
+
this.borderRadius = (0, import_core12.input)("0");
|
|
868
|
+
this.imgStyle = (0, import_core12.computed)(
|
|
869
|
+
() => `display: block; max-width: 100%; border: 0; outline: none; border-radius: ${this.borderRadius()};`
|
|
870
|
+
);
|
|
871
|
+
}
|
|
872
|
+
};
|
|
873
|
+
EmlImage = __decorateClass([
|
|
874
|
+
(0, import_core12.Component)({
|
|
875
|
+
selector: "eml-image",
|
|
876
|
+
template: `
|
|
877
|
+
<img
|
|
878
|
+
[attr.src]="src()"
|
|
879
|
+
[attr.alt]="alt()"
|
|
880
|
+
[attr.width]="width()"
|
|
881
|
+
[attr.height]="height()"
|
|
882
|
+
[attr.style]="imgStyle()"
|
|
883
|
+
/>
|
|
884
|
+
`,
|
|
885
|
+
changeDetection: import_core12.ChangeDetectionStrategy.OnPush
|
|
886
|
+
})
|
|
887
|
+
], EmlImage);
|
|
888
|
+
}
|
|
889
|
+
});
|
|
890
|
+
|
|
891
|
+
// libs/email/src/lib/components/eml-divider.component.ts
|
|
892
|
+
var import_core13, EmlDivider;
|
|
893
|
+
var init_eml_divider_component = __esm({
|
|
894
|
+
"libs/email/src/lib/components/eml-divider.component.ts"() {
|
|
895
|
+
"use strict";
|
|
896
|
+
import_core13 = require("@angular/core");
|
|
897
|
+
EmlDivider = class {
|
|
898
|
+
constructor() {
|
|
899
|
+
this.color = (0, import_core13.input)("#e4e4e7");
|
|
900
|
+
this.margin = (0, import_core13.input)("24px 0");
|
|
901
|
+
this.hrStyle = (0, import_core13.computed)(
|
|
902
|
+
() => `border: none; border-top: 1px solid ${this.color()}; margin: ${this.margin()};`
|
|
903
|
+
);
|
|
904
|
+
}
|
|
905
|
+
};
|
|
906
|
+
EmlDivider = __decorateClass([
|
|
907
|
+
(0, import_core13.Component)({
|
|
908
|
+
selector: "eml-divider",
|
|
909
|
+
template: `<hr [attr.style]="hrStyle()" />`,
|
|
910
|
+
changeDetection: import_core13.ChangeDetectionStrategy.OnPush
|
|
911
|
+
})
|
|
912
|
+
], EmlDivider);
|
|
913
|
+
}
|
|
914
|
+
});
|
|
915
|
+
|
|
916
|
+
// libs/email/src/lib/components/eml-preview.component.ts
|
|
917
|
+
var import_core14, EmlPreview;
|
|
918
|
+
var init_eml_preview_component = __esm({
|
|
919
|
+
"libs/email/src/lib/components/eml-preview.component.ts"() {
|
|
920
|
+
"use strict";
|
|
921
|
+
import_core14 = require("@angular/core");
|
|
922
|
+
EmlPreview = class {
|
|
923
|
+
};
|
|
924
|
+
EmlPreview = __decorateClass([
|
|
925
|
+
(0, import_core14.Component)({
|
|
926
|
+
selector: "eml-preview",
|
|
927
|
+
template: `
|
|
928
|
+
<div style="display: none; max-height: 0; overflow: hidden; mso-hide: all;">
|
|
929
|
+
<ng-content />
|
|
930
|
+
</div>
|
|
931
|
+
`,
|
|
932
|
+
changeDetection: import_core14.ChangeDetectionStrategy.OnPush
|
|
933
|
+
})
|
|
934
|
+
], EmlPreview);
|
|
935
|
+
}
|
|
936
|
+
});
|
|
937
|
+
|
|
938
|
+
// libs/email/src/lib/components/eml-spacer.component.ts
|
|
939
|
+
var import_core15, EmlSpacer;
|
|
940
|
+
var init_eml_spacer_component = __esm({
|
|
941
|
+
"libs/email/src/lib/components/eml-spacer.component.ts"() {
|
|
942
|
+
"use strict";
|
|
943
|
+
import_core15 = require("@angular/core");
|
|
944
|
+
EmlSpacer = class {
|
|
945
|
+
constructor() {
|
|
946
|
+
this.height = (0, import_core15.input)("24px");
|
|
947
|
+
this.spacerStyle = (0, import_core15.computed)(
|
|
948
|
+
() => `height: ${this.height()}; line-height: ${this.height()}; font-size: 1px;`
|
|
949
|
+
);
|
|
950
|
+
}
|
|
951
|
+
};
|
|
952
|
+
EmlSpacer = __decorateClass([
|
|
953
|
+
(0, import_core15.Component)({
|
|
954
|
+
selector: "eml-spacer",
|
|
955
|
+
template: `<div [attr.style]="spacerStyle()"></div>`,
|
|
956
|
+
changeDetection: import_core15.ChangeDetectionStrategy.OnPush
|
|
957
|
+
})
|
|
958
|
+
], EmlSpacer);
|
|
959
|
+
}
|
|
960
|
+
});
|
|
961
|
+
|
|
962
|
+
// libs/email/src/lib/components/eml-footer.component.ts
|
|
963
|
+
var import_core16, EmlFooter;
|
|
964
|
+
var init_eml_footer_component = __esm({
|
|
965
|
+
"libs/email/src/lib/components/eml-footer.component.ts"() {
|
|
966
|
+
"use strict";
|
|
967
|
+
import_core16 = require("@angular/core");
|
|
968
|
+
EmlFooter = class {
|
|
969
|
+
constructor() {
|
|
970
|
+
this.maxWidth = (0, import_core16.input)("480px");
|
|
971
|
+
this.color = (0, import_core16.input)("#71717a");
|
|
972
|
+
this.fontSize = (0, import_core16.input)("12px");
|
|
973
|
+
this.textAlign = (0, import_core16.input)("center");
|
|
974
|
+
this.padding = (0, import_core16.input)("20px 0 0");
|
|
975
|
+
this.tableStyle = (0, import_core16.computed)(() => `max-width: ${this.maxWidth()}; margin: 0 auto;`);
|
|
976
|
+
this.cellStyle = (0, import_core16.computed)(
|
|
977
|
+
() => `text-align: ${this.textAlign()}; color: ${this.color()}; font-size: ${this.fontSize()}; padding: ${this.padding()};`
|
|
978
|
+
);
|
|
979
|
+
}
|
|
980
|
+
};
|
|
981
|
+
EmlFooter = __decorateClass([
|
|
982
|
+
(0, import_core16.Component)({
|
|
983
|
+
selector: "eml-footer",
|
|
984
|
+
template: `
|
|
985
|
+
<table
|
|
986
|
+
role="presentation"
|
|
987
|
+
width="100%"
|
|
988
|
+
cellspacing="0"
|
|
989
|
+
cellpadding="0"
|
|
990
|
+
[attr.style]="tableStyle()"
|
|
991
|
+
>
|
|
992
|
+
<tr>
|
|
993
|
+
<td [attr.style]="cellStyle()">
|
|
994
|
+
<ng-content />
|
|
995
|
+
</td>
|
|
996
|
+
</tr>
|
|
997
|
+
</table>
|
|
998
|
+
`,
|
|
999
|
+
changeDetection: import_core16.ChangeDetectionStrategy.OnPush
|
|
1000
|
+
})
|
|
1001
|
+
], EmlFooter);
|
|
1002
|
+
}
|
|
1003
|
+
});
|
|
1004
|
+
|
|
1005
|
+
// libs/email/src/lib/utils/blocks-to-plain-text.ts
|
|
1006
|
+
function blocksToPlainText(blocks2, depth = 0) {
|
|
1007
|
+
const lines = [];
|
|
1008
|
+
for (const block of blocks2) {
|
|
1009
|
+
const text2 = blockToText(block, depth);
|
|
1010
|
+
if (text2) {
|
|
1011
|
+
lines.push(text2);
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
return lines.join("\n\n");
|
|
1015
|
+
}
|
|
1016
|
+
function blockToText(block, depth) {
|
|
1017
|
+
switch (block.type) {
|
|
1018
|
+
case "header":
|
|
1019
|
+
return headerToText(block.data);
|
|
1020
|
+
case "text":
|
|
1021
|
+
return String(block.data["content"] ?? "");
|
|
1022
|
+
case "button":
|
|
1023
|
+
return buttonToText(block.data);
|
|
1024
|
+
case "footer":
|
|
1025
|
+
return String(block.data["text"] ?? "");
|
|
1026
|
+
case "columns":
|
|
1027
|
+
if (depth >= MAX_BLOCK_DEPTH2) {
|
|
1028
|
+
console.warn("[momentum:email] Max nesting depth reached, skipping columns block");
|
|
1029
|
+
return "";
|
|
1030
|
+
}
|
|
1031
|
+
return columnsToText(block.data, depth);
|
|
1032
|
+
case "divider":
|
|
1033
|
+
case "spacer":
|
|
1034
|
+
case "image":
|
|
1035
|
+
return "";
|
|
1036
|
+
default:
|
|
1037
|
+
return "";
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
function headerToText(data) {
|
|
1041
|
+
const title = String(data["title"] ?? "");
|
|
1042
|
+
const subtitle = data["subtitle"] ? String(data["subtitle"]) : "";
|
|
1043
|
+
if (!title && !subtitle)
|
|
1044
|
+
return "";
|
|
1045
|
+
if (!subtitle)
|
|
1046
|
+
return title;
|
|
1047
|
+
return `${title}
|
|
1048
|
+
${subtitle}`;
|
|
1049
|
+
}
|
|
1050
|
+
function buttonToText(data) {
|
|
1051
|
+
const label = String(data["label"] ?? "");
|
|
1052
|
+
const href = data["href"] ? String(data["href"]) : "";
|
|
1053
|
+
if (!label)
|
|
1054
|
+
return "";
|
|
1055
|
+
if (!href)
|
|
1056
|
+
return label;
|
|
1057
|
+
return `${label}: ${href}`;
|
|
1058
|
+
}
|
|
1059
|
+
function columnsToText(data, depth) {
|
|
1060
|
+
const columns = data["columns"];
|
|
1061
|
+
if (!Array.isArray(columns))
|
|
1062
|
+
return "";
|
|
1063
|
+
const parts = [];
|
|
1064
|
+
for (const col of columns) {
|
|
1065
|
+
if (col && typeof col === "object" && Array.isArray(col.blocks)) {
|
|
1066
|
+
const colText = blocksToPlainText(col.blocks, depth + 1);
|
|
1067
|
+
if (colText) {
|
|
1068
|
+
parts.push(colText);
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
return parts.join("\n\n");
|
|
1073
|
+
}
|
|
1074
|
+
var MAX_BLOCK_DEPTH2;
|
|
1075
|
+
var init_blocks_to_plain_text = __esm({
|
|
1076
|
+
"libs/email/src/lib/utils/blocks-to-plain-text.ts"() {
|
|
1077
|
+
"use strict";
|
|
1078
|
+
MAX_BLOCK_DEPTH2 = 5;
|
|
1079
|
+
}
|
|
1080
|
+
});
|
|
1081
|
+
|
|
1082
|
+
// libs/email/src/index.ts
|
|
31
1083
|
var src_exports = {};
|
|
32
1084
|
__export(src_exports, {
|
|
1085
|
+
DEFAULT_EMAIL_THEME: () => DEFAULT_EMAIL_THEME,
|
|
1086
|
+
DEFAULT_PASSWORD_RESET_BLOCKS: () => DEFAULT_PASSWORD_RESET_BLOCKS,
|
|
1087
|
+
DEFAULT_VERIFICATION_BLOCKS: () => DEFAULT_VERIFICATION_BLOCKS,
|
|
1088
|
+
EMAIL_DATA: () => EMAIL_DATA,
|
|
1089
|
+
EmlBody: () => EmlBody,
|
|
1090
|
+
EmlButton: () => EmlButton,
|
|
1091
|
+
EmlColumn: () => EmlColumn,
|
|
1092
|
+
EmlContainer: () => EmlContainer,
|
|
1093
|
+
EmlDivider: () => EmlDivider,
|
|
1094
|
+
EmlFooter: () => EmlFooter,
|
|
1095
|
+
EmlHeading: () => EmlHeading,
|
|
1096
|
+
EmlImage: () => EmlImage,
|
|
1097
|
+
EmlLink: () => EmlLink,
|
|
1098
|
+
EmlPreview: () => EmlPreview,
|
|
1099
|
+
EmlRow: () => EmlRow,
|
|
1100
|
+
EmlSection: () => EmlSection,
|
|
1101
|
+
EmlSpacer: () => EmlSpacer,
|
|
1102
|
+
EmlText: () => EmlText,
|
|
1103
|
+
blocksToPlainText: () => blocksToPlainText,
|
|
1104
|
+
escapeHtml: () => escapeHtml,
|
|
1105
|
+
injectEmailData: () => injectEmailData,
|
|
1106
|
+
inlineCss: () => inlineCss,
|
|
1107
|
+
isValidBlock: () => isValidBlock,
|
|
1108
|
+
renderEmail: () => renderEmail,
|
|
1109
|
+
renderEmailFromBlocks: () => renderEmailFromBlocks,
|
|
1110
|
+
replaceBlockVariables: () => replaceBlockVariables,
|
|
1111
|
+
replaceVariables: () => replaceVariables,
|
|
1112
|
+
sanitizeAlignment: () => sanitizeAlignment,
|
|
1113
|
+
sanitizeCssNumber: () => sanitizeCssNumber,
|
|
1114
|
+
sanitizeCssValue: () => sanitizeCssValue,
|
|
1115
|
+
sanitizeFontFamily: () => sanitizeFontFamily,
|
|
1116
|
+
sanitizeUrl: () => sanitizeUrl
|
|
1117
|
+
});
|
|
1118
|
+
var init_src = __esm({
|
|
1119
|
+
"libs/email/src/index.ts"() {
|
|
1120
|
+
"use strict";
|
|
1121
|
+
init_render_email();
|
|
1122
|
+
init_render_blocks();
|
|
1123
|
+
init_render_types();
|
|
1124
|
+
init_replace_variables();
|
|
1125
|
+
init_default_templates();
|
|
1126
|
+
init_eml_body_component();
|
|
1127
|
+
init_eml_container_component();
|
|
1128
|
+
init_eml_section_component();
|
|
1129
|
+
init_eml_row_component();
|
|
1130
|
+
init_eml_column_component();
|
|
1131
|
+
init_eml_text_component();
|
|
1132
|
+
init_eml_heading_component();
|
|
1133
|
+
init_eml_button_component();
|
|
1134
|
+
init_eml_link_component();
|
|
1135
|
+
init_eml_image_component();
|
|
1136
|
+
init_eml_divider_component();
|
|
1137
|
+
init_eml_preview_component();
|
|
1138
|
+
init_eml_spacer_component();
|
|
1139
|
+
init_eml_footer_component();
|
|
1140
|
+
init_escape_html();
|
|
1141
|
+
init_css_inliner();
|
|
1142
|
+
init_sanitize();
|
|
1143
|
+
init_blocks_to_plain_text();
|
|
1144
|
+
init_render_blocks();
|
|
1145
|
+
init_types();
|
|
1146
|
+
}
|
|
1147
|
+
});
|
|
1148
|
+
|
|
1149
|
+
// libs/auth/src/lib/email-components/password-reset-email.component.ts
|
|
1150
|
+
var password_reset_email_component_exports = {};
|
|
1151
|
+
__export(password_reset_email_component_exports, {
|
|
1152
|
+
PasswordResetEmailComponent: () => PasswordResetEmailComponent
|
|
1153
|
+
});
|
|
1154
|
+
var import_core17, PasswordResetEmailComponent;
|
|
1155
|
+
var init_password_reset_email_component = __esm({
|
|
1156
|
+
"libs/auth/src/lib/email-components/password-reset-email.component.ts"() {
|
|
1157
|
+
"use strict";
|
|
1158
|
+
import_core17 = require("@angular/core");
|
|
1159
|
+
init_src();
|
|
1160
|
+
init_src();
|
|
1161
|
+
PasswordResetEmailComponent = class {
|
|
1162
|
+
constructor() {
|
|
1163
|
+
this.data = injectEmailData();
|
|
1164
|
+
this.year = (/* @__PURE__ */ new Date()).getFullYear();
|
|
1165
|
+
}
|
|
1166
|
+
get greeting() {
|
|
1167
|
+
return this.data.name ? `Hi ${this.data.name},` : "Hi,";
|
|
1168
|
+
}
|
|
1169
|
+
};
|
|
1170
|
+
PasswordResetEmailComponent = __decorateClass([
|
|
1171
|
+
(0, import_core17.Component)({
|
|
1172
|
+
selector: "auth-password-reset-email",
|
|
1173
|
+
imports: [EmlBody, EmlContainer, EmlHeading, EmlText, EmlButton, EmlDivider, EmlFooter],
|
|
1174
|
+
template: `
|
|
1175
|
+
<eml-body>
|
|
1176
|
+
<eml-container>
|
|
1177
|
+
<eml-heading>Reset your password</eml-heading>
|
|
1178
|
+
<eml-text>{{ greeting }}</eml-text>
|
|
1179
|
+
<eml-text>
|
|
1180
|
+
We received a request to reset your password. Click the button below to choose a new
|
|
1181
|
+
password:
|
|
1182
|
+
</eml-text>
|
|
1183
|
+
<eml-button [href]="data.url">Reset Password</eml-button>
|
|
1184
|
+
<eml-text color="#71717a" fontSize="14px">
|
|
1185
|
+
This link will expire in {{ data.expiresIn }}.
|
|
1186
|
+
</eml-text>
|
|
1187
|
+
<eml-text color="#71717a" fontSize="14px">
|
|
1188
|
+
If you didn't request a password reset, you can safely ignore this email.
|
|
1189
|
+
</eml-text>
|
|
1190
|
+
<eml-divider />
|
|
1191
|
+
<eml-text color="#71717a" fontSize="12px">
|
|
1192
|
+
If the button doesn't work, copy and paste this URL into your browser:
|
|
1193
|
+
</eml-text>
|
|
1194
|
+
<eml-text color="#71717a" fontSize="12px">{{ data.url }}</eml-text>
|
|
1195
|
+
</eml-container>
|
|
1196
|
+
<eml-footer> © {{ year }} {{ data.appName }}. All rights reserved. </eml-footer>
|
|
1197
|
+
</eml-body>
|
|
1198
|
+
`,
|
|
1199
|
+
changeDetection: import_core17.ChangeDetectionStrategy.OnPush
|
|
1200
|
+
})
|
|
1201
|
+
], PasswordResetEmailComponent);
|
|
1202
|
+
}
|
|
1203
|
+
});
|
|
1204
|
+
|
|
1205
|
+
// libs/auth/src/lib/email-components/verification-email.component.ts
|
|
1206
|
+
var verification_email_component_exports = {};
|
|
1207
|
+
__export(verification_email_component_exports, {
|
|
1208
|
+
VerificationEmailComponent: () => VerificationEmailComponent
|
|
1209
|
+
});
|
|
1210
|
+
var import_core18, VerificationEmailComponent;
|
|
1211
|
+
var init_verification_email_component = __esm({
|
|
1212
|
+
"libs/auth/src/lib/email-components/verification-email.component.ts"() {
|
|
1213
|
+
"use strict";
|
|
1214
|
+
import_core18 = require("@angular/core");
|
|
1215
|
+
init_src();
|
|
1216
|
+
init_src();
|
|
1217
|
+
VerificationEmailComponent = class {
|
|
1218
|
+
constructor() {
|
|
1219
|
+
this.data = injectEmailData();
|
|
1220
|
+
this.year = (/* @__PURE__ */ new Date()).getFullYear();
|
|
1221
|
+
}
|
|
1222
|
+
get greeting() {
|
|
1223
|
+
return this.data.name ? `Hi ${this.data.name},` : "Hi,";
|
|
1224
|
+
}
|
|
1225
|
+
};
|
|
1226
|
+
VerificationEmailComponent = __decorateClass([
|
|
1227
|
+
(0, import_core18.Component)({
|
|
1228
|
+
selector: "auth-verification-email",
|
|
1229
|
+
imports: [EmlBody, EmlContainer, EmlHeading, EmlText, EmlButton, EmlDivider, EmlFooter],
|
|
1230
|
+
template: `
|
|
1231
|
+
<eml-body>
|
|
1232
|
+
<eml-container>
|
|
1233
|
+
<eml-heading>Verify your email</eml-heading>
|
|
1234
|
+
<eml-text>{{ greeting }}</eml-text>
|
|
1235
|
+
<eml-text>
|
|
1236
|
+
Welcome to {{ data.appName }}! Please verify your email address by clicking the button
|
|
1237
|
+
below:
|
|
1238
|
+
</eml-text>
|
|
1239
|
+
<eml-button [href]="data.url">Verify Email</eml-button>
|
|
1240
|
+
<eml-text color="#71717a" fontSize="14px">
|
|
1241
|
+
This link will expire in {{ data.expiresIn }}.
|
|
1242
|
+
</eml-text>
|
|
1243
|
+
<eml-text color="#71717a" fontSize="14px">
|
|
1244
|
+
If you didn't create an account, you can safely ignore this email.
|
|
1245
|
+
</eml-text>
|
|
1246
|
+
<eml-divider />
|
|
1247
|
+
<eml-text color="#71717a" fontSize="12px">
|
|
1248
|
+
If the button doesn't work, copy and paste this URL into your browser:
|
|
1249
|
+
</eml-text>
|
|
1250
|
+
<eml-text color="#71717a" fontSize="12px">{{ data.url }}</eml-text>
|
|
1251
|
+
</eml-container>
|
|
1252
|
+
<eml-footer> © {{ year }} {{ data.appName }}. All rights reserved. </eml-footer>
|
|
1253
|
+
</eml-body>
|
|
1254
|
+
`,
|
|
1255
|
+
changeDetection: import_core18.ChangeDetectionStrategy.OnPush
|
|
1256
|
+
})
|
|
1257
|
+
], VerificationEmailComponent);
|
|
1258
|
+
}
|
|
1259
|
+
});
|
|
1260
|
+
|
|
1261
|
+
// libs/auth/src/index.ts
|
|
1262
|
+
var src_exports2 = {};
|
|
1263
|
+
__export(src_exports2, {
|
|
33
1264
|
AUTH_ROLES: () => AUTH_ROLES,
|
|
34
1265
|
AuthAccountCollection: () => AuthAccountCollection,
|
|
35
1266
|
AuthApiKeysCollection: () => AuthApiKeysCollection,
|
|
@@ -47,7 +1278,7 @@ __export(src_exports, {
|
|
|
47
1278
|
getVerificationEmail: () => getVerificationEmail,
|
|
48
1279
|
momentumAuth: () => momentumAuth
|
|
49
1280
|
});
|
|
50
|
-
module.exports = __toCommonJS(
|
|
1281
|
+
module.exports = __toCommonJS(src_exports2);
|
|
51
1282
|
|
|
52
1283
|
// libs/auth/src/lib/auth-core.ts
|
|
53
1284
|
var AUTH_ROLES = [
|
|
@@ -59,7 +1290,6 @@ var AUTH_ROLES = [
|
|
|
59
1290
|
|
|
60
1291
|
// libs/auth/src/lib/auth.ts
|
|
61
1292
|
var import_better_auth = require("better-auth");
|
|
62
|
-
var import_plugins = require("better-auth/plugins");
|
|
63
1293
|
|
|
64
1294
|
// libs/auth/src/lib/email.ts
|
|
65
1295
|
var nodemailer = __toESM(require("nodemailer"));
|
|
@@ -117,48 +1347,27 @@ function createEmailService(config) {
|
|
|
117
1347
|
}
|
|
118
1348
|
|
|
119
1349
|
// libs/auth/src/lib/email-templates.ts
|
|
120
|
-
function
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
<td style="padding: 40px 20px;">
|
|
136
|
-
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="max-width: 480px; margin: 0 auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1);">
|
|
137
|
-
<tr>
|
|
138
|
-
<td style="padding: 40px;">
|
|
139
|
-
${content}
|
|
140
|
-
</td>
|
|
141
|
-
</tr>
|
|
142
|
-
</table>
|
|
143
|
-
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="max-width: 480px; margin: 20px auto 0;">
|
|
144
|
-
<tr>
|
|
145
|
-
<td style="text-align: center; color: #71717a; font-size: 12px;">
|
|
146
|
-
<p style="margin: 0;">© ${(/* @__PURE__ */ new Date()).getFullYear()} ${safeAppName}. All rights reserved.</p>
|
|
147
|
-
</td>
|
|
148
|
-
</tr>
|
|
149
|
-
</table>
|
|
150
|
-
</td>
|
|
151
|
-
</tr>
|
|
152
|
-
</table>
|
|
153
|
-
</body>
|
|
154
|
-
</html>
|
|
155
|
-
`.trim();
|
|
1350
|
+
async function renderFromDbTemplate(template, variables, defaultSubject, defaultText) {
|
|
1351
|
+
if (!template.emailBlocks || !Array.isArray(template.emailBlocks) || template.emailBlocks.length === 0) {
|
|
1352
|
+
return null;
|
|
1353
|
+
}
|
|
1354
|
+
const { renderEmailFromBlocks: renderEmailFromBlocks2, replaceVariables: replaceVariables2, blocksToPlainText: blocksToPlainText2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
1355
|
+
const subject = template.subject ? replaceVariables2(template.subject, variables) : defaultSubject;
|
|
1356
|
+
const blocks2 = template.emailBlocks;
|
|
1357
|
+
const html = renderEmailFromBlocks2(
|
|
1358
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- DB blocks stored as unknown[], narrowed by array check above
|
|
1359
|
+
{ blocks: blocks2 },
|
|
1360
|
+
{ variables }
|
|
1361
|
+
);
|
|
1362
|
+
const generatedText = blocksToPlainText2(blocks2);
|
|
1363
|
+
const text2 = generatedText ? replaceVariables2(generatedText, variables) : defaultText;
|
|
1364
|
+
return { subject, text: text2, html };
|
|
156
1365
|
}
|
|
157
|
-
function getPasswordResetEmail(options) {
|
|
1366
|
+
async function getPasswordResetEmail(options) {
|
|
158
1367
|
const { name, url, appName = "Momentum CMS", expiresIn = "1 hour" } = options;
|
|
159
1368
|
const greeting = name ? `Hi ${name},` : "Hi,";
|
|
160
|
-
const
|
|
161
|
-
const
|
|
1369
|
+
const defaultSubject = `Reset your password - ${appName}`;
|
|
1370
|
+
const defaultText = `
|
|
162
1371
|
${greeting}
|
|
163
1372
|
|
|
164
1373
|
We received a request to reset your password. Click the link below to choose a new password:
|
|
@@ -172,37 +1381,33 @@ If you didn't request a password reset, you can safely ignore this email. Your p
|
|
|
172
1381
|
Thanks,
|
|
173
1382
|
The ${appName} Team
|
|
174
1383
|
`.trim();
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
`,
|
|
197
|
-
safeAppName
|
|
198
|
-
);
|
|
199
|
-
return { subject, text: text2, html };
|
|
1384
|
+
if (options.findEmailTemplate) {
|
|
1385
|
+
try {
|
|
1386
|
+
const template = await options.findEmailTemplate("password-reset");
|
|
1387
|
+
if (template) {
|
|
1388
|
+
const variables = { greeting, url, appName, expiresIn };
|
|
1389
|
+
const result = await renderFromDbTemplate(template, variables, defaultSubject, defaultText);
|
|
1390
|
+
if (result)
|
|
1391
|
+
return result;
|
|
1392
|
+
}
|
|
1393
|
+
} catch (error) {
|
|
1394
|
+
console.warn(
|
|
1395
|
+
"[momentum:email] Failed to render DB template for password-reset, falling back to SSR:",
|
|
1396
|
+
error
|
|
1397
|
+
);
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
const { renderEmail: renderEmail2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
1401
|
+
const { PasswordResetEmailComponent: PasswordResetEmailComponent2 } = await Promise.resolve().then(() => (init_password_reset_email_component(), password_reset_email_component_exports));
|
|
1402
|
+
const data = { name, url, appName, expiresIn };
|
|
1403
|
+
const html = await renderEmail2(PasswordResetEmailComponent2, data);
|
|
1404
|
+
return { subject: defaultSubject, text: defaultText, html };
|
|
200
1405
|
}
|
|
201
|
-
function getVerificationEmail(options) {
|
|
1406
|
+
async function getVerificationEmail(options) {
|
|
202
1407
|
const { name, url, appName = "Momentum CMS", expiresIn = "24 hours" } = options;
|
|
203
1408
|
const greeting = name ? `Hi ${name},` : "Hi,";
|
|
204
|
-
const
|
|
205
|
-
const
|
|
1409
|
+
const defaultSubject = `Verify your email - ${appName}`;
|
|
1410
|
+
const defaultText = `
|
|
206
1411
|
${greeting}
|
|
207
1412
|
|
|
208
1413
|
Welcome to ${appName}! Please verify your email address by clicking the link below:
|
|
@@ -216,31 +1421,27 @@ If you didn't create an account, you can safely ignore this email.
|
|
|
216
1421
|
Thanks,
|
|
217
1422
|
The ${appName} Team
|
|
218
1423
|
`.trim();
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
`,
|
|
241
|
-
safeAppName
|
|
242
|
-
);
|
|
243
|
-
return { subject, text: text2, html };
|
|
1424
|
+
if (options.findEmailTemplate) {
|
|
1425
|
+
try {
|
|
1426
|
+
const template = await options.findEmailTemplate("verification");
|
|
1427
|
+
if (template) {
|
|
1428
|
+
const variables = { greeting, url, appName, expiresIn };
|
|
1429
|
+
const result = await renderFromDbTemplate(template, variables, defaultSubject, defaultText);
|
|
1430
|
+
if (result)
|
|
1431
|
+
return result;
|
|
1432
|
+
}
|
|
1433
|
+
} catch (error) {
|
|
1434
|
+
console.warn(
|
|
1435
|
+
"[momentum:email] Failed to render DB template for verification, falling back to SSR:",
|
|
1436
|
+
error
|
|
1437
|
+
);
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
const { renderEmail: renderEmail2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
1441
|
+
const { VerificationEmailComponent: VerificationEmailComponent2 } = await Promise.resolve().then(() => (init_verification_email_component(), verification_email_component_exports));
|
|
1442
|
+
const data = { name, url, appName, expiresIn };
|
|
1443
|
+
const html = await renderEmail2(VerificationEmailComponent2, data);
|
|
1444
|
+
return { subject: defaultSubject, text: defaultText, html };
|
|
244
1445
|
}
|
|
245
1446
|
|
|
246
1447
|
// libs/logger/src/lib/log-level.ts
|
|
@@ -540,14 +1741,7 @@ function convertFieldsToAdditionalFields(fields) {
|
|
|
540
1741
|
}
|
|
541
1742
|
function createMomentumAuth(config) {
|
|
542
1743
|
const dbConfig = isLegacyConfig(config) ? { type: "sqlite", database: config.database } : config.db;
|
|
543
|
-
const {
|
|
544
|
-
baseURL,
|
|
545
|
-
secret,
|
|
546
|
-
trustedOrigins,
|
|
547
|
-
email: emailConfig,
|
|
548
|
-
socialProviders,
|
|
549
|
-
twoFactorAuth
|
|
550
|
-
} = config;
|
|
1744
|
+
const { baseURL, secret, trustedOrigins, email: emailConfig, socialProviders } = config;
|
|
551
1745
|
const extraPlugins = !isLegacyConfig(config) ? config.plugins ?? [] : [];
|
|
552
1746
|
const extraUserFields = !isLegacyConfig(config) ? config.userFields ?? [] : [];
|
|
553
1747
|
const databaseOption = dbConfig.type === "sqlite" ? dbConfig.database : dbConfig.pool;
|
|
@@ -563,11 +1757,12 @@ function createMomentumAuth(config) {
|
|
|
563
1757
|
};
|
|
564
1758
|
if (emailService) {
|
|
565
1759
|
emailAndPasswordConfig.sendResetPassword = async ({ user, url }) => {
|
|
566
|
-
const { subject, text: text2, html } = getPasswordResetEmail({
|
|
1760
|
+
const { subject, text: text2, html } = await getPasswordResetEmail({
|
|
567
1761
|
name: user.name,
|
|
568
1762
|
url,
|
|
569
1763
|
appName,
|
|
570
|
-
expiresIn: "1 hour"
|
|
1764
|
+
expiresIn: "1 hour",
|
|
1765
|
+
findEmailTemplate: emailConfig?.findEmailTemplate
|
|
571
1766
|
});
|
|
572
1767
|
emailService.sendEmail({
|
|
573
1768
|
to: user.email,
|
|
@@ -591,11 +1786,12 @@ function createMomentumAuth(config) {
|
|
|
591
1786
|
user,
|
|
592
1787
|
url
|
|
593
1788
|
}) => {
|
|
594
|
-
const { subject, text: text2, html } = getVerificationEmail({
|
|
1789
|
+
const { subject, text: text2, html } = await getVerificationEmail({
|
|
595
1790
|
name: user.name,
|
|
596
1791
|
url,
|
|
597
1792
|
appName,
|
|
598
|
-
expiresIn: "24 hours"
|
|
1793
|
+
expiresIn: "24 hours",
|
|
1794
|
+
findEmailTemplate: emailConfig?.findEmailTemplate
|
|
599
1795
|
});
|
|
600
1796
|
emailService.sendEmail({
|
|
601
1797
|
to: user.email,
|
|
@@ -614,9 +1810,6 @@ function createMomentumAuth(config) {
|
|
|
614
1810
|
}
|
|
615
1811
|
const socialProvidersConfig = buildSocialProviders(socialProviders, baseURL);
|
|
616
1812
|
const plugins = [];
|
|
617
|
-
if (twoFactorAuth) {
|
|
618
|
-
plugins.push((0, import_plugins.twoFactor)());
|
|
619
|
-
}
|
|
620
1813
|
for (const p of extraPlugins) {
|
|
621
1814
|
if (p !== void 0) {
|
|
622
1815
|
plugins.push(p);
|
|
@@ -1068,7 +2261,7 @@ function momentumAuth(config) {
|
|
|
1068
2261
|
}
|
|
1069
2262
|
|
|
1070
2263
|
// libs/auth/src/lib/plugins/two-factor.ts
|
|
1071
|
-
var
|
|
2264
|
+
var import_plugins = require("better-auth/plugins");
|
|
1072
2265
|
var AuthTwoFactorCollection = defineCollection({
|
|
1073
2266
|
slug: "auth-two-factor",
|
|
1074
2267
|
dbName: "twoFactor",
|
|
@@ -1095,24 +2288,25 @@ var AuthTwoFactorCollection = defineCollection({
|
|
|
1095
2288
|
function authTwoFactor() {
|
|
1096
2289
|
return {
|
|
1097
2290
|
name: "two-factor",
|
|
1098
|
-
betterAuthPlugin: (0,
|
|
2291
|
+
betterAuthPlugin: (0, import_plugins.twoFactor)(),
|
|
1099
2292
|
collections: [AuthTwoFactorCollection],
|
|
1100
2293
|
userFields: [checkbox("twoFactorEnabled")]
|
|
1101
2294
|
};
|
|
1102
2295
|
}
|
|
1103
2296
|
|
|
1104
2297
|
// libs/auth/src/lib/plugins/admin.ts
|
|
2298
|
+
var import_plugins2 = require("better-auth/plugins");
|
|
1105
2299
|
function authAdmin() {
|
|
1106
2300
|
return {
|
|
1107
2301
|
name: "admin",
|
|
1108
|
-
|
|
1109
|
-
betterAuthPlugin: void 0,
|
|
2302
|
+
betterAuthPlugin: (0, import_plugins2.admin)(),
|
|
1110
2303
|
userFields: [checkbox("banned"), text("banReason"), date("banExpires")],
|
|
1111
2304
|
sessionFields: [text("impersonatedBy")]
|
|
1112
2305
|
};
|
|
1113
2306
|
}
|
|
1114
2307
|
|
|
1115
2308
|
// libs/auth/src/lib/plugins/organization.ts
|
|
2309
|
+
var import_plugins3 = require("better-auth/plugins");
|
|
1116
2310
|
var AuthOrganizationCollection = defineCollection({
|
|
1117
2311
|
slug: "auth-organization",
|
|
1118
2312
|
dbName: "organization",
|
|
@@ -1214,8 +2408,7 @@ var AuthInvitationCollection = defineCollection({
|
|
|
1214
2408
|
function authOrganization() {
|
|
1215
2409
|
return {
|
|
1216
2410
|
name: "organization",
|
|
1217
|
-
|
|
1218
|
-
betterAuthPlugin: void 0,
|
|
2411
|
+
betterAuthPlugin: (0, import_plugins3.organization)(),
|
|
1219
2412
|
collections: [AuthOrganizationCollection, AuthMemberCollection, AuthInvitationCollection]
|
|
1220
2413
|
};
|
|
1221
2414
|
}
|