custom-email-otp-template 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +154 -3
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +12 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/templates/default.d.ts +3 -0
- package/dist/src/templates/default.d.ts.map +1 -0
- package/dist/src/templates/default.js +117 -0
- package/dist/src/templates/default.js.map +1 -0
- package/dist/src/types/email.types.d.ts +11 -0
- package/dist/src/types/email.types.d.ts.map +1 -0
- package/dist/src/types/email.types.js +3 -0
- package/dist/src/types/email.types.js.map +1 -0
- package/dist/src/utils/escapeHtml.d.ts +2 -0
- package/dist/src/utils/escapeHtml.d.ts.map +1 -0
- package/dist/src/utils/escapeHtml.js +16 -0
- package/dist/src/utils/escapeHtml.js.map +1 -0
- package/dist/src/utils/validate.d.ts +3 -0
- package/dist/src/utils/validate.d.ts.map +1 -0
- package/dist/src/utils/validate.js +25 -0
- package/dist/src/utils/validate.js.map +1 -0
- package/dist/templates/dark.d.ts +3 -0
- package/dist/templates/dark.d.ts.map +1 -0
- package/dist/templates/dark.js +126 -0
- package/dist/templates/dark.js.map +1 -0
- package/dist/templates/default.d.ts +3 -0
- package/dist/templates/default.d.ts.map +1 -0
- package/dist/templates/default.js +117 -0
- package/dist/templates/default.js.map +1 -0
- package/dist/templates/modern.d.ts +3 -0
- package/dist/templates/modern.d.ts.map +1 -0
- package/dist/templates/modern.js +127 -0
- package/dist/templates/modern.js.map +1 -0
- package/dist/tests/template.test.d.ts +2 -0
- package/dist/tests/template.test.d.ts.map +1 -0
- package/dist/tests/template.test.js +57 -0
- package/dist/tests/template.test.js.map +1 -0
- package/dist/types/email.types.d.ts +11 -0
- package/dist/types/email.types.d.ts.map +1 -0
- package/dist/types/email.types.js +3 -0
- package/dist/types/email.types.js.map +1 -0
- package/dist/utils/escapeHtml.d.ts +2 -0
- package/dist/utils/escapeHtml.d.ts.map +1 -0
- package/dist/utils/escapeHtml.js +16 -0
- package/dist/utils/escapeHtml.js.map +1 -0
- package/dist/utils/validate.d.ts +3 -0
- package/dist/utils/validate.d.ts.map +1 -0
- package/dist/utils/validate.js +29 -0
- package/dist/utils/validate.js.map +1 -0
- package/dist/utils/validateEmail.d.ts +2 -0
- package/dist/utils/validateEmail.d.ts.map +1 -0
- package/dist/utils/validateEmail.js +12 -0
- package/dist/utils/validateEmail.js.map +1 -0
- package/dist/utils/validateUrl.d.ts +2 -0
- package/dist/utils/validateUrl.d.ts.map +1 -0
- package/dist/utils/validateUrl.js +17 -0
- package/dist/utils/validateUrl.js.map +1 -0
- package/package.json +36 -4
package/README.md
CHANGED
|
@@ -1,3 +1,154 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# Custom Email OTP Template
|
|
2
|
+
|
|
3
|
+
A lightweight and customizable HTML email OTP template generator built with TypeScript.
|
|
4
|
+
|
|
5
|
+
Generate beautiful, responsive OTP verification emails using ready-made templates and custom branding.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- Multiple email templates: Default, Modern, and Dark.
|
|
10
|
+
- Custom company name and branding.
|
|
11
|
+
- Custom OTP expiration time.
|
|
12
|
+
- Custom brand colors.
|
|
13
|
+
- Custom logo support.
|
|
14
|
+
- Support email configuration.
|
|
15
|
+
- TypeScript support.
|
|
16
|
+
- HTML escaping for dynamic text.
|
|
17
|
+
- Input validation.
|
|
18
|
+
- No email service dependency.
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install custom-email-otp-template
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Basic Usage
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { generateOtpEmail } from "custom-email-otp-template";
|
|
30
|
+
|
|
31
|
+
const email = generateOtpEmail({
|
|
32
|
+
companyName: "My Company",
|
|
33
|
+
otp: "583921"
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
console.log(email.html);
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Available Templates
|
|
40
|
+
|
|
41
|
+
### Default Template
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
const email = generateOtpEmail({
|
|
45
|
+
companyName: "My Company",
|
|
46
|
+
otp: "583921",
|
|
47
|
+
template: "default"
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Modern Template
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
const email = generateOtpEmail({
|
|
55
|
+
companyName: "My Company",
|
|
56
|
+
otp: "583921",
|
|
57
|
+
template: "modern",
|
|
58
|
+
brandColor: "#2563eb"
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Dark Template
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
const email = generateOtpEmail({
|
|
66
|
+
companyName: "My Company",
|
|
67
|
+
otp: "583921",
|
|
68
|
+
template: "dark",
|
|
69
|
+
brandColor: "#60a5fa"
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Custom Branding
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
const email = generateOtpEmail({
|
|
77
|
+
companyName: "Tech Solutions",
|
|
78
|
+
otp: "583921",
|
|
79
|
+
expiresIn: "5 minutes",
|
|
80
|
+
brandColor: "#2563eb",
|
|
81
|
+
template: "modern",
|
|
82
|
+
logoUrl: "https://example.com/logo.png",
|
|
83
|
+
supportEmail: "support@example.com"
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Configuration Options
|
|
88
|
+
|
|
89
|
+
| Property | Type | Required | Default |
|
|
90
|
+
|---|---|---|---|
|
|
91
|
+
| companyName | string | Yes | — |
|
|
92
|
+
| otp | string | Yes | — |
|
|
93
|
+
| expiresIn | string | No | 5 minutes |
|
|
94
|
+
| brandColor | string | No | #2563eb |
|
|
95
|
+
| logoUrl | string | No | — |
|
|
96
|
+
| template | string | No | default |
|
|
97
|
+
| supportEmail | string | No | — |
|
|
98
|
+
|
|
99
|
+
## Using with Nodemailer
|
|
100
|
+
|
|
101
|
+
This package generates HTML only. You can send the generated HTML using Nodemailer.
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
npm install nodemailer
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
import nodemailer from "nodemailer";
|
|
109
|
+
import { generateOtpEmail } from "custom-email-otp-template";
|
|
110
|
+
|
|
111
|
+
const email = generateOtpEmail({
|
|
112
|
+
companyName: "My Company",
|
|
113
|
+
otp: "583921",
|
|
114
|
+
template: "modern"
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const transporter = nodemailer.createTransport({
|
|
118
|
+
host: process.env.SMTP_HOST,
|
|
119
|
+
port: Number(process.env.SMTP_PORT),
|
|
120
|
+
secure: true,
|
|
121
|
+
auth: {
|
|
122
|
+
user: process.env.SMTP_USER,
|
|
123
|
+
pass: process.env.SMTP_PASSWORD
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
await transporter.sendMail({
|
|
128
|
+
from: process.env.SMTP_USER,
|
|
129
|
+
to: "user@example.com",
|
|
130
|
+
subject: "Email Verification",
|
|
131
|
+
html: email.html
|
|
132
|
+
});
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Important Notes
|
|
136
|
+
|
|
137
|
+
- This package generates email HTML; it does not generate OTPs.
|
|
138
|
+
- This package does not send emails.
|
|
139
|
+
- Generate and securely verify OTPs in your own application.
|
|
140
|
+
- Never log or expose OTP values in production.
|
|
141
|
+
- OTP expiration and verification must be enforced by your application.
|
|
142
|
+
- Use a trusted HTTPS image URL for your logo.
|
|
143
|
+
|
|
144
|
+
## Development
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
npm install
|
|
148
|
+
npm run build
|
|
149
|
+
npm test
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## License
|
|
153
|
+
|
|
154
|
+
MIT License
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAQ9D,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,eAAe;;EAqBxD"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateOtpEmail = generateOtpEmail;
|
|
4
|
+
const default_js_1 = require("./templates/default.js");
|
|
5
|
+
const modern_js_1 = require("./templates/modern.js");
|
|
6
|
+
const dark_js_1 = require("./templates/dark.js");
|
|
7
|
+
const validate_js_1 = require("./utils/validate.js");
|
|
8
|
+
function generateOtpEmail(options) {
|
|
9
|
+
(0, validate_js_1.validateOtpEmail)(options);
|
|
10
|
+
let html;
|
|
11
|
+
switch (options.template ?? "default") {
|
|
12
|
+
case "modern":
|
|
13
|
+
html = (0, modern_js_1.modernTemplate)(options);
|
|
14
|
+
break;
|
|
15
|
+
case "dark":
|
|
16
|
+
html = (0, dark_js_1.darkTemplate)(options);
|
|
17
|
+
break;
|
|
18
|
+
case "default":
|
|
19
|
+
default:
|
|
20
|
+
html = (0, default_js_1.defaultTemplate)(options);
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
return { html };
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAGA,uDAAyD;AACzD,qDAAuD;AACvD,iDAAmD;AAEnD,qDAAuD;AAEvD,0BAAiC,OAAwB;IACrD,IAAA,8BAAgB,EAAC,OAAO,CAAC,CAAC;IAE1B,IAAI,IAAY,CAAC;IAEjB,QAAQ,OAAO,CAAC,QAAQ,IAAI,SAAS,EAAE,CAAC;QACpC,KAAK,QAAQ;YACT,IAAI,GAAG,IAAA,0BAAc,EAAC,OAAO,CAAC,CAAC;YAC/B,MAAM;QAEV,KAAK,MAAM;YACP,IAAI,GAAG,IAAA,sBAAY,EAAC,OAAO,CAAC,CAAC;YAC7B,MAAM;QAEV,KAAK,SAAS,CAAC;QACf;YACI,IAAI,GAAG,IAAA,4BAAe,EAAC,OAAO,CAAC,CAAC;YAChC,MAAM;IACd,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAIxD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc;IAGpD,IAAI;EAEP"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateOtpEmail = generateOtpEmail;
|
|
4
|
+
const default_js_1 = require("./templates/default.js");
|
|
5
|
+
const validate_js_1 = require("./utils/validate.js");
|
|
6
|
+
function generateOtpEmail(options) {
|
|
7
|
+
(0, validate_js_1.validateOtpEmail)(options);
|
|
8
|
+
return {
|
|
9
|
+
html: (0, default_js_1.defaultTemplate)(options),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AACA,uDAAyD;AACzD,qDAAuD;AAEvD,0BAAiC,OAAuB;IACtD,IAAA,8BAAgB,EAAC,OAAO,CAAC,CAAC;IAC1B,OAAO;QACL,IAAI,EAAE,IAAA,4BAAe,EAAC,OAAO,CAAC;KAC/B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default.d.ts","sourceRoot":"","sources":["../../../src/templates/default.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGzD,wBAAgB,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CA6H/D"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defaultTemplate = defaultTemplate;
|
|
4
|
+
const escapeHtml_js_1 = require("../utils/escapeHtml.js");
|
|
5
|
+
function defaultTemplate(options) {
|
|
6
|
+
const { companyName, otp, expiresIn = "5 minutes", brandColor = "#2563eb", logoUrl, supportEmail, } = options;
|
|
7
|
+
const safeCompanyName = (0, escapeHtml_js_1.escapeHtml)(companyName);
|
|
8
|
+
const safeOtp = (0, escapeHtml_js_1.escapeHtml)(otp);
|
|
9
|
+
const safeExpiresIn = (0, escapeHtml_js_1.escapeHtml)(expiresIn);
|
|
10
|
+
const safeSupportEmail = supportEmail
|
|
11
|
+
? (0, escapeHtml_js_1.escapeHtml)(supportEmail)
|
|
12
|
+
: "";
|
|
13
|
+
const safeLogoUrl = logoUrl
|
|
14
|
+
? (0, escapeHtml_js_1.escapeHtml)(logoUrl)
|
|
15
|
+
: "";
|
|
16
|
+
return `
|
|
17
|
+
<!DOCTYPE html>
|
|
18
|
+
<html>
|
|
19
|
+
<head>
|
|
20
|
+
<meta charset="UTF-8">
|
|
21
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
22
|
+
<title>Email Verification</title>
|
|
23
|
+
</head>
|
|
24
|
+
|
|
25
|
+
<body style="
|
|
26
|
+
margin: 0;
|
|
27
|
+
padding: 30px 10px;
|
|
28
|
+
background-color: #f3f4f6;
|
|
29
|
+
font-family: Arial, sans-serif;
|
|
30
|
+
">
|
|
31
|
+
|
|
32
|
+
<div style="
|
|
33
|
+
max-width: 500px;
|
|
34
|
+
margin: auto;
|
|
35
|
+
background: #ffffff;
|
|
36
|
+
padding: 35px 25px;
|
|
37
|
+
border-radius: 12px;
|
|
38
|
+
text-align: center;
|
|
39
|
+
">
|
|
40
|
+
|
|
41
|
+
${safeLogoUrl
|
|
42
|
+
? `
|
|
43
|
+
<img
|
|
44
|
+
src="${safeLogoUrl}"
|
|
45
|
+
alt="${safeCompanyName}"
|
|
46
|
+
width="120"
|
|
47
|
+
style="margin-bottom: 20px;"
|
|
48
|
+
/>
|
|
49
|
+
`
|
|
50
|
+
: ""}
|
|
51
|
+
|
|
52
|
+
<h2 style="color: #111827;">
|
|
53
|
+
Verify Your Email
|
|
54
|
+
</h2>
|
|
55
|
+
|
|
56
|
+
<p style="color: #6b7280; line-height: 1.6;">
|
|
57
|
+
Hello,<br>
|
|
58
|
+
Use the verification code below to complete
|
|
59
|
+
your email verification.
|
|
60
|
+
</p>
|
|
61
|
+
|
|
62
|
+
<div style="
|
|
63
|
+
margin: 30px 0;
|
|
64
|
+
padding: 20px;
|
|
65
|
+
background: #f9fafb;
|
|
66
|
+
border-radius: 8px;
|
|
67
|
+
color: ${brandColor};
|
|
68
|
+
font-size: 32px;
|
|
69
|
+
font-weight: bold;
|
|
70
|
+
letter-spacing: 8px;
|
|
71
|
+
">
|
|
72
|
+
${safeOtp}
|
|
73
|
+
</div>
|
|
74
|
+
|
|
75
|
+
<p style="color: #6b7280;">
|
|
76
|
+
This code expires in
|
|
77
|
+
<strong>${safeExpiresIn}</strong>.
|
|
78
|
+
</p>
|
|
79
|
+
|
|
80
|
+
<p style="
|
|
81
|
+
color: #9ca3af;
|
|
82
|
+
font-size: 13px;
|
|
83
|
+
line-height: 1.6;
|
|
84
|
+
">
|
|
85
|
+
If you didn't request this verification code,
|
|
86
|
+
please ignore this email.
|
|
87
|
+
</p>
|
|
88
|
+
|
|
89
|
+
${safeSupportEmail
|
|
90
|
+
? `
|
|
91
|
+
<p style="font-size: 13px; color: #6b7280;">
|
|
92
|
+
Support:
|
|
93
|
+
<a href="mailto:${safeSupportEmail}">
|
|
94
|
+
${safeSupportEmail}
|
|
95
|
+
</a>
|
|
96
|
+
</p>
|
|
97
|
+
`
|
|
98
|
+
: ""}
|
|
99
|
+
|
|
100
|
+
<hr style="
|
|
101
|
+
border: none;
|
|
102
|
+
border-top: 1px solid #e5e7eb;
|
|
103
|
+
margin: 25px 0;
|
|
104
|
+
" />
|
|
105
|
+
|
|
106
|
+
<p style="font-size: 12px; color: #9ca3af;">
|
|
107
|
+
© ${new Date().getFullYear()} ${safeCompanyName}.
|
|
108
|
+
All rights reserved.
|
|
109
|
+
</p>
|
|
110
|
+
|
|
111
|
+
</div>
|
|
112
|
+
|
|
113
|
+
</body>
|
|
114
|
+
</html>
|
|
115
|
+
`;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=default.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default.js","sourceRoot":"","sources":["../../../src/templates/default.ts"],"names":[],"mappings":";;;AACA,0DAAoD;AAEpD,yBAAgC,OAAuB;IACrD,MAAM,EACJ,WAAW,EACX,GAAG,EACH,SAAS,GAAG,WAAW,EACvB,UAAU,GAAG,SAAS,EACtB,OAAO,EACP,YAAY,GACb,GAAG,OAAO,CAAC;IAEZ,MAAM,eAAe,GAAG,IAAA,0BAAU,EAAC,WAAW,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,IAAA,0BAAU,EAAC,GAAG,CAAC,CAAC;IAChC,MAAM,aAAa,GAAG,IAAA,0BAAU,EAAC,SAAS,CAAC,CAAC;IAC5C,MAAM,gBAAgB,GAAG,YAAY;QACnC,CAAC,CAAC,IAAA,0BAAU,EAAC,YAAY,CAAC;QAC1B,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,WAAW,GAAG,OAAO;QACzB,CAAC,CAAC,IAAA,0BAAU,EAAC,OAAO,CAAC;QACrB,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;QA0BD,WAAW;QACT,CAAC,CAAC;;mBAEO,WAAW;mBACX,eAAe;;;;WAIvB;QACD,CAAC,CAAC,EACN;;;;;;;;;;;;;;;;;iBAiBW,UAAU;;;;;UAKjB,OAAO;;;;;kBAKC,aAAa;;;;;;;;;;;;QAavB,gBAAgB;QACd,CAAC,CAAC;;;8BAGkB,gBAAgB;gBAC9B,gBAAgB;;;WAGrB;QACD,CAAC,CAAC,EACN;;;;;;;;;iBASW,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,eAAe;;;;;;;;GAQzD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type EmailTemplate = "default" | "modern" | "dark";
|
|
2
|
+
export interface OtpEmailOption {
|
|
3
|
+
companyName: string;
|
|
4
|
+
otp: string;
|
|
5
|
+
expiresIn?: string;
|
|
6
|
+
brandColor?: string;
|
|
7
|
+
logoUrl?: string;
|
|
8
|
+
template?: EmailTemplate;
|
|
9
|
+
supportEmail?: string;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=email.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.types.d.ts","sourceRoot":"","sources":["../../../src/types/email.types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAI,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAE;AAE5D,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAG,MAAM,CAAC;IACb,SAAS,CAAC,EAAC,MAAM,CAAC;IAClB,UAAU,CAAC,EAAC,MAAM,CAAC;IACnB,OAAO,CAAC,EAAC,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAC,aAAa,CAAC;IACxB,YAAY,CAAC,EAAC,MAAM,CAAA;CACrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.types.js","sourceRoot":"","sources":["../../../src/types/email.types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escapeHtml.d.ts","sourceRoot":"","sources":["../../../src/utils/escapeHtml.ts"],"names":[],"mappings":"AACA,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAYhD"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.escapeHtml = escapeHtml;
|
|
4
|
+
function escapeHtml(value) {
|
|
5
|
+
return value.replace(/[&<>"']/g, (character) => {
|
|
6
|
+
const entities = {
|
|
7
|
+
"&": "&",
|
|
8
|
+
"<": "<",
|
|
9
|
+
">": ">",
|
|
10
|
+
'"': """,
|
|
11
|
+
"'": "'"
|
|
12
|
+
};
|
|
13
|
+
return entities[character];
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=escapeHtml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escapeHtml.js","sourceRoot":"","sources":["../../../src/utils/escapeHtml.ts"],"names":[],"mappings":";;;AACA,oBAA2B,KAAa;IACpC,OAAO,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,SAAS,EAAE,EAAE;QAC3C,MAAM,QAAQ,GAA2B;YACrC,GAAG,EAAE,OAAO;YACZ,GAAG,EAAE,MAAM;YACX,GAAG,EAAE,MAAM;YACX,GAAG,EAAE,QAAQ;YACb,GAAG,EAAE,OAAO;SACf,CAAC;QAEF,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/utils/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAsB9D"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateOtpEmail = validateOtpEmail;
|
|
4
|
+
function validateOtpEmail(options) {
|
|
5
|
+
if (!options) {
|
|
6
|
+
throw new Error("OTP email options are required.");
|
|
7
|
+
}
|
|
8
|
+
if (!options.companyName.trim()) {
|
|
9
|
+
throw new Error("Company name is required.");
|
|
10
|
+
}
|
|
11
|
+
if (!options.otp.trim()) {
|
|
12
|
+
throw new Error("OTP is required.");
|
|
13
|
+
}
|
|
14
|
+
if (!/^[a-zA-Z0-9]{4,8}$/.test(options.otp)) {
|
|
15
|
+
throw new Error("OTP must contain 4 to 8 alphanumeric characters.");
|
|
16
|
+
}
|
|
17
|
+
if (options.brandColor && !/^#[0-9A-Fa-f]{6}$/.test(options.brandColor)) {
|
|
18
|
+
throw new Error("Brand color must be a valid HEX color.");
|
|
19
|
+
}
|
|
20
|
+
if (options.template &&
|
|
21
|
+
!["default", "modern", "dark"].includes(options.template)) {
|
|
22
|
+
throw new Error("Invalid email template.");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/utils/validate.ts"],"names":[],"mappings":";;;AAEA,0BAAiC,OAAuB;IACtD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACtC,CAAC;IACD,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACxE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC5D,CAAC;IACD,IACE,OAAO,CAAC,QAAQ;QAChB,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,EACzD,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dark.d.ts","sourceRoot":"","sources":["../../src/templates/dark.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG/D,wBAAgB,YAAY,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CAqI7D"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.darkTemplate = darkTemplate;
|
|
4
|
+
const escapeHtml_js_1 = require("../utils/escapeHtml.js");
|
|
5
|
+
function darkTemplate(options) {
|
|
6
|
+
const { companyName, otp, expiresIn = "5 minutes", brandColor = "#60a5fa", logoUrl, supportEmail } = options;
|
|
7
|
+
const safeCompanyName = (0, escapeHtml_js_1.escapeHtml)(companyName);
|
|
8
|
+
const safeOtp = (0, escapeHtml_js_1.escapeHtml)(otp);
|
|
9
|
+
const safeExpiresIn = (0, escapeHtml_js_1.escapeHtml)(expiresIn);
|
|
10
|
+
const safeLogoUrl = logoUrl ? (0, escapeHtml_js_1.escapeHtml)(logoUrl) : "";
|
|
11
|
+
const safeSupportEmail = supportEmail
|
|
12
|
+
? (0, escapeHtml_js_1.escapeHtml)(supportEmail)
|
|
13
|
+
: "";
|
|
14
|
+
return `
|
|
15
|
+
<!DOCTYPE html>
|
|
16
|
+
<html>
|
|
17
|
+
<head>
|
|
18
|
+
<meta charset="UTF-8">
|
|
19
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
20
|
+
<title>Email Verification</title>
|
|
21
|
+
</head>
|
|
22
|
+
|
|
23
|
+
<body style="
|
|
24
|
+
margin: 0;
|
|
25
|
+
padding: 30px 12px;
|
|
26
|
+
background-color: #111827;
|
|
27
|
+
font-family: Arial, sans-serif;
|
|
28
|
+
">
|
|
29
|
+
|
|
30
|
+
<div style="
|
|
31
|
+
max-width: 520px;
|
|
32
|
+
margin: auto;
|
|
33
|
+
background: #1f2937;
|
|
34
|
+
border-radius: 14px;
|
|
35
|
+
overflow: hidden;
|
|
36
|
+
">
|
|
37
|
+
|
|
38
|
+
<div style="
|
|
39
|
+
padding: 35px 20px;
|
|
40
|
+
text-align: center;
|
|
41
|
+
">
|
|
42
|
+
${logoUrl
|
|
43
|
+
? `<img src="${safeLogoUrl}" alt="${safeCompanyName}" width="110" style="margin-bottom: 15px;">`
|
|
44
|
+
: ""}
|
|
45
|
+
|
|
46
|
+
<h1 style="
|
|
47
|
+
color: #ffffff;
|
|
48
|
+
font-size: 24px;
|
|
49
|
+
">
|
|
50
|
+
Verify Your Email
|
|
51
|
+
</h1>
|
|
52
|
+
|
|
53
|
+
<p style="
|
|
54
|
+
color: #9ca3af;
|
|
55
|
+
line-height: 1.6;
|
|
56
|
+
">
|
|
57
|
+
Welcome to ${safeCompanyName}.
|
|
58
|
+
Enter the code below to verify your email.
|
|
59
|
+
</p>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<div style="
|
|
63
|
+
margin: 0 25px 25px;
|
|
64
|
+
padding: 25px 15px;
|
|
65
|
+
background: #374151;
|
|
66
|
+
border-radius: 12px;
|
|
67
|
+
text-align: center;
|
|
68
|
+
">
|
|
69
|
+
<p style="
|
|
70
|
+
color: #9ca3af;
|
|
71
|
+
font-size: 13px;
|
|
72
|
+
">
|
|
73
|
+
VERIFICATION CODE
|
|
74
|
+
</p>
|
|
75
|
+
|
|
76
|
+
<div style="
|
|
77
|
+
color: ${brandColor};
|
|
78
|
+
font-size: 32px;
|
|
79
|
+
font-weight: bold;
|
|
80
|
+
letter-spacing: 8px;
|
|
81
|
+
">
|
|
82
|
+
${safeOtp}
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
|
|
86
|
+
<div style="
|
|
87
|
+
padding: 0 25px 30px;
|
|
88
|
+
text-align: center;
|
|
89
|
+
">
|
|
90
|
+
<p style="color: #d1d5db; font-size: 14px;">
|
|
91
|
+
This code expires in
|
|
92
|
+
<strong>${safeExpiresIn}</strong>.
|
|
93
|
+
</p>
|
|
94
|
+
|
|
95
|
+
<p style="
|
|
96
|
+
color: #9ca3af;
|
|
97
|
+
font-size: 13px;
|
|
98
|
+
line-height: 1.6;
|
|
99
|
+
">
|
|
100
|
+
If you didn't request this code,
|
|
101
|
+
please ignore this email.
|
|
102
|
+
</p>
|
|
103
|
+
|
|
104
|
+
${supportEmail
|
|
105
|
+
? `<p style="font-size: 13px;"><a style="color: ${brandColor};" href="mailto:${safeSupportEmail}">${safeSupportEmail}</a></p>`
|
|
106
|
+
: ""}
|
|
107
|
+
</div>
|
|
108
|
+
|
|
109
|
+
<div style="
|
|
110
|
+
padding: 18px;
|
|
111
|
+
background: #111827;
|
|
112
|
+
text-align: center;
|
|
113
|
+
color: #6b7280;
|
|
114
|
+
font-size: 12px;
|
|
115
|
+
">
|
|
116
|
+
© ${new Date().getFullYear()} ${safeCompanyName}.
|
|
117
|
+
All rights reserved.
|
|
118
|
+
</div>
|
|
119
|
+
|
|
120
|
+
</div>
|
|
121
|
+
|
|
122
|
+
</body>
|
|
123
|
+
</html>
|
|
124
|
+
`;
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=dark.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dark.js","sourceRoot":"","sources":["../../src/templates/dark.ts"],"names":[],"mappings":";;;AAEA,0DAAoD;AAEpD,sBAA6B,OAAwB;IACjD,MAAM,EACF,WAAW,EACX,GAAG,EACH,SAAS,GAAG,WAAW,EACvB,UAAU,GAAG,SAAS,EACtB,OAAO,EACP,YAAY,EACf,GAAG,OAAO,CAAC;IAEZ,MAAM,eAAe,GAAG,IAAA,0BAAU,EAAC,WAAW,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,IAAA,0BAAU,EAAC,GAAG,CAAC,CAAC;IAChC,MAAM,aAAa,GAAG,IAAA,0BAAU,EAAC,SAAS,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,IAAA,0BAAU,EAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvD,MAAM,gBAAgB,GAAG,YAAY;QACjC,CAAC,CAAC,IAAA,0BAAU,EAAC,YAAY,CAAC;QAC1B,CAAC,CAAC,EAAE,CAAC;IAET,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA6BS,OAAO;QACH,CAAC,CAAC,aAAa,WAAW,UAAU,eAAe,6CAA6C;QAChG,CAAC,CAAC,EACV;;;;;;;;;;;;;iCAaiB,eAAe;;;;;;;;;;;;;;;;;;;;6BAoBnB,UAAU;;;;;sBAKjB,OAAO;;;;;;;;;;8BAUC,aAAa;;;;;;;;;;;;kBAavB,YAAY;QACR,CAAC,CAAC,gDAAgD,UAAU,mBAAmB,gBAAgB,KAAK,gBAAgB,UAAU;QAC9H,CAAC,CAAC,EACV;;;;;;;;;;oBAUI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,eAAe;;;;;;;;KAQ1D,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default.d.ts","sourceRoot":"","sources":["../../src/templates/default.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG1D,wBAAgB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CA6HhE"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defaultTemplate = defaultTemplate;
|
|
4
|
+
const escapeHtml_js_1 = require("../utils/escapeHtml.js");
|
|
5
|
+
function defaultTemplate(options) {
|
|
6
|
+
const { companyName, otp, expiresIn = "5 minutes", brandColor = "#2563eb", logoUrl, supportEmail, } = options;
|
|
7
|
+
const safeCompanyName = (0, escapeHtml_js_1.escapeHtml)(companyName);
|
|
8
|
+
const safeOtp = (0, escapeHtml_js_1.escapeHtml)(otp);
|
|
9
|
+
const safeExpiresIn = (0, escapeHtml_js_1.escapeHtml)(expiresIn);
|
|
10
|
+
const safeSupportEmail = supportEmail
|
|
11
|
+
? (0, escapeHtml_js_1.escapeHtml)(supportEmail)
|
|
12
|
+
: "";
|
|
13
|
+
const safeLogoUrl = logoUrl
|
|
14
|
+
? (0, escapeHtml_js_1.escapeHtml)(logoUrl)
|
|
15
|
+
: "";
|
|
16
|
+
return `
|
|
17
|
+
<!DOCTYPE html>
|
|
18
|
+
<html>
|
|
19
|
+
<head>
|
|
20
|
+
<meta charset="UTF-8">
|
|
21
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
22
|
+
<title>Email Verification</title>
|
|
23
|
+
</head>
|
|
24
|
+
|
|
25
|
+
<body style="
|
|
26
|
+
margin: 0;
|
|
27
|
+
padding: 30px 10px;
|
|
28
|
+
background-color: #f3f4f6;
|
|
29
|
+
font-family: Arial, sans-serif;
|
|
30
|
+
">
|
|
31
|
+
|
|
32
|
+
<div style="
|
|
33
|
+
max-width: 500px;
|
|
34
|
+
margin: auto;
|
|
35
|
+
background: #ffffff;
|
|
36
|
+
padding: 35px 25px;
|
|
37
|
+
border-radius: 12px;
|
|
38
|
+
text-align: center;
|
|
39
|
+
">
|
|
40
|
+
|
|
41
|
+
${safeLogoUrl
|
|
42
|
+
? `
|
|
43
|
+
<img
|
|
44
|
+
src="${safeLogoUrl}"
|
|
45
|
+
alt="${safeCompanyName}"
|
|
46
|
+
width="120"
|
|
47
|
+
style="margin-bottom: 20px;"
|
|
48
|
+
/>
|
|
49
|
+
`
|
|
50
|
+
: ""}
|
|
51
|
+
|
|
52
|
+
<h2 style="color: #111827;">
|
|
53
|
+
Verify Your Email
|
|
54
|
+
</h2>
|
|
55
|
+
|
|
56
|
+
<p style="color: #6b7280; line-height: 1.6;">
|
|
57
|
+
Hello,<br>
|
|
58
|
+
Use the verification code below to complete
|
|
59
|
+
your email verification.
|
|
60
|
+
</p>
|
|
61
|
+
|
|
62
|
+
<div style="
|
|
63
|
+
margin: 30px 0;
|
|
64
|
+
padding: 20px;
|
|
65
|
+
background: #f9fafb;
|
|
66
|
+
border-radius: 8px;
|
|
67
|
+
color: ${brandColor};
|
|
68
|
+
font-size: 32px;
|
|
69
|
+
font-weight: bold;
|
|
70
|
+
letter-spacing: 8px;
|
|
71
|
+
">
|
|
72
|
+
${safeOtp}
|
|
73
|
+
</div>
|
|
74
|
+
|
|
75
|
+
<p style="color: #6b7280;">
|
|
76
|
+
This code expires in
|
|
77
|
+
<strong>${safeExpiresIn}</strong>.
|
|
78
|
+
</p>
|
|
79
|
+
|
|
80
|
+
<p style="
|
|
81
|
+
color: #9ca3af;
|
|
82
|
+
font-size: 13px;
|
|
83
|
+
line-height: 1.6;
|
|
84
|
+
">
|
|
85
|
+
If you didn't request this verification code,
|
|
86
|
+
please ignore this email.
|
|
87
|
+
</p>
|
|
88
|
+
|
|
89
|
+
${safeSupportEmail
|
|
90
|
+
? `
|
|
91
|
+
<p style="font-size: 13px; color: #6b7280;">
|
|
92
|
+
Support:
|
|
93
|
+
<a href="mailto:${safeSupportEmail}">
|
|
94
|
+
${safeSupportEmail}
|
|
95
|
+
</a>
|
|
96
|
+
</p>
|
|
97
|
+
`
|
|
98
|
+
: ""}
|
|
99
|
+
|
|
100
|
+
<hr style="
|
|
101
|
+
border: none;
|
|
102
|
+
border-top: 1px solid #e5e7eb;
|
|
103
|
+
margin: 25px 0;
|
|
104
|
+
" />
|
|
105
|
+
|
|
106
|
+
<p style="font-size: 12px; color: #9ca3af;">
|
|
107
|
+
© ${new Date().getFullYear()} ${safeCompanyName}.
|
|
108
|
+
All rights reserved.
|
|
109
|
+
</p>
|
|
110
|
+
|
|
111
|
+
</div>
|
|
112
|
+
|
|
113
|
+
</body>
|
|
114
|
+
</html>
|
|
115
|
+
`;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=default.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default.js","sourceRoot":"","sources":["../../src/templates/default.ts"],"names":[],"mappings":";;;AACA,0DAAoD;AAEpD,yBAAgC,OAAwB;IACtD,MAAM,EACJ,WAAW,EACX,GAAG,EACH,SAAS,GAAG,WAAW,EACvB,UAAU,GAAG,SAAS,EACtB,OAAO,EACP,YAAY,GACb,GAAG,OAAO,CAAC;IAEZ,MAAM,eAAe,GAAG,IAAA,0BAAU,EAAC,WAAW,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,IAAA,0BAAU,EAAC,GAAG,CAAC,CAAC;IAChC,MAAM,aAAa,GAAG,IAAA,0BAAU,EAAC,SAAS,CAAC,CAAC;IAC5C,MAAM,gBAAgB,GAAG,YAAY;QACnC,CAAC,CAAC,IAAA,0BAAU,EAAC,YAAY,CAAC;QAC1B,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,WAAW,GAAG,OAAO;QACzB,CAAC,CAAC,IAAA,0BAAU,EAAC,OAAO,CAAC;QACrB,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;QA0BD,WAAW;QACT,CAAC,CAAC;;mBAEO,WAAW;mBACX,eAAe;;;;WAIvB;QACD,CAAC,CAAC,EACN;;;;;;;;;;;;;;;;;iBAiBW,UAAU;;;;;UAKjB,OAAO;;;;;kBAKC,aAAa;;;;;;;;;;;;QAavB,gBAAgB;QACd,CAAC,CAAC;;;8BAGkB,gBAAgB;gBAC9B,gBAAgB;;;WAGrB;QACD,CAAC,CAAC,EACN;;;;;;;;;iBASW,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,eAAe;;;;;;;;GAQzD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modern.d.ts","sourceRoot":"","sources":["../../src/templates/modern.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG/D,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CAsI/D"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.modernTemplate = modernTemplate;
|
|
4
|
+
const escapeHtml_js_1 = require("../utils/escapeHtml.js");
|
|
5
|
+
function modernTemplate(options) {
|
|
6
|
+
const { companyName, otp, expiresIn = "5 minutes", brandColor = "#2563eb", logoUrl, supportEmail } = options;
|
|
7
|
+
const safeCompanyName = (0, escapeHtml_js_1.escapeHtml)(companyName);
|
|
8
|
+
const safeOtp = (0, escapeHtml_js_1.escapeHtml)(otp);
|
|
9
|
+
const safeExpiresIn = (0, escapeHtml_js_1.escapeHtml)(expiresIn);
|
|
10
|
+
const safeLogoUrl = logoUrl ? (0, escapeHtml_js_1.escapeHtml)(logoUrl) : "";
|
|
11
|
+
const safeSupportEmail = supportEmail
|
|
12
|
+
? (0, escapeHtml_js_1.escapeHtml)(supportEmail)
|
|
13
|
+
: "";
|
|
14
|
+
return `
|
|
15
|
+
<!DOCTYPE html>
|
|
16
|
+
<html>
|
|
17
|
+
<head>
|
|
18
|
+
<meta charset="UTF-8">
|
|
19
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
20
|
+
<title>Email Verification</title>
|
|
21
|
+
</head>
|
|
22
|
+
|
|
23
|
+
<body style="
|
|
24
|
+
margin: 0;
|
|
25
|
+
padding: 30px 12px;
|
|
26
|
+
background-color: #eef2ff;
|
|
27
|
+
font-family: Arial, sans-serif;
|
|
28
|
+
">
|
|
29
|
+
|
|
30
|
+
<div style="
|
|
31
|
+
max-width: 520px;
|
|
32
|
+
margin: auto;
|
|
33
|
+
background: #ffffff;
|
|
34
|
+
border-radius: 16px;
|
|
35
|
+
overflow: hidden;
|
|
36
|
+
">
|
|
37
|
+
|
|
38
|
+
<div style="
|
|
39
|
+
padding: 30px 20px;
|
|
40
|
+
background: ${brandColor};
|
|
41
|
+
text-align: center;
|
|
42
|
+
">
|
|
43
|
+
${logoUrl
|
|
44
|
+
? `<img src="${safeLogoUrl}" alt="${safeCompanyName}" width="110" style="margin-bottom: 15px;">`
|
|
45
|
+
: ""}
|
|
46
|
+
|
|
47
|
+
<h1 style="
|
|
48
|
+
color: #ffffff;
|
|
49
|
+
font-size: 24px;
|
|
50
|
+
margin: 0;
|
|
51
|
+
">
|
|
52
|
+
Verify Your Email
|
|
53
|
+
</h1>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<div style="
|
|
57
|
+
padding: 35px 25px;
|
|
58
|
+
text-align: center;
|
|
59
|
+
">
|
|
60
|
+
|
|
61
|
+
<p style="color: #4b5563; line-height: 1.7;">
|
|
62
|
+
Welcome to <strong>${safeCompanyName}</strong>!
|
|
63
|
+
Please use the verification code below.
|
|
64
|
+
</p>
|
|
65
|
+
|
|
66
|
+
<div style="
|
|
67
|
+
margin: 30px 0;
|
|
68
|
+
padding: 25px 15px;
|
|
69
|
+
background: #f1f5f9;
|
|
70
|
+
border-radius: 12px;
|
|
71
|
+
">
|
|
72
|
+
<p style="
|
|
73
|
+
margin: 0 0 12px;
|
|
74
|
+
color: #64748b;
|
|
75
|
+
font-size: 13px;
|
|
76
|
+
">
|
|
77
|
+
YOUR VERIFICATION CODE
|
|
78
|
+
</p>
|
|
79
|
+
|
|
80
|
+
<div style="
|
|
81
|
+
color: ${brandColor};
|
|
82
|
+
font-size: 32px;
|
|
83
|
+
font-weight: bold;
|
|
84
|
+
letter-spacing: 8px;
|
|
85
|
+
">
|
|
86
|
+
${safeOtp}
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
|
|
90
|
+
<p style="color: #64748b; font-size: 14px;">
|
|
91
|
+
This code expires in
|
|
92
|
+
<strong>${safeExpiresIn}</strong>.
|
|
93
|
+
</p>
|
|
94
|
+
|
|
95
|
+
<p style="
|
|
96
|
+
color: #94a3b8;
|
|
97
|
+
font-size: 13px;
|
|
98
|
+
line-height: 1.6;
|
|
99
|
+
">
|
|
100
|
+
If you didn't request this code, you can safely
|
|
101
|
+
ignore this email.
|
|
102
|
+
</p>
|
|
103
|
+
|
|
104
|
+
${supportEmail
|
|
105
|
+
? `<p style="font-size: 13px; color: #64748b;">Need help? <a href="mailto:${safeSupportEmail}">${safeSupportEmail}</a></p>`
|
|
106
|
+
: ""}
|
|
107
|
+
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
<div style="
|
|
111
|
+
padding: 18px;
|
|
112
|
+
background: #f8fafc;
|
|
113
|
+
text-align: center;
|
|
114
|
+
color: #94a3b8;
|
|
115
|
+
font-size: 12px;
|
|
116
|
+
">
|
|
117
|
+
© ${new Date().getFullYear()} ${safeCompanyName}.
|
|
118
|
+
All rights reserved.
|
|
119
|
+
</div>
|
|
120
|
+
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
</body>
|
|
124
|
+
</html>
|
|
125
|
+
`;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=modern.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modern.js","sourceRoot":"","sources":["../../src/templates/modern.ts"],"names":[],"mappings":";;;AAEA,0DAAoD;AAEpD,wBAA+B,OAAwB;IACnD,MAAM,EACF,WAAW,EACX,GAAG,EACH,SAAS,GAAG,WAAW,EACvB,UAAU,GAAG,SAAS,EACtB,OAAO,EACP,YAAY,EACf,GAAG,OAAO,CAAC;IAEZ,MAAM,eAAe,GAAG,IAAA,0BAAU,EAAC,WAAW,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,IAAA,0BAAU,EAAC,GAAG,CAAC,CAAC;IAChC,MAAM,aAAa,GAAG,IAAA,0BAAU,EAAC,SAAS,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,IAAA,0BAAU,EAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvD,MAAM,gBAAgB,GAAG,YAAY;QACjC,CAAC,CAAC,IAAA,0BAAU,EAAC,YAAY,CAAC;QAC1B,CAAC,CAAC,EAAE,CAAC;IAET,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;8BA0BmB,UAAU;;;kBAIpB,OAAO;QACH,CAAC,CAAC,aAAa,WAAW,UAAU,eAAe,6CAA6C;QAChG,CAAC,CAAC,EACV;;;;;;;;;;;;;;;;;yCAiByB,eAAe;;;;;;;;;;;;;;;;;;;iCAmBvB,UAAU;;;;;0BAKjB,OAAO;;;;;;8BAMH,aAAa;;;;;;;;;;;;kBAavB,YAAY;QACR,CAAC,CAAC,0EAA0E,gBAAgB,KAAK,gBAAgB,UAAU;QAC3H,CAAC,CAAC,EACV;;;;;;;;;;;oBAWI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,eAAe;;;;;;;;KAQ1D,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.test.d.ts","sourceRoot":"","sources":["../../tests/template.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const index_js_1 = require("../src/index.js");
|
|
5
|
+
(0, vitest_1.describe)("Custom Email OTP Template", () => {
|
|
6
|
+
(0, vitest_1.it)("should generate HTML for valid OTP", () => {
|
|
7
|
+
const result = (0, index_js_1.generateOtpEmail)({
|
|
8
|
+
companyName: "My Company",
|
|
9
|
+
otp: "583921"
|
|
10
|
+
});
|
|
11
|
+
(0, vitest_1.expect)(result.html).toBeTypeOf("string");
|
|
12
|
+
(0, vitest_1.expect)(result.html).toContain("583921");
|
|
13
|
+
(0, vitest_1.expect)(result.html).toContain("My Company");
|
|
14
|
+
});
|
|
15
|
+
(0, vitest_1.it)("should throw error when company name is empty", () => {
|
|
16
|
+
(0, vitest_1.expect)(() => {
|
|
17
|
+
(0, index_js_1.generateOtpEmail)({
|
|
18
|
+
companyName: "",
|
|
19
|
+
otp: "583921"
|
|
20
|
+
});
|
|
21
|
+
}).toThrow("Company name is required.");
|
|
22
|
+
});
|
|
23
|
+
(0, vitest_1.it)("should throw error when OTP is empty", () => {
|
|
24
|
+
(0, vitest_1.expect)(() => {
|
|
25
|
+
(0, index_js_1.generateOtpEmail)({
|
|
26
|
+
companyName: "My Company",
|
|
27
|
+
otp: ""
|
|
28
|
+
});
|
|
29
|
+
}).toThrow("OTP is required.");
|
|
30
|
+
});
|
|
31
|
+
(0, vitest_1.it)("should reject invalid OTP", () => {
|
|
32
|
+
(0, vitest_1.expect)(() => {
|
|
33
|
+
(0, index_js_1.generateOtpEmail)({
|
|
34
|
+
companyName: "My Company",
|
|
35
|
+
otp: "12"
|
|
36
|
+
});
|
|
37
|
+
}).toThrow("OTP must contain 4 to 8 alphanumeric characters.");
|
|
38
|
+
});
|
|
39
|
+
(0, vitest_1.it)("should reject invalid brand color", () => {
|
|
40
|
+
(0, vitest_1.expect)(() => {
|
|
41
|
+
(0, index_js_1.generateOtpEmail)({
|
|
42
|
+
companyName: "My Company",
|
|
43
|
+
otp: "583921",
|
|
44
|
+
brandColor: "red"
|
|
45
|
+
});
|
|
46
|
+
}).toThrow("Brand color must be a valid HEX color.");
|
|
47
|
+
});
|
|
48
|
+
(0, vitest_1.it)("should escape HTML characters", () => {
|
|
49
|
+
const result = (0, index_js_1.generateOtpEmail)({
|
|
50
|
+
companyName: "<script>alert('test')</script>",
|
|
51
|
+
otp: "583921"
|
|
52
|
+
});
|
|
53
|
+
(0, vitest_1.expect)(result.html).not.toContain("<script>");
|
|
54
|
+
(0, vitest_1.expect)(result.html).toContain("<script>");
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
//# sourceMappingURL=template.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.test.js","sourceRoot":"","sources":["../../tests/template.test.ts"],"names":[],"mappings":";;AACA,mCAA8C;AAC9C,8CAAmD;AAEnD,IAAA,iBAAQ,EAAC,2BAA2B,EAAE,GAAG,EAAE;IAEvC,IAAA,WAAE,EAAC,oCAAoC,EAAE,GAAG,EAAE;QAE1C,MAAM,MAAM,GAAG,IAAA,2BAAgB,EAAC;YAC5B,WAAW,EAAE,YAAY;YACzB,GAAG,EAAE,QAAQ;SAChB,CAAC,CAAC;QAEH,IAAA,eAAM,EAAC,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QACzC,IAAA,eAAM,EAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAA,eAAM,EAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,+CAA+C,EAAE,GAAG,EAAE;QAErD,IAAA,eAAM,EAAC,GAAG,EAAE;YACR,IAAA,2BAAgB,EAAC;gBACb,WAAW,EAAE,EAAE;gBACf,GAAG,EAAE,QAAQ;aAChB,CAAC,CAAC;QACP,CAAC,CAAC,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,sCAAsC,EAAE,GAAG,EAAE;QAE5C,IAAA,eAAM,EAAC,GAAG,EAAE;YACR,IAAA,2BAAgB,EAAC;gBACb,WAAW,EAAE,YAAY;gBACzB,GAAG,EAAE,EAAE;aACV,CAAC,CAAC;QACP,CAAC,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,2BAA2B,EAAE,GAAG,EAAE;QAEjC,IAAA,eAAM,EAAC,GAAG,EAAE;YACR,IAAA,2BAAgB,EAAC;gBACb,WAAW,EAAE,YAAY;gBACzB,GAAG,EAAE,IAAI;aACZ,CAAC,CAAC;QACP,CAAC,CAAC,CAAC,OAAO,CAAC,kDAAkD,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,mCAAmC,EAAE,GAAG,EAAE;QAEzC,IAAA,eAAM,EAAC,GAAG,EAAE;YACR,IAAA,2BAAgB,EAAC;gBACb,WAAW,EAAE,YAAY;gBACzB,GAAG,EAAE,QAAQ;gBACb,UAAU,EAAE,KAAK;aACpB,CAAC,CAAC;QACP,CAAC,CAAC,CAAC,OAAO,CAAC,wCAAwC,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,+BAA+B,EAAE,GAAG,EAAE;QAErC,MAAM,MAAM,GAAG,IAAA,2BAAgB,EAAC;YAC5B,WAAW,EAAE,gCAAgC;YAC7C,GAAG,EAAE,QAAQ;SAChB,CAAC,CAAC;QAEH,IAAA,eAAM,EAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAA,eAAM,EAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AAEP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type EmailTemplate = "default" | "modern" | "dark";
|
|
2
|
+
export interface OtpEmailOptions {
|
|
3
|
+
companyName: string;
|
|
4
|
+
otp: string;
|
|
5
|
+
expiresIn?: string;
|
|
6
|
+
brandColor?: string;
|
|
7
|
+
logoUrl?: string;
|
|
8
|
+
template?: EmailTemplate;
|
|
9
|
+
supportEmail?: string;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=email.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.types.d.ts","sourceRoot":"","sources":["../../src/types/email.types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAI,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAE;AAE5D,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAG,MAAM,CAAC;IACb,SAAS,CAAC,EAAC,MAAM,CAAC;IAClB,UAAU,CAAC,EAAC,MAAM,CAAC;IACnB,OAAO,CAAC,EAAC,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAC,aAAa,CAAC;IACxB,YAAY,CAAC,EAAC,MAAM,CAAA;CACrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.types.js","sourceRoot":"","sources":["../../src/types/email.types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escapeHtml.d.ts","sourceRoot":"","sources":["../../src/utils/escapeHtml.ts"],"names":[],"mappings":"AACA,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAYhD"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.escapeHtml = escapeHtml;
|
|
4
|
+
function escapeHtml(value) {
|
|
5
|
+
return value.replace(/[&<>"']/g, (character) => {
|
|
6
|
+
const entities = {
|
|
7
|
+
"&": "&",
|
|
8
|
+
"<": "<",
|
|
9
|
+
">": ">",
|
|
10
|
+
'"': """,
|
|
11
|
+
"'": "'"
|
|
12
|
+
};
|
|
13
|
+
return entities[character];
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=escapeHtml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escapeHtml.js","sourceRoot":"","sources":["../../src/utils/escapeHtml.ts"],"names":[],"mappings":";;;AACA,oBAA2B,KAAa;IACpC,OAAO,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,SAAS,EAAE,EAAE;QAC3C,MAAM,QAAQ,GAA2B;YACrC,GAAG,EAAE,OAAO;YACZ,GAAG,EAAE,MAAM;YACX,GAAG,EAAE,MAAM;YACX,GAAG,EAAE,QAAQ;YACb,GAAG,EAAE,OAAO;SACf,CAAC;QAEF,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/utils/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAI1D,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,CAwB/D"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateOtpEmail = validateOtpEmail;
|
|
4
|
+
const validateUrl_js_1 = require("./validateUrl.js");
|
|
5
|
+
const validateEmail_js_1 = require("./validateEmail.js");
|
|
6
|
+
function validateOtpEmail(options) {
|
|
7
|
+
(0, validateUrl_js_1.validateLogoUrl)(options.logoUrl);
|
|
8
|
+
(0, validateEmail_js_1.validateEmail)(options.supportEmail);
|
|
9
|
+
if (!options) {
|
|
10
|
+
throw new Error("OTP email options are required.");
|
|
11
|
+
}
|
|
12
|
+
if (!options.companyName.trim()) {
|
|
13
|
+
throw new Error("Company name is required.");
|
|
14
|
+
}
|
|
15
|
+
if (!options.otp.trim()) {
|
|
16
|
+
throw new Error("OTP is required.");
|
|
17
|
+
}
|
|
18
|
+
if (!/^[a-zA-Z0-9]{4,8}$/.test(options.otp)) {
|
|
19
|
+
throw new Error("OTP must contain 4 to 8 alphanumeric characters.");
|
|
20
|
+
}
|
|
21
|
+
if (options.brandColor && !/^#[0-9A-Fa-f]{6}$/.test(options.brandColor)) {
|
|
22
|
+
throw new Error("Brand color must be a valid HEX color.");
|
|
23
|
+
}
|
|
24
|
+
if (options.template &&
|
|
25
|
+
!["default", "modern", "dark"].includes(options.template)) {
|
|
26
|
+
throw new Error("Invalid email template.");
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/utils/validate.ts"],"names":[],"mappings":";;;AACA,qDAAmD;AACnD,yDAAmD;AAEnD,0BAAiC,OAAwB;IACvD,IAAA,gCAAe,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACjC,IAAA,gCAAa,EAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACpC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACtC,CAAC;IACD,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACxE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC5D,CAAC;IACD,IACE,OAAO,CAAC,QAAQ;QAChB,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,EACzD,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateEmail.d.ts","sourceRoot":"","sources":["../../src/utils/validateEmail.ts"],"names":[],"mappings":"AACA,wBAAgB,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAQlD"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateEmail = validateEmail;
|
|
4
|
+
function validateEmail(email) {
|
|
5
|
+
if (!email)
|
|
6
|
+
return;
|
|
7
|
+
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
8
|
+
if (!emailPattern.test(email)) {
|
|
9
|
+
throw new Error("Please provide a valid support email.");
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=validateEmail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateEmail.js","sourceRoot":"","sources":["../../src/utils/validateEmail.ts"],"names":[],"mappings":";;;AACA,uBAA8B,KAAc;IACxC,IAAI,CAAC,KAAK;QAAE,OAAO;IAEnB,MAAM,YAAY,GAAG,4BAA4B,CAAC;IAElD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC7D,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateUrl.d.ts","sourceRoot":"","sources":["../../src/utils/validateUrl.ts"],"names":[],"mappings":"AACA,wBAAgB,eAAe,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAYlD"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateLogoUrl = validateLogoUrl;
|
|
4
|
+
function validateLogoUrl(url) {
|
|
5
|
+
if (!url)
|
|
6
|
+
return;
|
|
7
|
+
try {
|
|
8
|
+
const parsedUrl = new URL(url);
|
|
9
|
+
if (parsedUrl.protocol !== "https:") {
|
|
10
|
+
throw new Error("Logo URL must use HTTPS.");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
throw new Error("Please provide a valid HTTPS logo URL.");
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=validateUrl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateUrl.js","sourceRoot":"","sources":["../../src/utils/validateUrl.ts"],"names":[],"mappings":";;;AACA,yBAAgC,GAAY;IACxC,IAAI,CAAC,GAAG;QAAE,OAAO;IAEjB,IAAI,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAE/B,IAAI,SAAS,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAChD,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACL,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC9D,CAAC;AACL,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "custom-email-otp-template",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Customizable HTML email OTP templates for Node.js applications",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"require": "./dist/index.js",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"test:watch": "vitest",
|
|
21
|
+
"example": "tsx examples/example.ts"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"email",
|
|
25
|
+
"otp",
|
|
26
|
+
"email-template",
|
|
27
|
+
"typescript",
|
|
28
|
+
"html-email"
|
|
29
|
+
],
|
|
30
|
+
"author": "",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^26.6.6",
|
|
34
|
+
"tsx": "^4.23.15",
|
|
35
|
+
"typescript": "^7.0.2",
|
|
36
|
+
"vitest": "^5.1.0"
|
|
37
|
+
}
|
|
38
|
+
}
|