hazo_notify 1.0.2 → 1.1.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/README.md +30 -10
- package/config/hazo_logs_config.ini +21 -0
- package/{hazo_notify_config.ini → config/hazo_notify_config.ini} +39 -0
- package/data/templates/email_signature.html +11 -0
- package/data/templates/email_signature.txt +4 -0
- package/data/templates/email_verification.html +64 -0
- package/data/templates/email_verification.txt +11 -0
- package/data/templates/forgot_password.html +64 -0
- package/data/templates/forgot_password.txt +11 -0
- package/data/templates/manifest.json +86 -0
- package/data/templates/welcome_email.html +54 -0
- package/data/templates/welcome_email.txt +8 -0
- package/dist/emailer/emailer.d.ts +3 -3
- package/dist/emailer/emailer.d.ts.map +1 -1
- package/dist/emailer/emailer.js +25 -15
- package/dist/emailer/emailer.js.map +1 -1
- package/dist/emailer/index.d.ts +1 -0
- package/dist/emailer/index.d.ts.map +1 -1
- package/dist/emailer/index.js +5 -1
- package/dist/emailer/index.js.map +1 -1
- package/dist/emailer/providers/pop3_provider.d.ts +3 -2
- package/dist/emailer/providers/pop3_provider.d.ts.map +1 -1
- package/dist/emailer/providers/pop3_provider.js +2 -1
- package/dist/emailer/providers/pop3_provider.js.map +1 -1
- package/dist/emailer/providers/smtp_provider.d.ts +3 -2
- package/dist/emailer/providers/smtp_provider.d.ts.map +1 -1
- package/dist/emailer/providers/smtp_provider.js +2 -1
- package/dist/emailer/providers/smtp_provider.js.map +1 -1
- package/dist/emailer/providers/zeptomail_provider.d.ts +3 -2
- package/dist/emailer/providers/zeptomail_provider.d.ts.map +1 -1
- package/dist/emailer/providers/zeptomail_provider.js +24 -11
- package/dist/emailer/providers/zeptomail_provider.js.map +1 -1
- package/dist/emailer/types.d.ts +13 -1
- package/dist/emailer/types.d.ts.map +1 -1
- package/dist/emailer/utils/logger.d.ts +22 -14
- package/dist/emailer/utils/logger.d.ts.map +1 -1
- package/dist/emailer/utils/logger.js +51 -13
- package/dist/emailer/utils/logger.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/template_manager/config/config_loader.d.ts +48 -0
- package/dist/template_manager/config/config_loader.d.ts.map +1 -0
- package/dist/template_manager/config/config_loader.js +161 -0
- package/dist/template_manager/config/config_loader.js.map +1 -0
- package/dist/template_manager/config/constants.d.ts +101 -0
- package/dist/template_manager/config/constants.d.ts.map +1 -0
- package/dist/template_manager/config/constants.js +163 -0
- package/dist/template_manager/config/constants.js.map +1 -0
- package/dist/template_manager/config/index.d.ts +6 -0
- package/dist/template_manager/config/index.d.ts.map +1 -0
- package/dist/{lib/emailer/utils → template_manager/config}/index.js +4 -4
- package/dist/template_manager/config/index.js.map +1 -0
- package/dist/template_manager/db/category_repository.d.ts +57 -0
- package/dist/template_manager/db/category_repository.d.ts.map +1 -0
- package/dist/template_manager/db/category_repository.js +326 -0
- package/dist/template_manager/db/category_repository.js.map +1 -0
- package/dist/template_manager/db/index.d.ts +6 -0
- package/dist/template_manager/db/index.d.ts.map +1 -0
- package/dist/template_manager/db/index.js +23 -0
- package/dist/template_manager/db/index.js.map +1 -0
- package/dist/template_manager/db/template_repository.d.ts +76 -0
- package/dist/template_manager/db/template_repository.d.ts.map +1 -0
- package/dist/template_manager/db/template_repository.js +684 -0
- package/dist/template_manager/db/template_repository.js.map +1 -0
- package/dist/template_manager/engine/handlebars_engine.d.ts +52 -0
- package/dist/template_manager/engine/handlebars_engine.d.ts.map +1 -0
- package/dist/template_manager/engine/handlebars_engine.js +175 -0
- package/dist/template_manager/engine/handlebars_engine.js.map +1 -0
- package/dist/template_manager/engine/index.d.ts +6 -0
- package/dist/template_manager/engine/index.d.ts.map +1 -0
- package/dist/template_manager/engine/index.js +19 -0
- package/dist/template_manager/engine/index.js.map +1 -0
- package/dist/template_manager/engine/variable_resolver.d.ts +48 -0
- package/dist/template_manager/engine/variable_resolver.d.ts.map +1 -0
- package/dist/template_manager/engine/variable_resolver.js +223 -0
- package/dist/template_manager/engine/variable_resolver.js.map +1 -0
- package/dist/template_manager/index.d.ts +32 -0
- package/dist/template_manager/index.d.ts.map +1 -0
- package/dist/template_manager/index.js +88 -0
- package/dist/template_manager/index.js.map +1 -0
- package/dist/template_manager/template_manager.d.ts +69 -0
- package/dist/template_manager/template_manager.d.ts.map +1 -0
- package/dist/template_manager/template_manager.js +335 -0
- package/dist/template_manager/template_manager.js.map +1 -0
- package/dist/template_manager/types.d.ts +255 -0
- package/dist/template_manager/types.d.ts.map +1 -0
- package/dist/template_manager/types.js +12 -0
- package/dist/template_manager/types.js.map +1 -0
- package/dist/template_manager/utils/index.d.ts +6 -0
- package/dist/template_manager/utils/index.d.ts.map +1 -0
- package/dist/template_manager/utils/index.js +21 -0
- package/dist/template_manager/utils/index.js.map +1 -0
- package/dist/template_manager/utils/system_variables.d.ts +28 -0
- package/dist/template_manager/utils/system_variables.d.ts.map +1 -0
- package/dist/template_manager/utils/system_variables.js +209 -0
- package/dist/template_manager/utils/system_variables.js.map +1 -0
- package/dist/template_manager/utils/validation.d.ts +74 -0
- package/dist/template_manager/utils/validation.d.ts.map +1 -0
- package/dist/template_manager/utils/validation.js +163 -0
- package/dist/template_manager/utils/validation.js.map +1 -0
- package/package.json +70 -22
- package/dist/lib/emailer/emailer.d.ts +0 -19
- package/dist/lib/emailer/emailer.d.ts.map +0 -1
- package/dist/lib/emailer/emailer.js +0 -220
- package/dist/lib/emailer/emailer.js.map +0 -1
- package/dist/lib/emailer/index.d.ts +0 -11
- package/dist/lib/emailer/index.d.ts.map +0 -1
- package/dist/lib/emailer/index.js +0 -34
- package/dist/lib/emailer/index.js.map +0 -1
- package/dist/lib/emailer/providers/index.d.ts +0 -15
- package/dist/lib/emailer/providers/index.d.ts.map +0 -1
- package/dist/lib/emailer/providers/index.js +0 -36
- package/dist/lib/emailer/providers/index.js.map +0 -1
- package/dist/lib/emailer/providers/pop3_provider.d.ts +0 -15
- package/dist/lib/emailer/providers/pop3_provider.d.ts.map +0 -1
- package/dist/lib/emailer/providers/pop3_provider.js +0 -29
- package/dist/lib/emailer/providers/pop3_provider.js.map +0 -1
- package/dist/lib/emailer/providers/smtp_provider.d.ts +0 -15
- package/dist/lib/emailer/providers/smtp_provider.d.ts.map +0 -1
- package/dist/lib/emailer/providers/smtp_provider.js +0 -29
- package/dist/lib/emailer/providers/smtp_provider.js.map +0 -1
- package/dist/lib/emailer/providers/zeptomail_provider.d.ts +0 -15
- package/dist/lib/emailer/providers/zeptomail_provider.d.ts.map +0 -1
- package/dist/lib/emailer/providers/zeptomail_provider.js +0 -250
- package/dist/lib/emailer/providers/zeptomail_provider.js.map +0 -1
- package/dist/lib/emailer/types.d.ts +0 -94
- package/dist/lib/emailer/types.d.ts.map +0 -1
- package/dist/lib/emailer/types.js +0 -6
- package/dist/lib/emailer/types.js.map +0 -1
- package/dist/lib/emailer/utils/constants.d.ts +0 -14
- package/dist/lib/emailer/utils/constants.d.ts.map +0 -1
- package/dist/lib/emailer/utils/constants.js +0 -22
- package/dist/lib/emailer/utils/constants.js.map +0 -1
- package/dist/lib/emailer/utils/index.d.ts +0 -8
- package/dist/lib/emailer/utils/index.d.ts.map +0 -1
- package/dist/lib/emailer/utils/index.js.map +0 -1
- package/dist/lib/emailer/utils/logger.d.ts +0 -37
- package/dist/lib/emailer/utils/logger.d.ts.map +0 -1
- package/dist/lib/emailer/utils/logger.js +0 -60
- package/dist/lib/emailer/utils/logger.js.map +0 -1
- package/dist/lib/emailer/utils/validation.d.ts +0 -37
- package/dist/lib/emailer/utils/validation.d.ts.map +0 -1
- package/dist/lib/emailer/utils/validation.js +0 -81
- package/dist/lib/emailer/utils/validation.js.map +0 -1
- package/dist/lib/index.d.ts +0 -6
- package/dist/lib/index.d.ts.map +0 -1
- package/dist/lib/index.js +0 -22
- package/dist/lib/index.js.map +0 -1
- package/dist/lib/utils.d.ts +0 -3
- package/dist/lib/utils.d.ts.map +0 -1
- package/dist/lib/utils.js +0 -9
- package/dist/lib/utils.js.map +0 -1
|
@@ -0,0 +1,684 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Template repository for template manager
|
|
4
|
+
*
|
|
5
|
+
* CRUD operations for email templates using hazo_connect
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.list_templates = list_templates;
|
|
9
|
+
exports.list_templates_by_category = list_templates_by_category;
|
|
10
|
+
exports.get_template = get_template;
|
|
11
|
+
exports.get_template_by_name = get_template_by_name;
|
|
12
|
+
exports.create_template = create_template;
|
|
13
|
+
exports.update_template = update_template;
|
|
14
|
+
exports.delete_template = delete_template;
|
|
15
|
+
exports.seed_default_templates = seed_default_templates;
|
|
16
|
+
const constants_1 = require("../config/constants");
|
|
17
|
+
const validation_1 = require("../utils/validation");
|
|
18
|
+
const category_repository_1 = require("./category_repository");
|
|
19
|
+
/**
|
|
20
|
+
* List all email templates for an organization
|
|
21
|
+
*
|
|
22
|
+
* @param hazo_connect - Database connection instance
|
|
23
|
+
* @param org_id - Organization ID
|
|
24
|
+
* @returns Response with array of templates
|
|
25
|
+
*/
|
|
26
|
+
async function list_templates(hazo_connect, org_id) {
|
|
27
|
+
try {
|
|
28
|
+
if (!hazo_connect) {
|
|
29
|
+
return {
|
|
30
|
+
success: false,
|
|
31
|
+
error: constants_1.ERROR_MESSAGES.DB_CONNECTION_REQUIRED,
|
|
32
|
+
message: constants_1.ERROR_MESSAGES.DB_CONNECTION_REQUIRED,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
if (!(0, validation_1.validate_uuid)(org_id)) {
|
|
36
|
+
return {
|
|
37
|
+
success: false,
|
|
38
|
+
error: 'Invalid organization ID',
|
|
39
|
+
message: 'Invalid organization ID format',
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const query = hazo_connect
|
|
43
|
+
.query()
|
|
44
|
+
.from(constants_1.TABLE_TEMPLATES)
|
|
45
|
+
.select('*')
|
|
46
|
+
.where('org_id', 'eq', org_id)
|
|
47
|
+
.order('template_name', 'asc');
|
|
48
|
+
const templates = await hazo_connect.list(query);
|
|
49
|
+
return {
|
|
50
|
+
success: true,
|
|
51
|
+
data: templates,
|
|
52
|
+
message: `Found ${templates.length} templates`,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
const error_message = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
57
|
+
return {
|
|
58
|
+
success: false,
|
|
59
|
+
error: error_message,
|
|
60
|
+
message: `Failed to list templates: ${error_message}`,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* List templates by category
|
|
66
|
+
*
|
|
67
|
+
* @param hazo_connect - Database connection instance
|
|
68
|
+
* @param category_id - Category ID
|
|
69
|
+
* @returns Response with array of templates
|
|
70
|
+
*/
|
|
71
|
+
async function list_templates_by_category(hazo_connect, category_id) {
|
|
72
|
+
try {
|
|
73
|
+
if (!hazo_connect) {
|
|
74
|
+
return {
|
|
75
|
+
success: false,
|
|
76
|
+
error: constants_1.ERROR_MESSAGES.DB_CONNECTION_REQUIRED,
|
|
77
|
+
message: constants_1.ERROR_MESSAGES.DB_CONNECTION_REQUIRED,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
if (!(0, validation_1.validate_uuid)(category_id)) {
|
|
81
|
+
return {
|
|
82
|
+
success: false,
|
|
83
|
+
error: 'Invalid category ID',
|
|
84
|
+
message: 'Invalid category ID format',
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const query = hazo_connect
|
|
88
|
+
.query()
|
|
89
|
+
.from(constants_1.TABLE_TEMPLATES)
|
|
90
|
+
.select('*')
|
|
91
|
+
.where('template_category_id', 'eq', category_id)
|
|
92
|
+
.order('template_name', 'asc');
|
|
93
|
+
const templates = await hazo_connect.list(query);
|
|
94
|
+
return {
|
|
95
|
+
success: true,
|
|
96
|
+
data: templates,
|
|
97
|
+
message: `Found ${templates.length} templates in category`,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
const error_message = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
102
|
+
return {
|
|
103
|
+
success: false,
|
|
104
|
+
error: error_message,
|
|
105
|
+
message: `Failed to list templates: ${error_message}`,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get a single email template by ID
|
|
111
|
+
*
|
|
112
|
+
* @param hazo_connect - Database connection instance
|
|
113
|
+
* @param id - Template ID
|
|
114
|
+
* @returns Response with template data
|
|
115
|
+
*/
|
|
116
|
+
async function get_template(hazo_connect, id) {
|
|
117
|
+
try {
|
|
118
|
+
if (!hazo_connect) {
|
|
119
|
+
return {
|
|
120
|
+
success: false,
|
|
121
|
+
error: constants_1.ERROR_MESSAGES.DB_CONNECTION_REQUIRED,
|
|
122
|
+
message: constants_1.ERROR_MESSAGES.DB_CONNECTION_REQUIRED,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
if (!(0, validation_1.validate_uuid)(id)) {
|
|
126
|
+
return {
|
|
127
|
+
success: false,
|
|
128
|
+
error: 'Invalid template ID',
|
|
129
|
+
message: 'Invalid template ID format',
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
const template = await hazo_connect.findById(constants_1.TABLE_TEMPLATES, id);
|
|
133
|
+
if (!template) {
|
|
134
|
+
return {
|
|
135
|
+
success: false,
|
|
136
|
+
error: constants_1.ERROR_MESSAGES.TEMPLATE_NOT_FOUND,
|
|
137
|
+
message: constants_1.ERROR_MESSAGES.TEMPLATE_NOT_FOUND,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
success: true,
|
|
142
|
+
data: template,
|
|
143
|
+
message: 'Template found',
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
const error_message = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
148
|
+
return {
|
|
149
|
+
success: false,
|
|
150
|
+
error: error_message,
|
|
151
|
+
message: `Failed to get template: ${error_message}`,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Get a template by name within an organization
|
|
157
|
+
*
|
|
158
|
+
* @param hazo_connect - Database connection instance
|
|
159
|
+
* @param org_id - Organization ID
|
|
160
|
+
* @param template_name - Template name
|
|
161
|
+
* @returns Response with template if found
|
|
162
|
+
*/
|
|
163
|
+
async function get_template_by_name(hazo_connect, org_id, template_name) {
|
|
164
|
+
try {
|
|
165
|
+
if (!hazo_connect) {
|
|
166
|
+
return {
|
|
167
|
+
success: false,
|
|
168
|
+
error: constants_1.ERROR_MESSAGES.DB_CONNECTION_REQUIRED,
|
|
169
|
+
message: constants_1.ERROR_MESSAGES.DB_CONNECTION_REQUIRED,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
if (!(0, validation_1.validate_uuid)(org_id)) {
|
|
173
|
+
return {
|
|
174
|
+
success: false,
|
|
175
|
+
error: 'Invalid organization ID',
|
|
176
|
+
message: 'Invalid organization ID format',
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
const query = hazo_connect
|
|
180
|
+
.query()
|
|
181
|
+
.from(constants_1.TABLE_TEMPLATES)
|
|
182
|
+
.select('*')
|
|
183
|
+
.where('org_id', 'eq', org_id)
|
|
184
|
+
.where('template_name', 'eq', template_name);
|
|
185
|
+
const templates = await hazo_connect.list(query);
|
|
186
|
+
if (templates.length === 0) {
|
|
187
|
+
return {
|
|
188
|
+
success: false,
|
|
189
|
+
error: constants_1.ERROR_MESSAGES.TEMPLATE_NOT_FOUND,
|
|
190
|
+
message: `Template '${template_name}' not found`,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
success: true,
|
|
195
|
+
data: templates[0],
|
|
196
|
+
message: 'Template found',
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
const error_message = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
201
|
+
return {
|
|
202
|
+
success: false,
|
|
203
|
+
error: error_message,
|
|
204
|
+
message: `Failed to get template: ${error_message}`,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Create a new email template
|
|
210
|
+
*
|
|
211
|
+
* @param hazo_connect - Database connection instance
|
|
212
|
+
* @param data - Template input data
|
|
213
|
+
* @returns Response with created template
|
|
214
|
+
*/
|
|
215
|
+
async function create_template(hazo_connect, data) {
|
|
216
|
+
try {
|
|
217
|
+
if (!hazo_connect) {
|
|
218
|
+
return {
|
|
219
|
+
success: false,
|
|
220
|
+
error: constants_1.ERROR_MESSAGES.DB_CONNECTION_REQUIRED,
|
|
221
|
+
message: constants_1.ERROR_MESSAGES.DB_CONNECTION_REQUIRED,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
if (!(0, validation_1.validate_template_name)(data.template_name)) {
|
|
225
|
+
return {
|
|
226
|
+
success: false,
|
|
227
|
+
error: constants_1.ERROR_MESSAGES.INVALID_TEMPLATE_NAME,
|
|
228
|
+
message: constants_1.ERROR_MESSAGES.INVALID_TEMPLATE_NAME,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
if (!(0, validation_1.validate_uuid)(data.org_id)) {
|
|
232
|
+
return {
|
|
233
|
+
success: false,
|
|
234
|
+
error: 'Invalid organization ID',
|
|
235
|
+
message: 'Invalid organization ID format',
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
if (!(0, validation_1.validate_uuid)(data.root_org_id)) {
|
|
239
|
+
return {
|
|
240
|
+
success: false,
|
|
241
|
+
error: 'Invalid root organization ID',
|
|
242
|
+
message: 'Invalid root organization ID format',
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
if (!(0, validation_1.validate_uuid)(data.template_category_id)) {
|
|
246
|
+
return {
|
|
247
|
+
success: false,
|
|
248
|
+
error: 'Invalid category ID',
|
|
249
|
+
message: 'Invalid category ID format',
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
if (!(0, validation_1.validate_template_html_size)(data.template_html)) {
|
|
253
|
+
return {
|
|
254
|
+
success: false,
|
|
255
|
+
error: constants_1.ERROR_MESSAGES.TEMPLATE_HTML_TOO_LARGE,
|
|
256
|
+
message: constants_1.ERROR_MESSAGES.TEMPLATE_HTML_TOO_LARGE,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
if (!(0, validation_1.validate_template_text_size)(data.template_text)) {
|
|
260
|
+
return {
|
|
261
|
+
success: false,
|
|
262
|
+
error: constants_1.ERROR_MESSAGES.TEMPLATE_TEXT_TOO_LARGE,
|
|
263
|
+
message: constants_1.ERROR_MESSAGES.TEMPLATE_TEXT_TOO_LARGE,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
// Check if category exists
|
|
267
|
+
const category = await hazo_connect.findById(constants_1.TABLE_TEMPLATE_CATEGORY, data.template_category_id);
|
|
268
|
+
if (!category) {
|
|
269
|
+
return {
|
|
270
|
+
success: false,
|
|
271
|
+
error: constants_1.ERROR_MESSAGES.CATEGORY_NOT_FOUND,
|
|
272
|
+
message: 'Template category does not exist',
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
const template = await hazo_connect.insert(constants_1.TABLE_TEMPLATES, {
|
|
276
|
+
org_id: data.org_id,
|
|
277
|
+
root_org_id: data.root_org_id,
|
|
278
|
+
template_category_id: data.template_category_id,
|
|
279
|
+
template_variables: data.template_variables || {},
|
|
280
|
+
template_name: data.template_name.trim(),
|
|
281
|
+
template_html: data.template_html,
|
|
282
|
+
template_text: data.template_text,
|
|
283
|
+
email_type: data.email_type || 'user',
|
|
284
|
+
});
|
|
285
|
+
return {
|
|
286
|
+
success: true,
|
|
287
|
+
data: template,
|
|
288
|
+
message: 'Template created successfully',
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
const error_message = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
293
|
+
return {
|
|
294
|
+
success: false,
|
|
295
|
+
error: error_message,
|
|
296
|
+
message: `Failed to create template: ${error_message}`,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Update an existing email template
|
|
302
|
+
*
|
|
303
|
+
* @param hazo_connect - Database connection instance
|
|
304
|
+
* @param id - Template ID
|
|
305
|
+
* @param data - Update data
|
|
306
|
+
* @returns Response with updated template
|
|
307
|
+
*/
|
|
308
|
+
async function update_template(hazo_connect, id, data) {
|
|
309
|
+
try {
|
|
310
|
+
if (!hazo_connect) {
|
|
311
|
+
return {
|
|
312
|
+
success: false,
|
|
313
|
+
error: constants_1.ERROR_MESSAGES.DB_CONNECTION_REQUIRED,
|
|
314
|
+
message: constants_1.ERROR_MESSAGES.DB_CONNECTION_REQUIRED,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
if (!(0, validation_1.validate_uuid)(id)) {
|
|
318
|
+
return {
|
|
319
|
+
success: false,
|
|
320
|
+
error: 'Invalid template ID',
|
|
321
|
+
message: 'Invalid template ID format',
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
// Check if template exists
|
|
325
|
+
const existing = await hazo_connect.findById(constants_1.TABLE_TEMPLATES, id);
|
|
326
|
+
if (!existing) {
|
|
327
|
+
return {
|
|
328
|
+
success: false,
|
|
329
|
+
error: constants_1.ERROR_MESSAGES.TEMPLATE_NOT_FOUND,
|
|
330
|
+
message: constants_1.ERROR_MESSAGES.TEMPLATE_NOT_FOUND,
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
// Validate update data
|
|
334
|
+
if (data.template_name !== undefined &&
|
|
335
|
+
!(0, validation_1.validate_template_name)(data.template_name)) {
|
|
336
|
+
return {
|
|
337
|
+
success: false,
|
|
338
|
+
error: constants_1.ERROR_MESSAGES.INVALID_TEMPLATE_NAME,
|
|
339
|
+
message: constants_1.ERROR_MESSAGES.INVALID_TEMPLATE_NAME,
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
if (data.template_category_id !== undefined &&
|
|
343
|
+
!(0, validation_1.validate_uuid)(data.template_category_id)) {
|
|
344
|
+
return {
|
|
345
|
+
success: false,
|
|
346
|
+
error: 'Invalid category ID',
|
|
347
|
+
message: 'Invalid category ID format',
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
if (data.template_html !== undefined &&
|
|
351
|
+
!(0, validation_1.validate_template_html_size)(data.template_html)) {
|
|
352
|
+
return {
|
|
353
|
+
success: false,
|
|
354
|
+
error: constants_1.ERROR_MESSAGES.TEMPLATE_HTML_TOO_LARGE,
|
|
355
|
+
message: constants_1.ERROR_MESSAGES.TEMPLATE_HTML_TOO_LARGE,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
if (data.template_text !== undefined &&
|
|
359
|
+
!(0, validation_1.validate_template_text_size)(data.template_text)) {
|
|
360
|
+
return {
|
|
361
|
+
success: false,
|
|
362
|
+
error: constants_1.ERROR_MESSAGES.TEMPLATE_TEXT_TOO_LARGE,
|
|
363
|
+
message: constants_1.ERROR_MESSAGES.TEMPLATE_TEXT_TOO_LARGE,
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
const update_data = {
|
|
367
|
+
changed_at: new Date().toISOString(),
|
|
368
|
+
};
|
|
369
|
+
if (data.template_name !== undefined) {
|
|
370
|
+
update_data.template_name = data.template_name.trim();
|
|
371
|
+
}
|
|
372
|
+
if (data.template_category_id !== undefined) {
|
|
373
|
+
update_data.template_category_id = data.template_category_id;
|
|
374
|
+
}
|
|
375
|
+
if (data.template_variables !== undefined) {
|
|
376
|
+
update_data.template_variables = data.template_variables;
|
|
377
|
+
}
|
|
378
|
+
if (data.template_html !== undefined) {
|
|
379
|
+
update_data.template_html = data.template_html;
|
|
380
|
+
}
|
|
381
|
+
if (data.template_text !== undefined) {
|
|
382
|
+
update_data.template_text = data.template_text;
|
|
383
|
+
}
|
|
384
|
+
const template = await hazo_connect.updateById(constants_1.TABLE_TEMPLATES, id, update_data);
|
|
385
|
+
return {
|
|
386
|
+
success: true,
|
|
387
|
+
data: template,
|
|
388
|
+
message: 'Template updated successfully',
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
catch (error) {
|
|
392
|
+
const error_message = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
393
|
+
return {
|
|
394
|
+
success: false,
|
|
395
|
+
error: error_message,
|
|
396
|
+
message: `Failed to update template: ${error_message}`,
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Delete an email template
|
|
402
|
+
*
|
|
403
|
+
* @param hazo_connect - Database connection instance
|
|
404
|
+
* @param id - Template ID
|
|
405
|
+
* @returns Response with deletion result
|
|
406
|
+
*/
|
|
407
|
+
async function delete_template(hazo_connect, id) {
|
|
408
|
+
try {
|
|
409
|
+
if (!hazo_connect) {
|
|
410
|
+
return {
|
|
411
|
+
success: false,
|
|
412
|
+
error: constants_1.ERROR_MESSAGES.DB_CONNECTION_REQUIRED,
|
|
413
|
+
message: constants_1.ERROR_MESSAGES.DB_CONNECTION_REQUIRED,
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
if (!(0, validation_1.validate_uuid)(id)) {
|
|
417
|
+
return {
|
|
418
|
+
success: false,
|
|
419
|
+
error: 'Invalid template ID',
|
|
420
|
+
message: 'Invalid template ID format',
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
// Check if template exists
|
|
424
|
+
const existing = await hazo_connect.findById(constants_1.TABLE_TEMPLATES, id);
|
|
425
|
+
if (!existing) {
|
|
426
|
+
return {
|
|
427
|
+
success: false,
|
|
428
|
+
error: constants_1.ERROR_MESSAGES.TEMPLATE_NOT_FOUND,
|
|
429
|
+
message: constants_1.ERROR_MESSAGES.TEMPLATE_NOT_FOUND,
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
// Cannot delete system templates
|
|
433
|
+
if (existing.email_type === 'system') {
|
|
434
|
+
return {
|
|
435
|
+
success: false,
|
|
436
|
+
error: constants_1.ERROR_MESSAGES.CANNOT_DELETE_SYSTEM_TEMPLATE,
|
|
437
|
+
message: constants_1.ERROR_MESSAGES.CANNOT_DELETE_SYSTEM_TEMPLATE,
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
await hazo_connect.deleteById(constants_1.TABLE_TEMPLATES, id);
|
|
441
|
+
return {
|
|
442
|
+
success: true,
|
|
443
|
+
data: true,
|
|
444
|
+
message: 'Template deleted successfully',
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
catch (error) {
|
|
448
|
+
const error_message = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
449
|
+
return {
|
|
450
|
+
success: false,
|
|
451
|
+
error: error_message,
|
|
452
|
+
message: `Failed to delete template: ${error_message}`,
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
const DEFAULT_TEMPLATES = [
|
|
457
|
+
{
|
|
458
|
+
template_name: 'welcome_email',
|
|
459
|
+
template_html: `<!DOCTYPE html>
|
|
460
|
+
<html>
|
|
461
|
+
<head>
|
|
462
|
+
<meta charset="utf-8">
|
|
463
|
+
<title>Welcome</title>
|
|
464
|
+
</head>
|
|
465
|
+
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
|
|
466
|
+
<div style="max-width: 600px; margin: 0 auto; padding: 20px;">
|
|
467
|
+
<h1 style="color: #2563eb;">Welcome, {{user_name}}!</h1>
|
|
468
|
+
<p>Thank you for joining us. We're excited to have you on board.</p>
|
|
469
|
+
<p>To get started, please visit your account:</p>
|
|
470
|
+
<p style="margin: 20px 0;">
|
|
471
|
+
<a href="{{login_url}}" style="background-color: #2563eb; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px;">
|
|
472
|
+
Login to Your Account
|
|
473
|
+
</a>
|
|
474
|
+
</p>
|
|
475
|
+
<p>If you have any questions, feel free to reach out to our support team.</p>
|
|
476
|
+
<p>Best regards,<br>The Team</p>
|
|
477
|
+
</div>
|
|
478
|
+
</body>
|
|
479
|
+
</html>`,
|
|
480
|
+
template_text: `Welcome, {{user_name}}!
|
|
481
|
+
|
|
482
|
+
Thank you for joining us. We're excited to have you on board.
|
|
483
|
+
|
|
484
|
+
To get started, please visit your account:
|
|
485
|
+
{{login_url}}
|
|
486
|
+
|
|
487
|
+
If you have any questions, feel free to reach out to our support team.
|
|
488
|
+
|
|
489
|
+
Best regards,
|
|
490
|
+
The Team`,
|
|
491
|
+
variables: {
|
|
492
|
+
user_name: 'Recipient name',
|
|
493
|
+
login_url: 'Login URL',
|
|
494
|
+
},
|
|
495
|
+
},
|
|
496
|
+
{
|
|
497
|
+
template_name: 'email_verification',
|
|
498
|
+
template_html: `<!DOCTYPE html>
|
|
499
|
+
<html>
|
|
500
|
+
<head>
|
|
501
|
+
<meta charset="utf-8">
|
|
502
|
+
<title>Verify Your Email</title>
|
|
503
|
+
</head>
|
|
504
|
+
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
|
|
505
|
+
<div style="max-width: 600px; margin: 0 auto; padding: 20px;">
|
|
506
|
+
<h1 style="color: #2563eb;">Verify Your Email Address</h1>
|
|
507
|
+
<p>Hi {{user_name}},</p>
|
|
508
|
+
<p>Please click the button below to verify your email address:</p>
|
|
509
|
+
<p style="margin: 20px 0;">
|
|
510
|
+
<a href="{{verification_link}}" style="background-color: #16a34a; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px;">
|
|
511
|
+
Verify Email
|
|
512
|
+
</a>
|
|
513
|
+
</p>
|
|
514
|
+
<p style="color: #666; font-size: 14px;">
|
|
515
|
+
This link will expire in {{expiry_hours}} hours.
|
|
516
|
+
</p>
|
|
517
|
+
<p>If you didn't create an account, you can safely ignore this email.</p>
|
|
518
|
+
</div>
|
|
519
|
+
</body>
|
|
520
|
+
</html>`,
|
|
521
|
+
template_text: `Verify Your Email Address
|
|
522
|
+
|
|
523
|
+
Hi {{user_name}},
|
|
524
|
+
|
|
525
|
+
Please click the link below to verify your email address:
|
|
526
|
+
{{verification_link}}
|
|
527
|
+
|
|
528
|
+
This link will expire in {{expiry_hours}} hours.
|
|
529
|
+
|
|
530
|
+
If you didn't create an account, you can safely ignore this email.`,
|
|
531
|
+
variables: {
|
|
532
|
+
user_name: 'Recipient name',
|
|
533
|
+
verification_link: 'Verification URL',
|
|
534
|
+
expiry_hours: 'Hours until expiry',
|
|
535
|
+
},
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
template_name: 'forgot_password',
|
|
539
|
+
template_html: `<!DOCTYPE html>
|
|
540
|
+
<html>
|
|
541
|
+
<head>
|
|
542
|
+
<meta charset="utf-8">
|
|
543
|
+
<title>Reset Your Password</title>
|
|
544
|
+
</head>
|
|
545
|
+
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
|
|
546
|
+
<div style="max-width: 600px; margin: 0 auto; padding: 20px;">
|
|
547
|
+
<h1 style="color: #dc2626;">Reset Your Password</h1>
|
|
548
|
+
<p>Hi {{user_name}},</p>
|
|
549
|
+
<p>We received a request to reset your password. Click the button below to create a new password:</p>
|
|
550
|
+
<p style="margin: 20px 0;">
|
|
551
|
+
<a href="{{reset_link}}" style="background-color: #dc2626; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px;">
|
|
552
|
+
Reset Password
|
|
553
|
+
</a>
|
|
554
|
+
</p>
|
|
555
|
+
<p style="color: #666; font-size: 14px;">
|
|
556
|
+
This link will expire in {{expiry_minutes}} minutes.
|
|
557
|
+
</p>
|
|
558
|
+
<p>If you didn't request a password reset, please ignore this email or contact support if you have concerns.</p>
|
|
559
|
+
</div>
|
|
560
|
+
</body>
|
|
561
|
+
</html>`,
|
|
562
|
+
template_text: `Reset Your Password
|
|
563
|
+
|
|
564
|
+
Hi {{user_name}},
|
|
565
|
+
|
|
566
|
+
We received a request to reset your password. Click the link below to create a new password:
|
|
567
|
+
{{reset_link}}
|
|
568
|
+
|
|
569
|
+
This link will expire in {{expiry_minutes}} minutes.
|
|
570
|
+
|
|
571
|
+
If you didn't request a password reset, please ignore this email or contact support if you have concerns.`,
|
|
572
|
+
variables: {
|
|
573
|
+
user_name: 'Recipient name',
|
|
574
|
+
reset_link: 'Password reset URL',
|
|
575
|
+
expiry_minutes: 'Minutes until expiry',
|
|
576
|
+
},
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
template_name: 'email_signature',
|
|
580
|
+
template_html: `<div style="font-family: Arial, sans-serif; margin-top: 20px; padding-top: 20px; border-top: 1px solid #e5e7eb;">
|
|
581
|
+
<p style="margin: 0; font-weight: bold; color: #333;">{{sender_name}}</p>
|
|
582
|
+
<p style="margin: 4px 0; color: #666;">{{sender_title}}</p>
|
|
583
|
+
<p style="margin: 4px 0; color: #2563eb;">{{company_name}}</p>
|
|
584
|
+
</div>`,
|
|
585
|
+
template_text: `--
|
|
586
|
+
{{sender_name}}
|
|
587
|
+
{{sender_title}}
|
|
588
|
+
{{company_name}}`,
|
|
589
|
+
variables: {
|
|
590
|
+
sender_name: 'Sender name',
|
|
591
|
+
sender_title: 'Job title',
|
|
592
|
+
company_name: 'Company name',
|
|
593
|
+
},
|
|
594
|
+
},
|
|
595
|
+
];
|
|
596
|
+
/**
|
|
597
|
+
* Seed default templates for an organization
|
|
598
|
+
*
|
|
599
|
+
* Creates a "System" category and populates it with default templates
|
|
600
|
+
*
|
|
601
|
+
* @param hazo_connect - Database connection instance
|
|
602
|
+
* @param org_id - Organization ID
|
|
603
|
+
* @param root_org_id - Root organization ID
|
|
604
|
+
* @returns Response with seeded templates
|
|
605
|
+
*/
|
|
606
|
+
async function seed_default_templates(hazo_connect, org_id, root_org_id) {
|
|
607
|
+
try {
|
|
608
|
+
if (!hazo_connect) {
|
|
609
|
+
return {
|
|
610
|
+
success: false,
|
|
611
|
+
error: constants_1.ERROR_MESSAGES.DB_CONNECTION_REQUIRED,
|
|
612
|
+
message: constants_1.ERROR_MESSAGES.DB_CONNECTION_REQUIRED,
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
if (!(0, validation_1.validate_uuid)(org_id) || !(0, validation_1.validate_uuid)(root_org_id)) {
|
|
616
|
+
return {
|
|
617
|
+
success: false,
|
|
618
|
+
error: 'Invalid organization ID',
|
|
619
|
+
message: 'Invalid organization ID format',
|
|
620
|
+
};
|
|
621
|
+
}
|
|
622
|
+
// Find or create "System" category
|
|
623
|
+
const category_result = await (0, category_repository_1.find_category_by_name)(hazo_connect, org_id, constants_1.DEFAULT_CATEGORY_NAMES.SYSTEM);
|
|
624
|
+
let category_id;
|
|
625
|
+
if (category_result.success && category_result.data) {
|
|
626
|
+
category_id = category_result.data.id;
|
|
627
|
+
}
|
|
628
|
+
else {
|
|
629
|
+
// Create the System category
|
|
630
|
+
const create_result = await (0, category_repository_1.create_category)(hazo_connect, {
|
|
631
|
+
org_id,
|
|
632
|
+
root_org_id,
|
|
633
|
+
template_category_name: constants_1.DEFAULT_CATEGORY_NAMES.SYSTEM,
|
|
634
|
+
});
|
|
635
|
+
if (!create_result.success || !create_result.data) {
|
|
636
|
+
return {
|
|
637
|
+
success: false,
|
|
638
|
+
error: 'Failed to create system category',
|
|
639
|
+
message: create_result.message || 'Failed to create system category',
|
|
640
|
+
};
|
|
641
|
+
}
|
|
642
|
+
category_id = create_result.data.id;
|
|
643
|
+
}
|
|
644
|
+
// Seed default templates
|
|
645
|
+
const seeded_templates = [];
|
|
646
|
+
for (const default_template of DEFAULT_TEMPLATES) {
|
|
647
|
+
// Check if template already exists
|
|
648
|
+
const existing_result = await get_template_by_name(hazo_connect, org_id, default_template.template_name);
|
|
649
|
+
if (existing_result.success && existing_result.data) {
|
|
650
|
+
// Template already exists, skip
|
|
651
|
+
seeded_templates.push(existing_result.data);
|
|
652
|
+
continue;
|
|
653
|
+
}
|
|
654
|
+
// Create the template
|
|
655
|
+
const create_result = await create_template(hazo_connect, {
|
|
656
|
+
org_id,
|
|
657
|
+
root_org_id,
|
|
658
|
+
template_category_id: category_id,
|
|
659
|
+
template_name: default_template.template_name,
|
|
660
|
+
template_html: default_template.template_html,
|
|
661
|
+
template_text: default_template.template_text,
|
|
662
|
+
template_variables: default_template.variables,
|
|
663
|
+
email_type: 'system',
|
|
664
|
+
});
|
|
665
|
+
if (create_result.success && create_result.data) {
|
|
666
|
+
seeded_templates.push(create_result.data);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
return {
|
|
670
|
+
success: true,
|
|
671
|
+
data: seeded_templates,
|
|
672
|
+
message: `Seeded ${seeded_templates.length} default templates`,
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
catch (error) {
|
|
676
|
+
const error_message = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
677
|
+
return {
|
|
678
|
+
success: false,
|
|
679
|
+
error: error_message,
|
|
680
|
+
message: `Failed to seed templates: ${error_message}`,
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
//# sourceMappingURL=template_repository.js.map
|