@kyro-cms/core 0.12.57 → 0.12.60
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/dist/api-handler-graphql.cjs +1 -1
- package/dist/api-handler-graphql.js +1 -1
- package/dist/api-handler-trpc.cjs +1 -1
- package/dist/api-handler-trpc.js +1 -1
- package/dist/api-handler.cjs +1 -1
- package/dist/api-handler.js +1 -1
- package/dist/bootstrap-JF6Q4L6P.cjs +1 -0
- package/dist/{bootstrap-IGHJFNYG.js → bootstrap-VUWX45QN.js} +1 -1
- package/dist/{chunk-R3KFYDRS.js → chunk-33E4YN62.js} +1 -1
- package/dist/{chunk-BAXBE4JD.js → chunk-7N6TW4JB.js} +1 -1
- package/dist/{chunk-WDDKRBSY.js → chunk-AO2IXWV4.js} +1 -1
- package/dist/{chunk-XP56DE7A.js → chunk-KWGB3YNI.js} +90 -78
- package/dist/{chunk-ECFZEY5B.cjs → chunk-M56F4LQ5.cjs} +1 -1
- package/dist/{chunk-Q4B2IRX7.cjs → chunk-NTKIONEC.cjs} +1 -1
- package/dist/{chunk-LBYY3W2D.cjs → chunk-OUMUIICN.cjs} +3 -3
- package/dist/{chunk-5VGYVQPY.js → chunk-T4TSELDS.js} +3 -3
- package/dist/{chunk-T63QLFLZ.cjs → chunk-WQCLLM4S.cjs} +3 -3
- package/dist/{chunk-VKXWJOWI.cjs → chunk-XTTGHN3D.cjs} +90 -78
- package/dist/cli/index.cjs +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +6 -8
- package/dist/index.d.ts +6 -8
- package/dist/index.js +1 -1
- package/dist/rest/index.cjs +1 -1
- package/dist/rest/index.js +1 -1
- package/package.json +2 -2
- package/dist/bootstrap-FTVBJ47D.cjs +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {a}from'./chunk-OLRCZ6E3.js';import {g as g$1}from'./chunk-Y2YAKDEQ.js';if (typeof window === "undefined") { const { createRequire } = await import(/* @vite-ignore */ 'module'); createRequire(import.meta.url); }
|
|
2
|
-
g$1();function g(i){let{brand:e,title:t,previewText:r=t,
|
|
2
|
+
g$1();function g(i){let{brand:e,title:t,previewText:r=t,bodyHtml:s,ctaText:o,ctaUrl:n,secondaryCtaText:a,secondaryCtaUrl:l}=i,p=e?.siteName||"Kyro CMS",u=e?.logoUrl||"https://kyro-cms.com/logo.svg",f=e?.logoDarkUrl||e?.logoUrl||"https://kyro-cms.com/logo-white.svg",h=e?.appUrl||"https://kyro-cms.com";return `<!DOCTYPE html>
|
|
3
3
|
<html lang="en">
|
|
4
4
|
<head>
|
|
5
5
|
<meta charset="UTF-8">
|
|
@@ -35,30 +35,25 @@ g$1();function g(i){let{brand:e,title:t,previewText:r=t,badgeText:s="Security No
|
|
|
35
35
|
}
|
|
36
36
|
</style>
|
|
37
37
|
</head>
|
|
38
|
-
<body class="email-body" style="margin: 0; padding:
|
|
38
|
+
<body class="email-body" style="margin: 0; padding: 24px 12px; background-color: #fafafa; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; color: #09090b; -webkit-font-smoothing: antialiased;">
|
|
39
39
|
<!-- Preview Text -->
|
|
40
40
|
<div style="display: none; max-height: 0; overflow: hidden;">${r}</div>
|
|
41
41
|
|
|
42
|
-
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-card" style="max-width:
|
|
42
|
+
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-card" style="max-width: 480px; margin: 0 auto; background-color: #ffffff; border: 1px solid #f4f4f5; border-radius: 16px; overflow: hidden; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.02);">
|
|
43
43
|
<!-- Header Bar -->
|
|
44
44
|
<tr>
|
|
45
|
-
<td class="email-header" style="padding:
|
|
45
|
+
<td class="email-header" style="padding: 16px 24px; border-bottom: 1px solid #fafafa; background-color: #ffffff;">
|
|
46
46
|
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0">
|
|
47
47
|
<tr>
|
|
48
|
-
<td align="
|
|
49
|
-
<a href="${
|
|
48
|
+
<td align="center" valign="middle">
|
|
49
|
+
<a href="${h}" target="_blank" style="text-decoration: none; display: inline-flex; align-items: center; gap: 8px;">
|
|
50
50
|
<!-- Light Mode Logo -->
|
|
51
|
-
<img src="${
|
|
51
|
+
<img src="${u}" alt="${p} Logo" class="logo-light" height="22" style="display: inline-block; border: 0; max-height: 22px; vertical-align: middle;" />
|
|
52
52
|
<!-- Dark Mode Logo -->
|
|
53
|
-
<img src="${
|
|
54
|
-
<span class="email-brand-text" style="font-size:
|
|
53
|
+
<img src="${f}" alt="${p} Logo" class="logo-dark" height="22" style="display: none; border: 0; max-height: 22px; vertical-align: middle;" />
|
|
54
|
+
<span class="email-brand-text" style="font-size: 15px; font-weight: 600; color: #09090b; letter-spacing: -0.2px; vertical-align: middle;">${p}</span>
|
|
55
55
|
</a>
|
|
56
56
|
</td>
|
|
57
|
-
<td align="right" valign="middle">
|
|
58
|
-
<span class="badge-status" style="display: inline-block; padding: 4px 10px; background-color: ${f}; border: 1px solid ${h}; border-radius: 9999px; font-size: 11px; font-weight: 500; color: ${y};">
|
|
59
|
-
${s}
|
|
60
|
-
</span>
|
|
61
|
-
</td>
|
|
62
57
|
</tr>
|
|
63
58
|
</table>
|
|
64
59
|
</td>
|
|
@@ -66,23 +61,23 @@ g$1();function g(i){let{brand:e,title:t,previewText:r=t,badgeText:s="Security No
|
|
|
66
61
|
|
|
67
62
|
<!-- Body Section -->
|
|
68
63
|
<tr>
|
|
69
|
-
<td style="padding:
|
|
70
|
-
<h1 class="email-title" style="margin: 0 0
|
|
64
|
+
<td style="padding: 24px;">
|
|
65
|
+
<h1 class="email-title" style="margin: 0 0 8px; font-size: 18px; font-weight: 600; color: #09090b; letter-spacing: -0.2px; text-align: center;">
|
|
71
66
|
${t}
|
|
72
67
|
</h1>
|
|
73
68
|
|
|
74
|
-
${
|
|
69
|
+
${s}
|
|
75
70
|
|
|
76
|
-
${n
|
|
71
|
+
${o&&n?`
|
|
77
72
|
<!-- Action Buttons -->
|
|
78
|
-
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="margin-top:
|
|
73
|
+
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="margin-top: 20px;">
|
|
79
74
|
<tr>
|
|
80
|
-
<td align="
|
|
81
|
-
<a href="${
|
|
82
|
-
${
|
|
75
|
+
<td align="center">
|
|
76
|
+
<a href="${n}" target="_blank" class="email-btn-primary" style="display: inline-block; padding: 10px 18px; background-color: #09090b; color: #ffffff; font-size: 13px; font-weight: 500; text-decoration: none; border-radius: 8px;">
|
|
77
|
+
${o} \u2192
|
|
83
78
|
</a>
|
|
84
|
-
${
|
|
85
|
-
${
|
|
79
|
+
${a&&l?`<a href="${l}" target="_blank" class="email-btn-secondary" style="display: inline-block; padding: 10px 16px; margin-left: 8px; background-color: #ffffff; border: 1px solid #e4e4e7; color: #09090b; font-size: 13px; font-weight: 500; text-decoration: none; border-radius: 8px;">
|
|
80
|
+
${a}
|
|
86
81
|
</a>`:""}
|
|
87
82
|
</td>
|
|
88
83
|
</tr>
|
|
@@ -92,20 +87,16 @@ g$1();function g(i){let{brand:e,title:t,previewText:r=t,badgeText:s="Security No
|
|
|
92
87
|
|
|
93
88
|
<!-- Footer -->
|
|
94
89
|
<tr>
|
|
95
|
-
<td class="email-footer" style="padding:
|
|
96
|
-
<p
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
<p style="margin: 0; font-size: 12px; color: #71717a;">
|
|
100
|
-
<a href="${x}" target="_blank" class="email-footer-link" style="color: #09090b; text-decoration: none; font-weight: 500;">${x.replace(/^https?:\/\//,"")}</a> \u2022
|
|
101
|
-
<a href="${x}/docs" target="_blank" class="email-footer-link" style="color: #09090b; text-decoration: none; font-weight: 500;">Docs</a> \u2022
|
|
102
|
-
<a href="https://github.com/danielDozie/kyro-cms" target="_blank" class="email-footer-link" style="color: #09090b; text-decoration: none; font-weight: 500;">GitHub</a>
|
|
90
|
+
<td class="email-footer" style="padding: 16px 24px; border-top: 1px solid #fafafa; background-color: #fdfdfd; text-align: center;">
|
|
91
|
+
<p style="margin: 0; font-size: 12px; color: #a1a1aa;">
|
|
92
|
+
<a href="${h}" target="_blank" class="email-footer-link" style="color: #71717a; text-decoration: none; font-weight: 500;">${h.replace(/^https?:\/\//,"")}</a> \u2022
|
|
93
|
+
<a href="${h}/docs" target="_blank" class="email-footer-link" style="color: #71717a; text-decoration: none; font-weight: 500;">Docs</a>
|
|
103
94
|
</p>
|
|
104
95
|
</td>
|
|
105
96
|
</tr>
|
|
106
97
|
</table>
|
|
107
98
|
</body>
|
|
108
|
-
</html>`}g$1();function
|
|
99
|
+
</html>`}g$1();function x(i,e="User",t){let r="Confirm your email address \u2014 Kyro CMS",s=`
|
|
109
100
|
<p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
|
|
110
101
|
Hello <strong class="email-strong" style="color: #09090b;">${e}</strong>,
|
|
111
102
|
</p>
|
|
@@ -126,14 +117,14 @@ g$1();function g(i){let{brand:e,title:t,previewText:r=t,badgeText:s="Security No
|
|
|
126
117
|
<p class="email-text" style="margin: 0 0 8px; font-size: 12px; color: #71717a;">
|
|
127
118
|
This verification link will expire in 24 hours. If you did not create an account, you can safely ignore this email.
|
|
128
119
|
</p>
|
|
129
|
-
`,o=g({brand:t,title:"Confirm Your Email Address",previewText:"Please confirm your email address to activate your Kyro CMS account.",
|
|
120
|
+
`,o=g({brand:t,title:"Confirm Your Email Address",previewText:"Please confirm your email address to activate your Kyro CMS account.",bodyHtml:s,ctaText:"Confirm Email Address",ctaUrl:i,secondaryCtaText:"Documentation",secondaryCtaUrl:"https://kyro-cms.com/docs"}),n=`Welcome, ${e}!
|
|
130
121
|
|
|
131
122
|
Please verify your email address by visiting:
|
|
132
123
|
${i}
|
|
133
124
|
|
|
134
125
|
This link expires in 24 hours.
|
|
135
126
|
|
|
136
|
-
Kyro CMS \u2014 https://kyro-cms.com`;return {subject:r,html:o,text:
|
|
127
|
+
Kyro CMS \u2014 https://kyro-cms.com`;return {subject:r,html:o,text:n}}g$1();function w(i,e="User",t){let r="Reset your password \u2014 Kyro CMS",s=`
|
|
137
128
|
<p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
|
|
138
129
|
Hello <strong class="email-strong" style="color: #09090b;">${e}</strong>,
|
|
139
130
|
</p>
|
|
@@ -154,14 +145,14 @@ Kyro CMS \u2014 https://kyro-cms.com`;return {subject:r,html:o,text:a}}g$1();fun
|
|
|
154
145
|
<p class="email-text" style="margin: 0 0 8px; font-size: 12px; color: #71717a;">
|
|
155
146
|
For security reasons, this link will expire in 1 hour. If you did not request a password reset, no further action is required.
|
|
156
147
|
</p>
|
|
157
|
-
`,o=g({brand:t,title:"Reset Your Password",previewText:"Use this secure link to reset your Kyro CMS password.",
|
|
148
|
+
`,o=g({brand:t,title:"Reset Your Password",previewText:"Use this secure link to reset your Kyro CMS password.",bodyHtml:s,ctaText:"Reset Password",ctaUrl:i}),n=`Hello ${e},
|
|
158
149
|
|
|
159
150
|
Reset your password using the following link:
|
|
160
151
|
${i}
|
|
161
152
|
|
|
162
153
|
This link will expire in 1 hour.
|
|
163
154
|
|
|
164
|
-
Kyro CMS \u2014 https://kyro-cms.com`;return {subject:r,html:o,text:
|
|
155
|
+
Kyro CMS \u2014 https://kyro-cms.com`;return {subject:r,html:o,text:n}}g$1();function _(i="User",e="https://kyro-cms.com",t){let r="Welcome to Kyro CMS!",s=`
|
|
165
156
|
<p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
|
|
166
157
|
Welcome <strong class="email-strong" style="color: #09090b;">${i}</strong>,
|
|
167
158
|
</p>
|
|
@@ -182,32 +173,42 @@ Kyro CMS \u2014 https://kyro-cms.com`;return {subject:r,html:o,text:a}}g$1();fun
|
|
|
182
173
|
</td>
|
|
183
174
|
</tr>
|
|
184
175
|
</table>
|
|
185
|
-
`,o=g({brand:t,title:"Welcome to Kyro CMS",previewText:"Your account is verified and ready. Start building content applications.",
|
|
176
|
+
`,o=g({brand:t,title:"Welcome to Kyro CMS",previewText:"Your account is verified and ready. Start building content applications.",bodyHtml:s,ctaText:"Open Dashboard",ctaUrl:e,secondaryCtaText:"Documentation",secondaryCtaUrl:"https://kyro-cms.com/docs"}),n=`Welcome to Kyro CMS, ${i}!
|
|
186
177
|
|
|
187
178
|
Your account is active. Log in at ${e} to start building.
|
|
188
179
|
|
|
189
|
-
Documentation: https://kyro-cms.com/docs`;return {subject:r,html:o,text:
|
|
190
|
-
<p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
|
|
180
|
+
Documentation: https://kyro-cms.com/docs`;return {subject:r,html:o,text:n}}g$1();function C(i="User",e,t,r){let s="Security Alert: Password Changed \u2014 Kyro CMS",o=new Date().toUTCString(),n=`
|
|
181
|
+
<p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b; text-align: center;">
|
|
191
182
|
Hello <strong class="email-strong" style="color: #09090b;">${i}</strong>,
|
|
192
183
|
</p>
|
|
193
|
-
<p class="email-text" style="margin: 0 0 20px; font-size: 14px; line-height: 1.6; color: #52525b;">
|
|
194
|
-
This email confirms that the password for your Kyro CMS account was successfully updated on <strong>${
|
|
184
|
+
<p class="email-text" style="margin: 0 0 20px; font-size: 14px; line-height: 1.6; color: #52525b; text-align: center;">
|
|
185
|
+
This email confirms that the password for your Kyro CMS account was successfully updated on <strong>${o}</strong>.
|
|
195
186
|
</p>
|
|
196
187
|
|
|
197
188
|
<!-- Security Warning Card -->
|
|
198
|
-
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-table" style="background-color: #fef2f2; border: 1px solid #fecaca; border-radius:
|
|
189
|
+
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-table" style="background-color: #fef2f2; border: 1px solid #fecaca; border-radius: 12px; margin-bottom: 20px; padding: 16px; border-collapse: separate;">
|
|
199
190
|
<tr>
|
|
200
|
-
<td style="font-size: 13px; color: #991b1b; line-height: 1.5;">
|
|
191
|
+
<td style="font-size: 13px; color: #991b1b; line-height: 1.5; text-align: center;">
|
|
201
192
|
\u26A0\uFE0F <strong>Did not request this change?</strong><br />
|
|
202
193
|
If you did not initiate this change, your account may be compromised. Reset your password immediately and contact an administrator.
|
|
203
194
|
</td>
|
|
204
195
|
</tr>
|
|
205
196
|
</table>
|
|
206
|
-
|
|
197
|
+
|
|
198
|
+
${t||r?`
|
|
199
|
+
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-table" style="background-color: #fafafa; border: 1px solid #f4f4f5; border-radius: 12px; margin-bottom: 20px; padding: 16px; border-collapse: separate;">
|
|
200
|
+
<tr>
|
|
201
|
+
<td style="font-size: 13px; color: #09090b; line-height: 1.6;" class="email-value">
|
|
202
|
+
<strong>Action IP:</strong> ${t||"Unknown"}<br />
|
|
203
|
+
<strong>Device:</strong> ${r||"Unknown"}
|
|
204
|
+
</td>
|
|
205
|
+
</tr>
|
|
206
|
+
</table>`:""}
|
|
207
|
+
`,a=g({brand:e,title:"Password Updated",previewText:"Your Kyro CMS account password was updated.",bodyHtml:n,ctaText:"Account Security",ctaUrl:"https://kyro-cms.com"}),l=`Security Alert: Your Kyro CMS password was updated at ${o}.
|
|
207
208
|
|
|
208
209
|
If you did not make this change, please reset your password immediately.
|
|
209
210
|
|
|
210
|
-
Kyro CMS \u2014 https://kyro-cms.com`;return {subject:
|
|
211
|
+
Kyro CMS \u2014 https://kyro-cms.com`;return {subject:s,html:a,text:l}}g$1();function S(i,e,t="User",r){let s="Your one-time login link \u2014 Kyro CMS",o=`
|
|
211
212
|
<p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
|
|
212
213
|
Hello <strong class="email-strong" style="color: #09090b;">${t}</strong>,
|
|
213
214
|
</p>
|
|
@@ -233,7 +234,7 @@ Kyro CMS \u2014 https://kyro-cms.com`;return {subject:t,html:o,text:a}}g$1();fun
|
|
|
233
234
|
<p class="email-text" style="margin: 0 0 8px; font-size: 12px; color: #71717a;">
|
|
234
235
|
This single-use link will expire in 10 minutes. Never share authentication links with anyone.
|
|
235
236
|
</p>
|
|
236
|
-
`,
|
|
237
|
+
`,n=g({brand:r,title:"Sign in to Kyro CMS",previewText:"Your secure magic login link for Kyro CMS.",bodyHtml:o,ctaText:"Sign In Now",ctaUrl:i}),a=`Hello ${t},
|
|
237
238
|
|
|
238
239
|
Sign in to Kyro CMS using the link below:
|
|
239
240
|
${i}${e?`
|
|
@@ -242,26 +243,36 @@ Or enter code: ${e}`:""}
|
|
|
242
243
|
|
|
243
244
|
This link expires in 10 minutes.
|
|
244
245
|
|
|
245
|
-
Kyro CMS \u2014 https://kyro-cms.com`;return {subject:s,html:
|
|
246
|
-
<p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
|
|
246
|
+
Kyro CMS \u2014 https://kyro-cms.com`;return {subject:s,html:n,text:a}}g$1();function T(i,e,t="User",r,s,o){let n="Security Alert: Account Temporarily Locked \u2014 Kyro CMS",a=`
|
|
247
|
+
<p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b; text-align: center;">
|
|
247
248
|
Hello <strong class="email-strong" style="color: #09090b;">${t}</strong>,
|
|
248
249
|
</p>
|
|
249
|
-
<p class="email-text" style="margin: 0 0 20px; font-size: 14px; line-height: 1.6; color: #52525b;">
|
|
250
|
+
<p class="email-text" style="margin: 0 0 20px; font-size: 14px; line-height: 1.6; color: #52525b; text-align: center;">
|
|
250
251
|
Your Kyro CMS account was temporarily locked after <strong>${i} failed login attempts</strong>.
|
|
251
252
|
</p>
|
|
252
253
|
|
|
253
254
|
<!-- Lockout Notice Card -->
|
|
254
|
-
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-table" style="background-color: #fffbeb; border: 1px solid #fde68a; border-radius:
|
|
255
|
+
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-table" style="background-color: #fffbeb; border: 1px solid #fde68a; border-radius: 12px; margin-bottom: 20px; padding: 16px; border-collapse: separate;">
|
|
255
256
|
<tr>
|
|
256
|
-
<td style="font-size: 13px; color: #b45309; line-height: 1.5;">
|
|
257
|
+
<td style="font-size: 13px; color: #b45309; line-height: 1.5; text-align: center;">
|
|
257
258
|
\u{1F512} <strong>Lockout duration:</strong> ${e} minutes.<br />
|
|
258
259
|
You may try logging in again after the cooling-off period expires.
|
|
259
260
|
</td>
|
|
260
261
|
</tr>
|
|
261
262
|
</table>
|
|
262
|
-
|
|
263
|
+
|
|
264
|
+
${s||o?`
|
|
265
|
+
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-table" style="background-color: #fafafa; border: 1px solid #f4f4f5; border-radius: 12px; margin-bottom: 20px; padding: 16px; border-collapse: separate;">
|
|
266
|
+
<tr>
|
|
267
|
+
<td style="font-size: 13px; color: #09090b; line-height: 1.6;" class="email-value">
|
|
268
|
+
<strong>Failed Attempts IP:</strong> ${s||"Unknown"}<br />
|
|
269
|
+
<strong>Device:</strong> ${o||"Unknown"}
|
|
270
|
+
</td>
|
|
271
|
+
</tr>
|
|
272
|
+
</table>`:""}
|
|
273
|
+
`,l=g({brand:r,title:"Account Temporarily Locked",previewText:"Your Kyro CMS account was locked due to multiple failed login attempts.",bodyHtml:a,ctaText:"Unlock Instructions",ctaUrl:"https://kyro-cms.com/docs"}),p=`Security Alert: Account temporarily locked for ${t} after ${i} failed login attempts. Unlocks in ${e} minutes.
|
|
263
274
|
|
|
264
|
-
Kyro CMS \u2014 https://kyro-cms.com`;return {subject:
|
|
275
|
+
Kyro CMS \u2014 https://kyro-cms.com`;return {subject:n,html:l,text:p}}g$1();function k(i,e="Editor",t="An Administrator",r){let s="You're invited to join Kyro CMS",o=`
|
|
265
276
|
<p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
|
|
266
277
|
Hello,
|
|
267
278
|
</p>
|
|
@@ -278,47 +289,48 @@ Kyro CMS \u2014 https://kyro-cms.com`;return {subject:s,html:a,text:n}}g$1();fun
|
|
|
278
289
|
</td>
|
|
279
290
|
</tr>
|
|
280
291
|
</table>
|
|
281
|
-
`,
|
|
292
|
+
`,n=g({brand:r,title:"Workspace Invitation",previewText:`You have been invited to join Kyro CMS as an ${e}.`,bodyHtml:o,ctaText:"Accept Invitation",ctaUrl:i,secondaryCtaText:"Documentation",secondaryCtaUrl:"https://kyro-cms.com/docs"}),a=`You're invited to join Kyro CMS as an ${e} by ${t}.
|
|
282
293
|
|
|
283
294
|
Accept your invitation here:
|
|
284
295
|
${i}
|
|
285
296
|
|
|
286
|
-
Kyro CMS \u2014 https://kyro-cms.com`;return {subject:s,html:
|
|
287
|
-
<p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
|
|
297
|
+
Kyro CMS \u2014 https://kyro-cms.com`;return {subject:s,html:n,text:a}}g$1();function E(i,e,t="User",r,s="Unknown Device"){let o="Security Alert: New Sign-in to Kyro CMS",n=`
|
|
298
|
+
<p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b; text-align: center;">
|
|
288
299
|
Hello <strong class="email-strong" style="color: #09090b;">${t}</strong>,
|
|
289
300
|
</p>
|
|
290
|
-
<p class="email-text" style="margin: 0 0 20px; font-size: 14px; line-height: 1.6; color: #52525b;">
|
|
301
|
+
<p class="email-text" style="margin: 0 0 20px; font-size: 14px; line-height: 1.6; color: #52525b; text-align: center;">
|
|
291
302
|
A new sign-in to your Kyro CMS account was detected.
|
|
292
303
|
</p>
|
|
293
304
|
|
|
294
305
|
<!-- Sign-in Details -->
|
|
295
|
-
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-table" style="background-color: #fafafa; border: 1px solid #
|
|
306
|
+
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-table" style="background-color: #fafafa; border: 1px solid #f4f4f5; border-radius: 12px; margin-bottom: 20px; padding: 16px; border-collapse: separate;">
|
|
296
307
|
<tr>
|
|
297
308
|
<td style="font-size: 13px; color: #09090b; line-height: 1.6;" class="email-value">
|
|
298
309
|
<strong>Time:</strong> ${e}<br />
|
|
299
|
-
<strong>Location/IP:</strong> ${i}
|
|
310
|
+
<strong>Location/IP:</strong> ${i}<br />
|
|
311
|
+
<strong>Device:</strong> ${s}
|
|
300
312
|
</td>
|
|
301
313
|
</tr>
|
|
302
314
|
</table>
|
|
303
315
|
|
|
304
316
|
<!-- Security Warning Card -->
|
|
305
|
-
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-table" style="background-color: #fef2f2; border: 1px solid #fecaca; border-radius:
|
|
317
|
+
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-table" style="background-color: #fef2f2; border: 1px solid #fecaca; border-radius: 12px; margin-bottom: 20px; padding: 16px; border-collapse: separate;">
|
|
306
318
|
<tr>
|
|
307
|
-
<td style="font-size: 13px; color: #991b1b; line-height: 1.5;">
|
|
319
|
+
<td style="font-size: 13px; color: #991b1b; line-height: 1.5; text-align: center;">
|
|
308
320
|
\u26A0\uFE0F <strong>Don't recognize this activity?</strong><br />
|
|
309
321
|
If you did not sign in recently, your account may be compromised. Please reset your password immediately and contact an administrator.
|
|
310
322
|
</td>
|
|
311
323
|
</tr>
|
|
312
324
|
</table>
|
|
313
|
-
`,a=g({brand:r,title:"New Sign-in Detected",previewText:"A new sign-in was detected on your Kyro CMS account.",
|
|
325
|
+
`,a=g({brand:r,title:"New Sign-in Detected",previewText:"A new sign-in was detected on your Kyro CMS account.",bodyHtml:n,ctaText:"Review Account Security",ctaUrl:"https://kyro-cms.com"}),l=`Security Alert: New Sign-in to Kyro CMS
|
|
314
326
|
|
|
315
327
|
Hello ${t},
|
|
316
328
|
|
|
317
|
-
A new sign-in to your account was detected at ${e} from ${i}.
|
|
329
|
+
A new sign-in to your account was detected at ${e} from ${i} using ${s}.
|
|
318
330
|
|
|
319
331
|
If you did not sign in recently, please reset your password immediately.
|
|
320
332
|
|
|
321
|
-
Kyro CMS \u2014 https://kyro-cms.com`;return {subject:
|
|
333
|
+
Kyro CMS \u2014 https://kyro-cms.com`;return {subject:o,html:a,text:l}}g$1();function v(i,e="Customer",t,r,s){let o=`Order Confirmation #${i}`,n=`
|
|
322
334
|
<p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
|
|
323
335
|
Hi <strong class="email-strong" style="color: #09090b;">${e}</strong>,
|
|
324
336
|
</p>
|
|
@@ -334,13 +346,13 @@ Kyro CMS \u2014 https://kyro-cms.com`;return {subject:s,html:a,text:n}}g$1();fun
|
|
|
334
346
|
</td>
|
|
335
347
|
</tr>
|
|
336
348
|
</table>
|
|
337
|
-
`,
|
|
349
|
+
`,a=g({brand:s,title:"Order Confirmed",previewText:`Your order #${i} has been confirmed.`,bodyHtml:n,ctaText:"View Order",ctaUrl:r||"https://kyro-cms.com"}),l=`Hi ${e},
|
|
338
350
|
|
|
339
351
|
Thank you for your order #${i}!
|
|
340
352
|
|
|
341
353
|
Order Total: ${t}
|
|
342
354
|
|
|
343
|
-
View your order here: ${r||"https://kyro-cms.com"}`;return {subject:o,html:
|
|
355
|
+
View your order here: ${r||"https://kyro-cms.com"}`;return {subject:o,html:a,text:l}}g$1();function A(i,e="Customer",t,r,s){let o=`Your Order #${i} is on the way!`,n=`
|
|
344
356
|
<p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
|
|
345
357
|
Great news, <strong class="email-strong" style="color: #09090b;">${e}</strong>!
|
|
346
358
|
</p>
|
|
@@ -355,12 +367,12 @@ View your order here: ${r||"https://kyro-cms.com"}`;return {subject:o,html:n,tex
|
|
|
355
367
|
</td>
|
|
356
368
|
</tr>
|
|
357
369
|
</table>
|
|
358
|
-
`,
|
|
370
|
+
`,a=g({brand:s,title:"Order Shipped",previewText:`Your order #${i} has shipped. Track your package now.`,bodyHtml:n,ctaText:"Track Package",ctaUrl:r}),l=`Hi ${e},
|
|
359
371
|
|
|
360
372
|
Your order #${i} has been shipped!
|
|
361
373
|
|
|
362
374
|
Tracking Number: ${t}
|
|
363
|
-
Track it here: ${r}`;return {subject:o,html:
|
|
375
|
+
Track it here: ${r}`;return {subject:o,html:a,text:l}}g$1();function P(i,e="Customer",t,r){let s=`Your Order #${i} has been delivered`,o=`
|
|
364
376
|
<p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
|
|
365
377
|
Hi <strong class="email-strong" style="color: #09090b;">${e}</strong>,
|
|
366
378
|
</p>
|
|
@@ -370,11 +382,11 @@ Track it here: ${r}`;return {subject:o,html:n,text:c}}g$1();function O(i,e="Cust
|
|
|
370
382
|
<p class="email-text" style="margin: 0 0 20px; font-size: 14px; line-height: 1.6; color: #52525b;">
|
|
371
383
|
We'd love to hear your thoughts. If you have a minute, please leave a review for your items.
|
|
372
384
|
</p>
|
|
373
|
-
`,
|
|
385
|
+
`,n=g({brand:r,title:"Order Delivered",previewText:`Your order #${i} has arrived!`,bodyHtml:o,ctaText:"Leave a Review",ctaUrl:t}),a=`Hi ${e},
|
|
374
386
|
|
|
375
387
|
Your order #${i} has been delivered!
|
|
376
388
|
|
|
377
|
-
Leave a review here: ${t}`;return {subject:s,html:
|
|
389
|
+
Leave a review here: ${t}`;return {subject:s,html:n,text:a}}g$1();function R(i,e="Customer",t,r){let s=`Refund Processed for Order #${i}`,o=`
|
|
378
390
|
<p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
|
|
379
391
|
Hi <strong class="email-strong" style="color: #09090b;">${e}</strong>,
|
|
380
392
|
</p>
|
|
@@ -389,32 +401,32 @@ Leave a review here: ${t}`;return {subject:s,html:a,text:n}}g$1();function K(i,e
|
|
|
389
401
|
</td>
|
|
390
402
|
</tr>
|
|
391
403
|
</table>
|
|
392
|
-
`,
|
|
404
|
+
`,n=g({brand:r,title:"Refund Processed",previewText:`We have processed a refund of ${t} for order #${i}.`,bodyHtml:o,ctaText:"View Store",ctaUrl:"https://kyro-cms.com"}),a=`Hi ${e},
|
|
393
405
|
|
|
394
406
|
We have processed a refund of ${t} for order #${i}.
|
|
395
407
|
|
|
396
|
-
View store: https://kyro-cms.com`;return {subject:s,html:
|
|
408
|
+
View store: https://kyro-cms.com`;return {subject:s,html:n,text:a}}g$1();function I(i="Customer",e,t){let r="You left something behind...",s=`
|
|
397
409
|
<p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
|
|
398
410
|
Hi <strong class="email-strong" style="color: #09090b;">${i}</strong>,
|
|
399
411
|
</p>
|
|
400
412
|
<p class="email-text" style="margin: 0 0 20px; font-size: 14px; line-height: 1.6; color: #52525b;">
|
|
401
413
|
We noticed you left some great items in your shopping cart. They are still waiting for you, but they might sell out soon!
|
|
402
414
|
</p>
|
|
403
|
-
`,o=g({brand:t,title:"Complete Your Purchase",previewText:"Your shopping cart is waiting for you. Complete your purchase now.",
|
|
415
|
+
`,o=g({brand:t,title:"Complete Your Purchase",previewText:"Your shopping cart is waiting for you. Complete your purchase now.",bodyHtml:s,ctaText:"Return to Checkout",ctaUrl:e}),n=`Hi ${i},
|
|
404
416
|
|
|
405
|
-
You left some items in your cart! Complete your purchase here: ${e}`;return {subject:r,html:o,text:
|
|
417
|
+
You left some items in your cart! Complete your purchase here: ${e}`;return {subject:r,html:o,text:n}}g$1();function O(i){return {verifyEmail:(e,t)=>x(e,t,i),resetPassword:(e,t)=>w(e,t,i),welcome:(e,t)=>_(e,t,i),passwordChanged:e=>C(e,i),magicLink:(e,t,r)=>S(e,t,r,i),accountLocked:(e,t,r)=>T(e,t,r,i),newLogin:(e,t,r)=>E(e,t,r,i),userInvite:(e,t,r)=>k(e,t,r,i),orderConfirmation:(e,t,r,s)=>v(e,t,r||"0.00",s,i),orderShipped:(e,t,r,s)=>A(e,t,r||"",s||"",i),orderDelivered:(e,t,r)=>P(e,t,r||"",i),orderRefunded:(e,t,r)=>R(e,t,r||"0.00",i),abandonedCart:(e,t)=>I(e,t||"",i)}}g$1();var $=false,b=class i{db;cache={};loaded=false;static SENSITIVE_KEYS=["storage.s3.secret_access_key","storage.r2.secret_access_key","storage.gcs.private_key","storage.backblaze.application_key","storage.wasabi.secret_access_key","storage.ftp.password","storage.bunny.api_key","storage.cloudinary.api_secret","storage.imgix.sign_key","email.smtp.pass","auth.jwt_secret","auth.github_secret","auth.google_secret","auth.app_secret","database.url","redis.url","auth.admin_password"];constructor(e){this.db=e;}async load(){if(!this.loaded){await this.ensureSettingsTable();try{if(typeof this.db?.select=="function"){let e=await this.db.select().from(a);this.cache=e.reduce((t,r)=>(t[r.key]=r.value,t),{});}await this.loadFromGlobals();}catch{console.warn("ConfigService: Could not load settings from database, using environment fallbacks.");}this.loaded=true;}}async ensureSettingsTable(){if(!$)try{if(typeof this.db?.execute=="function"){let{sql:e}=await import('./drizzle-orm-XRTSOQJS.js');await this.db.execute(e`
|
|
406
418
|
CREATE TABLE IF NOT EXISTS "settings" (
|
|
407
419
|
"key" VARCHAR(255) PRIMARY KEY,
|
|
408
420
|
"value" TEXT NOT NULL,
|
|
409
421
|
"description" TEXT,
|
|
410
422
|
"updated_at" TIMESTAMP DEFAULT NOW()
|
|
411
423
|
)
|
|
412
|
-
`)
|
|
424
|
+
`),$=!0;}else typeof this.db?.exec=="function"&&(this.db.exec(`
|
|
413
425
|
CREATE TABLE IF NOT EXISTS settings (
|
|
414
426
|
key TEXT PRIMARY KEY,
|
|
415
427
|
value TEXT NOT NULL,
|
|
416
428
|
description TEXT,
|
|
417
429
|
updated_at TEXT
|
|
418
430
|
)
|
|
419
|
-
`),M=!0);}catch{}}async loadFromGlobals(){try{let e=null;if(typeof this.db?.findOne=="function")try{let s=await this.db.findOne({collection:"_globals_storage-settings",where:{},draft:!0});s&&(e=s);}catch{}if(!e&&typeof this.db?.execute=="function"){let{sql:s}=await import('./drizzle-orm-XRTSOQJS.js'),o=['"_globals_storage-settings"','"_globals_storage_settings"','"global_storage_settings"'];for(let a of o)try{let n=await this.db.execute(s`SELECT * FROM ${s.raw(a)} LIMIT 1`);if(e=Array.isArray(n)?n[0]:n?.rows?n.rows[0]:null,e)break}catch{}}else if(!e&&typeof this.db?.prepare=="function"){let s=['"_globals_storage-settings"','"_globals_storage_settings"','"global_storage_settings"'];for(let o of s)try{if(e=this.db.prepare(`SELECT * FROM ${o} LIMIT 1`).get(),e)break}catch{}}if(!e)return;let t=s=>{if(!s)return null;if(typeof s=="string")try{return JSON.parse(s)}catch{return null}return s},r=e.provider||"local";if(this.cache["storage.type"]=r,r==="local"){let s=t(e.local);this.cache["storage.local.dir"]=s?.uploadDir||"./public/uploads",this.cache["storage.local.url"]=s?.baseUrl||"/uploads";}if(r==="aws"){let s=t(e.aws);this.cache["storage.s3.bucket"]=s?.bucket||"",this.cache["storage.s3.region"]=s?.region||"us-east-1",this.cache["storage.s3.access_key_id"]=s?.accessKeyId||"",this.cache["storage.s3.secret_access_key"]=s?.secretAccessKey||"",this.cache["storage.s3.endpoint"]=s?.endpoint||"",this.cache["storage.s3.cdn_url"]=s?.cdnUrl||"",this.cache["storage.s3.prefix"]=s?.prefix||"";}if(r==="r2"){let s=t(e.r2);this.cache["storage.r2.account_id"]=s?.accountId||"",this.cache["storage.r2.access_key_id"]=s?.accessKeyId||"",this.cache["storage.r2.secret_access_key"]=s?.secretAccessKey||"",this.cache["storage.r2.bucket"]=s?.bucket||"",this.cache["storage.r2.cdn_url"]=s?.cdnUrl||"",this.cache["storage.r2.prefix"]=s?.prefix||"";}if(r==="cloudinary"){let s=t(e.cloudinary);this.cache["storage.cloudinary.cloud_name"]=s?.cloudName||"",this.cache["storage.cloudinary.api_key"]=s?.apiKey||"",this.cache["storage.cloudinary.api_secret"]=s?.apiSecret||"",this.cache["storage.cloudinary.folder"]=s?.folder||"";}if(r==="ftp"){let s=t(e.ftp);this.cache["storage.ftp.host"]=s?.host||"",this.cache["storage.ftp.port"]=String(s?.port||"21"),this.cache["storage.ftp.user"]=s?.user||"",this.cache["storage.ftp.password"]=s?.password||"",this.cache["storage.ftp.secure"]=s?.secure?"true":"false",this.cache["storage.ftp.base_url"]=s?.baseUrl||"",this.cache["storage.ftp.prefix"]=s?.prefix||"";}}catch(e){console.warn("ConfigService: Could not load storage settings from globals table:",e);}try{let e=null;if(typeof this.db?.findOne=="function")try{let t=await this.db.findOne({collection:"_globals_email-settings",where:{},draft:!0});t&&(e=t);}catch{}if(!e&&typeof this.db?.execute=="function"){let{sql:t}=await import('./drizzle-orm-XRTSOQJS.js'),r=['"_globals_email-settings"','"_globals_email_settings"','"global_email_settings"'];for(let s of r)try{let o=await this.db.execute(t`SELECT * FROM ${t.raw(s)} LIMIT 1`);if(e=Array.isArray(o)?o[0]:o?.rows?o.rows[0]:null,e)break}catch{}}else if(!e&&typeof this.db?.prepare=="function"){let t=['"_globals_email-settings"','"_globals_email_settings"','"global_email_settings"'];for(let r of t)try{if(e=this.db.prepare(`SELECT * FROM ${r} LIMIT 1`).get(),e)break}catch{}}if(e){let t=r=>{if(!r)return null;if(typeof r=="string")try{return JSON.parse(r)}catch{return null}return r};if(this.cache["email.provider"]=e.provider||"smtp",this.cache["email.smtp.from"]=e.fromEmail||"",this.cache["email.smtp.from_name"]=e.fromName||"",this.cache["email.smtp.reply_to"]=e.replyTo||"",e.provider==="smtp"){let r=t(e.smtp);this.cache["email.smtp.host"]=r?.host||"",this.cache["email.smtp.port"]=String(r?.port||"587"),this.cache["email.smtp.user"]=r?.username||"",this.cache["email.smtp.pass"]=r?.password||"",this.cache["email.smtp.secure"]=r?.secure?"true":"false";}else if(e.provider==="resend"){let r=t(e.resend);this.cache["email.smtp.pass"]=r?.apiKey||"";}else if(e.provider==="sendgrid"){let r=t(e.sendgrid);this.cache["email.smtp.pass"]=r?.apiKey||"";}else if(e.provider==="mailgun"){let r=t(e.mailgun);this.cache["email.smtp.pass"]=r?.apiKey||"";}else if(e.provider==="ses"){let r=t(e.ses);this.cache["email.smtp.user"]=r?.accessKeyId||"",this.cache["email.smtp.pass"]=r?.secretAccessKey||"";}}}catch(e){console.warn("ConfigService: Could not load email settings from globals table:",e);}}get(e,t,r){return this.cache[e]?this.cache[e]:t&&process.env[t]?process.env[t]:r}getStorageConfig(){let e="local";return typeof globalThis.STORAGE_BUCKET<"u"&&(e="cloudflare_r2"),{type:this.get("storage.type","STORAGE_TYPE",e),s3:{bucket:this.get("storage.s3.bucket","STORAGE_BUCKET"),region:this.get("storage.s3.region","STORAGE_REGION","us-east-1"),accessKeyId:this.get("storage.s3.access_key_id","STORAGE_ACCESS_KEY_ID"),secretAccessKey:this.get("storage.s3.secret_access_key","STORAGE_SECRET_ACCESS_KEY"),endpoint:this.get("storage.s3.endpoint","STORAGE_ENDPOINT"),cdnUrl:this.get("storage.s3.cdn_url","STORAGE_CDN_URL"),prefix:this.get("storage.s3.prefix","STORAGE_PREFIX")},r2:{accountId:this.get("storage.r2.account_id","R2_ACCOUNT_ID"),accessKeyId:this.get("storage.r2.access_key_id","R2_ACCESS_KEY_ID"),secretAccessKey:this.get("storage.r2.secret_access_key","R2_SECRET_ACCESS_KEY"),bucket:this.get("storage.r2.bucket","R2_BUCKET"),cdnUrl:this.get("storage.r2.cdn_url","R2_CDN_URL"),prefix:this.get("storage.r2.prefix","R2_PREFIX")},gcs:{bucket:this.get("storage.gcs.bucket","GCS_BUCKET"),projectId:this.get("storage.gcs.project_id","GCS_PROJECT_ID"),clientEmail:this.get("storage.gcs.client_email","GCS_CLIENT_EMAIL"),privateKey:this.get("storage.gcs.private_key","GCS_PRIVATE_KEY"),cdnUrl:this.get("storage.gcs.cdn_url","GCS_CDN_URL"),prefix:this.get("storage.gcs.prefix","GCS_PREFIX")},digitalocean:{bucket:this.get("storage.digitalocean.bucket","DO_BUCKET"),region:this.get("storage.digitalocean.region","DO_REGION","nyc3"),accessKeyId:this.get("storage.digitalocean.access_key_id","DO_ACCESS_KEY_ID"),secretAccessKey:this.get("storage.digitalocean.secret_access_key","DO_SECRET_ACCESS_KEY"),cdnUrl:this.get("storage.digitalocean.cdn_url","DO_CDN_URL"),prefix:this.get("storage.digitalocean.prefix","DO_PREFIX")},backblaze:{bucket:this.get("storage.backblaze.bucket","BB_BUCKET"),accountId:this.get("storage.backblaze.account_id","BB_ACCOUNT_ID"),applicationKeyId:this.get("storage.backblaze.application_key_id","BB_APPLICATION_KEY_ID"),applicationKey:this.get("storage.backblaze.application_key","BB_APPLICATION_KEY"),cdnUrl:this.get("storage.backblaze.cdn_url","BB_CDN_URL"),prefix:this.get("storage.backblaze.prefix","BB_PREFIX")},wasabi:{bucket:this.get("storage.wasabi.bucket","WASABI_BUCKET"),region:this.get("storage.wasabi.region","WASABI_REGION","us-east-1"),accessKeyId:this.get("storage.wasabi.access_key_id","WASABI_ACCESS_KEY_ID"),secretAccessKey:this.get("storage.wasabi.secret_access_key","WASABI_SECRET_ACCESS_KEY"),cdnUrl:this.get("storage.wasabi.cdn_url","WASABI_CDN_URL"),prefix:this.get("storage.wasabi.prefix","WASABI_PREFIX")},bunny:{storageZone:this.get("storage.bunny.storage_zone","BUNNY_STORAGE_ZONE"),apiKey:this.get("storage.bunny.api_key","BUNNY_API_KEY"),cdnUrl:this.get("storage.bunny.cdn_url","BUNNY_CDN_URL"),prefix:this.get("storage.bunny.prefix","BUNNY_PREFIX")},ftp:{host:this.get("storage.ftp.host","FTP_HOST"),port:parseInt(this.get("storage.ftp.port","FTP_PORT","21"),10),user:this.get("storage.ftp.user","FTP_USER"),password:this.get("storage.ftp.password","FTP_PASSWORD"),secure:this.get("storage.ftp.secure","FTP_SECURE")==="true",baseUrl:this.get("storage.ftp.base_url","FTP_BASE_URL"),prefix:this.get("storage.ftp.prefix","FTP_PREFIX")},cloudinary:{cloudName:this.get("storage.cloudinary.cloud_name","CLOUDINARY_CLOUD_NAME"),apiKey:this.get("storage.cloudinary.api_key","CLOUDINARY_API_KEY"),apiSecret:this.get("storage.cloudinary.api_secret","CLOUDINARY_API_SECRET"),folder:this.get("storage.cloudinary.folder","CLOUDINARY_FOLDER")},imgix:{domain:this.get("storage.imgix.domain","IMGIX_DOMAIN"),signKey:this.get("storage.imgix.sign_key","IMGIX_SIGN_KEY")},local:{uploadDir:this.get("storage.local.dir","STORAGE_LOCAL_DIR","./public/uploads"),baseUrl:this.get("storage.local.url","STORAGE_LOCAL_URL","/uploads")}}}getEmailConfig(){return {provider:this.get("email.provider","EMAIL_PROVIDER","smtp"),host:this.get("email.smtp.host","SMTP_HOST"),port:parseInt(this.get("email.smtp.port","SMTP_PORT","587"),10),secure:this.get("email.smtp.secure","SMTP_SECURE")==="true",user:this.get("email.smtp.user","SMTP_USER"),pass:this.get("email.smtp.pass","SMTP_PASS"),from:this.get("email.smtp.from","SMTP_FROM","noreply@example.com"),fromName:this.get("email.smtp.from_name","SMTP_FROM_NAME","Kyro CMS"),replyTo:this.get("email.smtp.reply_to","SMTP_REPLY_TO")}}maskSensitive(e,t){return t&&(i.SENSITIVE_KEYS.includes(e)?"********":t)}async set(e,t,r){await this.db.insert(a).values({key:e,value:t,description:r,updatedAt:new Date}).onConflictDoUpdate({target:[a.key],set:{value:t,description:r,updatedAt:new Date}}),this.cache[e]=t;}};g$1();var U=class i{transporter;config;templates;transporterInitialized=false;constructor(e,t){this.config=e,this.templates={...$(e.brand),...t};}async ensureTransporter(){if(this.transporterInitialized)return this.transporter;let{default:e}=await import('./nodemailer-NITB45SS.js');return this.config.provider==="smtp"&&this.config.smtp?this.transporter=e.createTransport({host:this.config.smtp.host,port:this.config.smtp.port,secure:this.config.smtp.secure,auth:this.config.smtp.auth}):this.config.provider==="ses"&&this.config.ses&&(this.transporter=e.createTransport({host:`email-smtp.${this.config.ses.region}.amazonaws.com`,port:587,secure:false,auth:{user:this.config.ses.accessKeyId,pass:this.config.ses.secretAccessKey}})),this.transporterInitialized=true,this.transporter}async send(e){let{provider:t,from:r,fromName:s,replyTo:o}=this.config,a=`"${s||"Kyro CMS"}" <${r}>`,n=e.replyTo||o;try{let c;switch(t){case "smtp":case "ses":{let d=await this.ensureTransporter();if(!d)throw new Error(`${t} transporter not initialized`);c=await d.sendMail({from:a,to:Array.isArray(e.to)?e.to.join(", "):e.to,subject:e.subject,html:e.html,text:e.text,replyTo:n});}break;case "resend":c=await this.sendViaResend(a,e,n);break;case "sendgrid":c=await this.sendViaSendGrid(a,e,n);break;case "mailgun":c=await this.sendViaMailgun(a,e,n);break;default:throw new Error(`Unsupported email provider: ${t}`)}return c}catch(c){throw console.error("[EmailTransport] FAILED to send email:",c.message),c.response&&console.error("[EmailTransport] Provider Error Detail:",JSON.stringify(c.response,null,2)),c}}async sendViaResend(e,t,r){let s=this.config.resend?.apiKey;if(!s)throw new Error("Resend API Key missing");let o={from:e,to:t.to,subject:t.subject,html:t.html,text:t.text,reply_to:r},a=await fetch("https://api.resend.com/emails",{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json"},body:JSON.stringify(o)});if(!a.ok){let n=await a.json();throw new Error(`Resend Error: ${JSON.stringify(n)}`)}return a.json()}async sendViaSendGrid(e,t,r){let s=this.config.sendgrid?.apiKey;if(!s)throw new Error("SendGrid API Key missing");let o={personalizations:[{to:Array.isArray(t.to)?t.to.map(n=>({email:n})):[{email:t.to}]}],from:{email:e.match(/<(.+)>/)?.[1]||e,name:e.match(/"(.+)"/)?.[1]},subject:t.subject,content:[{type:"text/plain",value:t.text||""},{type:"text/html",value:t.html}],reply_to:r?{email:r}:void 0},a=await fetch("https://api.sendgrid.com/v3/mail/send",{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json"},body:JSON.stringify(o)});if(!a.ok){let n=await a.json();throw new Error(`SendGrid Error: ${JSON.stringify(n)}`)}return {success:true}}async sendViaMailgun(e,t,r){let{apiKey:s,domain:o,region:a}=this.config.mailgun||{};if(!s||!o)throw new Error("Mailgun config missing");let n=a==="eu"?"api.eu.mailgun.net":"api.mailgun.net",c=btoa(`api:${s}`),d=new URLSearchParams;d.append("from",e);let u=Array.isArray(t.to)?t.to.join(", "):t.to;d.append("to",u),d.append("subject",t.subject),d.append("html",t.html),t.text&&d.append("text",t.text),r&&d.append("h:Reply-To",r);let f=await fetch(`https://${n}/v3/${o}/messages`,{method:"POST",headers:{Authorization:`Basic ${c}`,"Content-Type":"application/x-www-form-urlencoded"},body:d});if(!f.ok){let h=await f.json();throw new Error(`Mailgun Error: ${JSON.stringify(h)}`)}return f.json()}getTemplates(){return this.templates}async verifyConnection(){if(this.config.provider==="smtp"||this.config.provider==="ses")try{let e=await this.ensureTransporter();if(e)return await e.verify(),!0}catch{return false}return !!(this.config.resend?.apiKey||this.config.sendgrid?.apiKey||this.config.mailgun?.apiKey)}static async fetchBrandConfig(e){let t="Kyro CMS",r="https://kyro-cms.com/logo.svg",s="https://kyro-cms.com/logo-white.svg";try{let o=null,a=null;if(typeof e?.findOne=="function")o=await e.findOne({collection:"_globals_store-settings",where:{},draft:!0}),a=await e.findOne({collection:"_globals_brand-settings",where:{},draft:!0});else if(typeof e?.execute=="function"){let{sql:n}=await import('./drizzle-orm-XRTSOQJS.js');try{let c=await e.execute(n`SELECT * FROM "_globals_store-settings" LIMIT 1`);o=Array.isArray(c)?c[0]:c?.rows?c.rows[0]:null;}catch{}try{let c=await e.execute(n`SELECT * FROM "_globals_brand-settings" LIMIT 1`);a=Array.isArray(c)?c[0]:c?.rows?c.rows[0]:null;}catch{}}else if(typeof e?.prepare=="function"){try{o=e.prepare('SELECT * FROM "_globals_store-settings" LIMIT 1').get();}catch{}try{a=e.prepare('SELECT * FROM "_globals_brand-settings" LIMIT 1').get();}catch{}}if(o?.storeName&&(t=o.storeName),a?.identity){let n=typeof a.identity=="string"?JSON.parse(a.identity):a.identity,c=async d=>{if(typeof e?.findOne=="function")return (await e.findOne({collection:"media",where:{id:{equals:d}}}))?.url;if(typeof e?.execute=="function"){let{sql:u}=await import('./drizzle-orm-XRTSOQJS.js');try{let f=await e.execute(u`SELECT url FROM "media" WHERE id = ${d}`);return (Array.isArray(f)?f[0]:f?.rows?f.rows[0]:null)?.url}catch{}}else if(typeof e?.prepare=="function")try{return e.prepare('SELECT url FROM "media" WHERE id = ?').get(d)?.url}catch{}};if(n.primaryLogo){let d=await c(n.primaryLogo);d&&(r=d);}if(n.darkLogo){let d=await c(n.darkLogo);d&&(s=d);}}}catch{}return {siteName:t,logoUrl:r,logoDarkUrl:s,appUrl:process.env.PUBLIC_URL||"https://kyro-cms.com"}}static async fromConfig(e){let t=new _(e);await t.load();let r=t.getEmailConfig();if(!r.provider)return this.fromEnv();let o={brand:await this.fetchBrandConfig(e),provider:r.provider||"smtp",from:r.from||"noreply@example.com",fromName:r.fromName,replyTo:r.replyTo,smtp:r.provider==="smtp"?{host:r.host||"",port:r.port||587,secure:r.secure||false,auth:{user:r.user||"",pass:r.pass||""}}:void 0,resend:r.provider==="resend"?{apiKey:r.pass||""}:void 0,sendgrid:r.provider==="sendgrid"?{apiKey:r.pass||""}:void 0,mailgun:r.provider==="mailgun"?{apiKey:r.pass||"",domain:r.host||"",region:r.secure?"eu":"us"}:void 0,ses:r.provider==="ses"?{accessKeyId:r.user||"",secretAccessKey:r.pass||"",region:r.host||"us-east-1"}:void 0};return new i(o)}static fromEnv(){let e=process.env.EMAIL_PROVIDER||"smtp",t=process.env.SMTP_FROM||process.env.DEFAULT_FROM||"noreply@example.com",r=process.env.SMTP_FROM_NAME||"Kyro CMS",s=process.env.SMTP_REPLY_TO;if(e==="smtp"){let o=process.env.SMTP_HOST,a=process.env.SMTP_USER,n=process.env.SMTP_PASS;return !o||!a||!n?null:new i({provider:"smtp",from:t,fromName:r,replyTo:s,smtp:{host:o,port:parseInt(process.env.SMTP_PORT||"587",10),secure:process.env.SMTP_SECURE==="true",auth:{user:a,pass:n}}})}if(e==="resend"){let o=process.env.RESEND_API_KEY||process.env.SMTP_PASS;return o?new i({provider:"resend",from:t,fromName:r,replyTo:s,resend:{apiKey:o}}):null}if(e==="sendgrid"){let o=process.env.SENDGRID_API_KEY||process.env.SMTP_PASS;return o?new i({provider:"sendgrid",from:t,fromName:r,replyTo:s,sendgrid:{apiKey:o}}):null}if(e==="mailgun"){let o=process.env.MAILGUN_API_KEY||process.env.SMTP_PASS,a=process.env.MAILGUN_DOMAIN||process.env.SMTP_HOST;return !o||!a?null:new i({provider:"mailgun",from:t,fromName:r,replyTo:s,mailgun:{apiKey:o,domain:a,region:process.env.MAILGUN_REGION||(process.env.SMTP_SECURE==="true"?"eu":"us")}})}if(e==="ses"){let o=process.env.AWS_ACCESS_KEY_ID||process.env.SMTP_USER,a=process.env.AWS_SECRET_ACCESS_KEY||process.env.SMTP_PASS,n=process.env.AWS_REGION||process.env.SMTP_HOST||"us-east-1";return !o||!a?null:new i({provider:"ses",from:t,fromName:r,replyTo:s,ses:{accessKeyId:o,secretAccessKey:a,region:n}})}return null}};g$1();var z={minLength:12,requireUppercase:true,requireLowercase:true,requireNumbers:true,requireSpecialChars:true,preventReuse:5,maxLength:128},B=class{config;constructor(e={}){this.config={...z,...e};}validate(e){let t=[];return this.config.maxLength&&e.length>this.config.maxLength&&t.push(`Password must not exceed ${this.config.maxLength} characters`),e.length<this.config.minLength&&t.push(`Password must be at least ${this.config.minLength} characters`),this.config.requireUppercase&&!/[A-Z]/.test(e)&&t.push("Password must contain at least one uppercase letter"),this.config.requireLowercase&&!/[a-z]/.test(e)&&t.push("Password must contain at least one lowercase letter"),this.config.requireNumbers&&!/[0-9]/.test(e)&&t.push("Password must contain at least one number"),this.config.requireSpecialChars&&!/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(e)&&t.push("Password must contain at least one special character"),["password","123456","12345678","qwerty","abc123","monkey","1234567","letmein","trustno1","dragon","baseball","iloveyou","master","sunshine","ashley","football","password1","shadow","123123","654321"].includes(e.toLowerCase())&&t.push("This password is too common. Please choose a more secure password"),(/^[a-zA-Z]+$/.test(e)||/^[0-9]+$/.test(e))&&t.push("Password must contain a mix of letters, numbers, and/or special characters"),/(.)\1{2,}/.test(e)&&t.push("Password must not contain more than 2 consecutive identical characters"),/^(012|123|234|345|456|567|678|789|890|098|987|876|765|654|543|432|321|210)+$/i.test(e)&&t.push("Password must not contain sequential numbers or letters"),{valid:t.length===0,errors:t}}async checkReuse(e,t,r){return {valid:true,errors:[]}}async isInHistory(e,t,r){for(let s of t)if(await r(e,s))return true;return false}generatePassword(e=16){let t="ABCDEFGHIJKLMNOPQRSTUVWXYZ",r="abcdefghijklmnopqrstuvwxyz",s="0123456789",o="!@#$%^&*()_+-=[]{}|;:,.<>?",a="";a+=t[Math.floor(Math.random()*t.length)],a+=r[Math.floor(Math.random()*r.length)],a+=s[Math.floor(Math.random()*s.length)],a+=o[Math.floor(Math.random()*o.length)];let n=t+r+s+o;for(let c=a.length;c<e;c++)a+=n[Math.floor(Math.random()*n.length)];return a.split("").sort(()=>Math.random()-.5).join("")}getStrength(e){let t=0,r=[];e.length>=8&&(t+=1),e.length>=12&&(t+=1),e.length>=16&&(t+=1),/[a-z]/.test(e)&&(t+=1),/[A-Z]/.test(e)&&(t+=1),/[0-9]/.test(e)&&(t+=1),/[!@#$%^&*()_+\-=\[\]{}|;:,.<>?]/.test(e)&&(t+=1),e.length>8&&(t+=1),e.length>12&&(t+=1);let s=new Set(e).size;s>6&&(t+=1),s>10&&(t+=1);let o;return t<=3?(o="Weak",r.push("Add more characters"),r.push("Include uppercase and lowercase letters")):t<=5?(o="Fair",r.push("Add special characters"),r.push("Consider making it longer")):t<=7?(o="Good",r.push("Consider making it longer for extra security")):o="Strong",{score:t,label:o,feedback:r}}setConfig(e){this.config={...this.config,...e};}getConfig(){return {...this.config}}};
|
|
420
|
-
export{g as a,
|
|
431
|
+
`),$=!0);}catch{}}async loadFromGlobals(){try{let e=null;if(typeof this.db?.findOne=="function")try{let s=await this.db.findOne({collection:"_globals_storage-settings",where:{},draft:!0});s&&(e=s);}catch{}if(!e&&typeof this.db?.execute=="function"){let{sql:s}=await import('./drizzle-orm-XRTSOQJS.js'),o=['"_globals_storage-settings"','"_globals_storage_settings"','"global_storage_settings"'];for(let n of o)try{let a=await this.db.execute(s`SELECT * FROM ${s.raw(n)} LIMIT 1`);if(e=Array.isArray(a)?a[0]:a?.rows?a.rows[0]:null,e)break}catch{}}else if(!e&&typeof this.db?.prepare=="function"){let s=['"_globals_storage-settings"','"_globals_storage_settings"','"global_storage_settings"'];for(let o of s)try{if(e=this.db.prepare(`SELECT * FROM ${o} LIMIT 1`).get(),e)break}catch{}}if(!e)return;let t=s=>{if(!s)return null;if(typeof s=="string")try{return JSON.parse(s)}catch{return null}return s},r=e.provider||"local";if(this.cache["storage.type"]=r,r==="local"){let s=t(e.local);this.cache["storage.local.dir"]=s?.uploadDir||"./public/uploads",this.cache["storage.local.url"]=s?.baseUrl||"/uploads";}if(r==="aws"){let s=t(e.aws);this.cache["storage.s3.bucket"]=s?.bucket||"",this.cache["storage.s3.region"]=s?.region||"us-east-1",this.cache["storage.s3.access_key_id"]=s?.accessKeyId||"",this.cache["storage.s3.secret_access_key"]=s?.secretAccessKey||"",this.cache["storage.s3.endpoint"]=s?.endpoint||"",this.cache["storage.s3.cdn_url"]=s?.cdnUrl||"",this.cache["storage.s3.prefix"]=s?.prefix||"";}if(r==="r2"){let s=t(e.r2);this.cache["storage.r2.account_id"]=s?.accountId||"",this.cache["storage.r2.access_key_id"]=s?.accessKeyId||"",this.cache["storage.r2.secret_access_key"]=s?.secretAccessKey||"",this.cache["storage.r2.bucket"]=s?.bucket||"",this.cache["storage.r2.cdn_url"]=s?.cdnUrl||"",this.cache["storage.r2.prefix"]=s?.prefix||"";}if(r==="cloudinary"){let s=t(e.cloudinary);this.cache["storage.cloudinary.cloud_name"]=s?.cloudName||"",this.cache["storage.cloudinary.api_key"]=s?.apiKey||"",this.cache["storage.cloudinary.api_secret"]=s?.apiSecret||"",this.cache["storage.cloudinary.folder"]=s?.folder||"";}if(r==="ftp"){let s=t(e.ftp);this.cache["storage.ftp.host"]=s?.host||"",this.cache["storage.ftp.port"]=String(s?.port||"21"),this.cache["storage.ftp.user"]=s?.user||"",this.cache["storage.ftp.password"]=s?.password||"",this.cache["storage.ftp.secure"]=s?.secure?"true":"false",this.cache["storage.ftp.base_url"]=s?.baseUrl||"",this.cache["storage.ftp.prefix"]=s?.prefix||"";}}catch(e){console.warn("ConfigService: Could not load storage settings from globals table:",e);}try{let e=null;if(typeof this.db?.findOne=="function")try{let t=await this.db.findOne({collection:"_globals_email-settings",where:{},draft:!0});t&&(e=t);}catch{}if(!e&&typeof this.db?.execute=="function"){let{sql:t}=await import('./drizzle-orm-XRTSOQJS.js'),r=['"_globals_email-settings"','"_globals_email_settings"','"global_email_settings"'];for(let s of r)try{let o=await this.db.execute(t`SELECT * FROM ${t.raw(s)} LIMIT 1`);if(e=Array.isArray(o)?o[0]:o?.rows?o.rows[0]:null,e)break}catch{}}else if(!e&&typeof this.db?.prepare=="function"){let t=['"_globals_email-settings"','"_globals_email_settings"','"global_email_settings"'];for(let r of t)try{if(e=this.db.prepare(`SELECT * FROM ${r} LIMIT 1`).get(),e)break}catch{}}if(e){let t=r=>{if(!r)return null;if(typeof r=="string")try{return JSON.parse(r)}catch{return null}return r};if(this.cache["email.provider"]=e.provider||"smtp",this.cache["email.smtp.from"]=e.fromEmail||"",this.cache["email.smtp.from_name"]=e.fromName||"",this.cache["email.smtp.reply_to"]=e.replyTo||"",e.provider==="smtp"){let r=t(e.smtp);this.cache["email.smtp.host"]=r?.host||"",this.cache["email.smtp.port"]=String(r?.port||"587"),this.cache["email.smtp.user"]=r?.username||"",this.cache["email.smtp.pass"]=r?.password||"",this.cache["email.smtp.secure"]=r?.secure?"true":"false";}else if(e.provider==="resend"){let r=t(e.resend);this.cache["email.smtp.pass"]=r?.apiKey||"";}else if(e.provider==="sendgrid"){let r=t(e.sendgrid);this.cache["email.smtp.pass"]=r?.apiKey||"";}else if(e.provider==="mailgun"){let r=t(e.mailgun);this.cache["email.smtp.pass"]=r?.apiKey||"";}else if(e.provider==="ses"){let r=t(e.ses);this.cache["email.smtp.user"]=r?.accessKeyId||"",this.cache["email.smtp.pass"]=r?.secretAccessKey||"";}}}catch(e){console.warn("ConfigService: Could not load email settings from globals table:",e);}}get(e,t,r){return this.cache[e]?this.cache[e]:t&&process.env[t]?process.env[t]:r}getStorageConfig(){let e="local";return typeof globalThis.STORAGE_BUCKET<"u"&&(e="cloudflare_r2"),{type:this.get("storage.type","STORAGE_TYPE",e),s3:{bucket:this.get("storage.s3.bucket","STORAGE_BUCKET"),region:this.get("storage.s3.region","STORAGE_REGION","us-east-1"),accessKeyId:this.get("storage.s3.access_key_id","STORAGE_ACCESS_KEY_ID"),secretAccessKey:this.get("storage.s3.secret_access_key","STORAGE_SECRET_ACCESS_KEY"),endpoint:this.get("storage.s3.endpoint","STORAGE_ENDPOINT"),cdnUrl:this.get("storage.s3.cdn_url","STORAGE_CDN_URL"),prefix:this.get("storage.s3.prefix","STORAGE_PREFIX")},r2:{accountId:this.get("storage.r2.account_id","R2_ACCOUNT_ID"),accessKeyId:this.get("storage.r2.access_key_id","R2_ACCESS_KEY_ID"),secretAccessKey:this.get("storage.r2.secret_access_key","R2_SECRET_ACCESS_KEY"),bucket:this.get("storage.r2.bucket","R2_BUCKET"),cdnUrl:this.get("storage.r2.cdn_url","R2_CDN_URL"),prefix:this.get("storage.r2.prefix","R2_PREFIX")},gcs:{bucket:this.get("storage.gcs.bucket","GCS_BUCKET"),projectId:this.get("storage.gcs.project_id","GCS_PROJECT_ID"),clientEmail:this.get("storage.gcs.client_email","GCS_CLIENT_EMAIL"),privateKey:this.get("storage.gcs.private_key","GCS_PRIVATE_KEY"),cdnUrl:this.get("storage.gcs.cdn_url","GCS_CDN_URL"),prefix:this.get("storage.gcs.prefix","GCS_PREFIX")},digitalocean:{bucket:this.get("storage.digitalocean.bucket","DO_BUCKET"),region:this.get("storage.digitalocean.region","DO_REGION","nyc3"),accessKeyId:this.get("storage.digitalocean.access_key_id","DO_ACCESS_KEY_ID"),secretAccessKey:this.get("storage.digitalocean.secret_access_key","DO_SECRET_ACCESS_KEY"),cdnUrl:this.get("storage.digitalocean.cdn_url","DO_CDN_URL"),prefix:this.get("storage.digitalocean.prefix","DO_PREFIX")},backblaze:{bucket:this.get("storage.backblaze.bucket","BB_BUCKET"),accountId:this.get("storage.backblaze.account_id","BB_ACCOUNT_ID"),applicationKeyId:this.get("storage.backblaze.application_key_id","BB_APPLICATION_KEY_ID"),applicationKey:this.get("storage.backblaze.application_key","BB_APPLICATION_KEY"),cdnUrl:this.get("storage.backblaze.cdn_url","BB_CDN_URL"),prefix:this.get("storage.backblaze.prefix","BB_PREFIX")},wasabi:{bucket:this.get("storage.wasabi.bucket","WASABI_BUCKET"),region:this.get("storage.wasabi.region","WASABI_REGION","us-east-1"),accessKeyId:this.get("storage.wasabi.access_key_id","WASABI_ACCESS_KEY_ID"),secretAccessKey:this.get("storage.wasabi.secret_access_key","WASABI_SECRET_ACCESS_KEY"),cdnUrl:this.get("storage.wasabi.cdn_url","WASABI_CDN_URL"),prefix:this.get("storage.wasabi.prefix","WASABI_PREFIX")},bunny:{storageZone:this.get("storage.bunny.storage_zone","BUNNY_STORAGE_ZONE"),apiKey:this.get("storage.bunny.api_key","BUNNY_API_KEY"),cdnUrl:this.get("storage.bunny.cdn_url","BUNNY_CDN_URL"),prefix:this.get("storage.bunny.prefix","BUNNY_PREFIX")},ftp:{host:this.get("storage.ftp.host","FTP_HOST"),port:parseInt(this.get("storage.ftp.port","FTP_PORT","21"),10),user:this.get("storage.ftp.user","FTP_USER"),password:this.get("storage.ftp.password","FTP_PASSWORD"),secure:this.get("storage.ftp.secure","FTP_SECURE")==="true",baseUrl:this.get("storage.ftp.base_url","FTP_BASE_URL"),prefix:this.get("storage.ftp.prefix","FTP_PREFIX")},cloudinary:{cloudName:this.get("storage.cloudinary.cloud_name","CLOUDINARY_CLOUD_NAME"),apiKey:this.get("storage.cloudinary.api_key","CLOUDINARY_API_KEY"),apiSecret:this.get("storage.cloudinary.api_secret","CLOUDINARY_API_SECRET"),folder:this.get("storage.cloudinary.folder","CLOUDINARY_FOLDER")},imgix:{domain:this.get("storage.imgix.domain","IMGIX_DOMAIN"),signKey:this.get("storage.imgix.sign_key","IMGIX_SIGN_KEY")},local:{uploadDir:this.get("storage.local.dir","STORAGE_LOCAL_DIR","./public/uploads"),baseUrl:this.get("storage.local.url","STORAGE_LOCAL_URL","/uploads")}}}getEmailConfig(){return {provider:this.get("email.provider","EMAIL_PROVIDER","smtp"),host:this.get("email.smtp.host","SMTP_HOST"),port:parseInt(this.get("email.smtp.port","SMTP_PORT","587"),10),secure:this.get("email.smtp.secure","SMTP_SECURE")==="true",user:this.get("email.smtp.user","SMTP_USER"),pass:this.get("email.smtp.pass","SMTP_PASS"),from:this.get("email.smtp.from","SMTP_FROM","noreply@example.com"),fromName:this.get("email.smtp.from_name","SMTP_FROM_NAME","Kyro CMS"),replyTo:this.get("email.smtp.reply_to","SMTP_REPLY_TO")}}maskSensitive(e,t){return t&&(i.SENSITIVE_KEYS.includes(e)?"********":t)}async set(e,t,r){await this.db.insert(a).values({key:e,value:t,description:r,updatedAt:new Date}).onConflictDoUpdate({target:[a.key],set:{value:t,description:r,updatedAt:new Date}}),this.cache[e]=t;}};g$1();var K=class i{transporter;config;templates;transporterInitialized=false;constructor(e,t){this.config=e,this.templates={...O(e.brand),...t};}async ensureTransporter(){if(this.transporterInitialized)return this.transporter;let{default:e}=await import('./nodemailer-NITB45SS.js');return this.config.provider==="smtp"&&this.config.smtp?this.transporter=e.createTransport({host:this.config.smtp.host,port:this.config.smtp.port,secure:this.config.smtp.secure,auth:this.config.smtp.auth}):this.config.provider==="ses"&&this.config.ses&&(this.transporter=e.createTransport({host:`email-smtp.${this.config.ses.region}.amazonaws.com`,port:587,secure:false,auth:{user:this.config.ses.accessKeyId,pass:this.config.ses.secretAccessKey}})),this.transporterInitialized=true,this.transporter}async send(e){let{provider:t,from:r,fromName:s,replyTo:o}=this.config,n=`"${s||"Kyro CMS"}" <${r}>`,a=e.replyTo||o;try{let l;switch(t){case "smtp":case "ses":{let p=await this.ensureTransporter();if(!p)throw new Error(`${t} transporter not initialized`);l=await p.sendMail({from:n,to:Array.isArray(e.to)?e.to.join(", "):e.to,subject:e.subject,html:e.html,text:e.text,replyTo:a});}break;case "resend":l=await this.sendViaResend(n,e,a);break;case "sendgrid":l=await this.sendViaSendGrid(n,e,a);break;case "mailgun":l=await this.sendViaMailgun(n,e,a);break;default:throw new Error(`Unsupported email provider: ${t}`)}return l}catch(l){throw console.error("[EmailTransport] FAILED to send email:",l.message),l.response&&console.error("[EmailTransport] Provider Error Detail:",JSON.stringify(l.response,null,2)),l}}async sendViaResend(e,t,r){let s=this.config.resend?.apiKey;if(!s)throw new Error("Resend API Key missing");let o={from:e,to:t.to,subject:t.subject,html:t.html,text:t.text,reply_to:r},n=await fetch("https://api.resend.com/emails",{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json"},body:JSON.stringify(o)});if(!n.ok){let a=await n.json();throw new Error(`Resend Error: ${JSON.stringify(a)}`)}return n.json()}async sendViaSendGrid(e,t,r){let s=this.config.sendgrid?.apiKey;if(!s)throw new Error("SendGrid API Key missing");let o={personalizations:[{to:Array.isArray(t.to)?t.to.map(a=>({email:a})):[{email:t.to}]}],from:{email:e.match(/<(.+)>/)?.[1]||e,name:e.match(/"(.+)"/)?.[1]},subject:t.subject,content:[{type:"text/plain",value:t.text||""},{type:"text/html",value:t.html}],reply_to:r?{email:r}:void 0},n=await fetch("https://api.sendgrid.com/v3/mail/send",{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json"},body:JSON.stringify(o)});if(!n.ok){let a=await n.json();throw new Error(`SendGrid Error: ${JSON.stringify(a)}`)}return {success:true}}async sendViaMailgun(e,t,r){let{apiKey:s,domain:o,region:n}=this.config.mailgun||{};if(!s||!o)throw new Error("Mailgun config missing");let a=n==="eu"?"api.eu.mailgun.net":"api.mailgun.net",l=btoa(`api:${s}`),p=new URLSearchParams;p.append("from",e);let u=Array.isArray(t.to)?t.to.join(", "):t.to;p.append("to",u),p.append("subject",t.subject),p.append("html",t.html),t.text&&p.append("text",t.text),r&&p.append("h:Reply-To",r);let f=await fetch(`https://${a}/v3/${o}/messages`,{method:"POST",headers:{Authorization:`Basic ${l}`,"Content-Type":"application/x-www-form-urlencoded"},body:p});if(!f.ok){let h=await f.json();throw new Error(`Mailgun Error: ${JSON.stringify(h)}`)}return f.json()}getTemplates(){return this.templates}async verifyConnection(){if(this.config.provider==="smtp"||this.config.provider==="ses")try{let e=await this.ensureTransporter();if(e)return await e.verify(),!0}catch{return false}return !!(this.config.resend?.apiKey||this.config.sendgrid?.apiKey||this.config.mailgun?.apiKey)}static async fetchBrandConfig(e){let t="Kyro CMS",r="https://kyro-cms.com/logo.svg",s="https://kyro-cms.com/logo-white.svg";try{let o=null,n=null;if(typeof e?.findOne=="function")o=await e.findOne({collection:"_globals_store-settings",where:{},draft:!0}),n=await e.findOne({collection:"_globals_brand-settings",where:{},draft:!0});else if(typeof e?.execute=="function"){let{sql:a}=await import('./drizzle-orm-XRTSOQJS.js');try{let l=await e.execute(a`SELECT * FROM "_globals_store-settings" LIMIT 1`);o=Array.isArray(l)?l[0]:l?.rows?l.rows[0]:null;}catch{}try{let l=await e.execute(a`SELECT * FROM "_globals_brand-settings" LIMIT 1`);n=Array.isArray(l)?l[0]:l?.rows?l.rows[0]:null;}catch{}}else if(typeof e?.prepare=="function"){try{o=e.prepare('SELECT * FROM "_globals_store-settings" LIMIT 1').get();}catch{}try{n=e.prepare('SELECT * FROM "_globals_brand-settings" LIMIT 1').get();}catch{}}if(o?.storeName&&(t=o.storeName),n?.identity){let a=typeof n.identity=="string"?JSON.parse(n.identity):n.identity,l=async p=>{if(typeof e?.findOne=="function")return (await e.findOne({collection:"media",where:{id:{equals:p}}}))?.url;if(typeof e?.execute=="function"){let{sql:u}=await import('./drizzle-orm-XRTSOQJS.js');try{let f=await e.execute(u`SELECT url FROM "media" WHERE id = ${p}`);return (Array.isArray(f)?f[0]:f?.rows?f.rows[0]:null)?.url}catch{}}else if(typeof e?.prepare=="function")try{return e.prepare('SELECT url FROM "media" WHERE id = ?').get(p)?.url}catch{}};if(a.primaryLogo){let p=await l(a.primaryLogo);p&&(r=p);}if(a.darkLogo){let p=await l(a.darkLogo);p&&(s=p);}}}catch{}return {siteName:t,logoUrl:r,logoDarkUrl:s,appUrl:process.env.PUBLIC_URL||"https://kyro-cms.com"}}static async fromConfig(e){let t=new b(e);await t.load();let r=t.getEmailConfig();if(!r.provider)return this.fromEnv();let o={brand:await this.fetchBrandConfig(e),provider:r.provider||"smtp",from:r.from||"noreply@example.com",fromName:r.fromName,replyTo:r.replyTo,smtp:r.provider==="smtp"?{host:r.host||"",port:r.port||587,secure:r.secure||false,auth:{user:r.user||"",pass:r.pass||""}}:void 0,resend:r.provider==="resend"?{apiKey:r.pass||""}:void 0,sendgrid:r.provider==="sendgrid"?{apiKey:r.pass||""}:void 0,mailgun:r.provider==="mailgun"?{apiKey:r.pass||"",domain:r.host||"",region:r.secure?"eu":"us"}:void 0,ses:r.provider==="ses"?{accessKeyId:r.user||"",secretAccessKey:r.pass||"",region:r.host||"us-east-1"}:void 0};return new i(o)}static fromEnv(){let e=process.env.EMAIL_PROVIDER||"smtp",t=process.env.SMTP_FROM||process.env.DEFAULT_FROM||"noreply@example.com",r=process.env.SMTP_FROM_NAME||"Kyro CMS",s=process.env.SMTP_REPLY_TO;if(e==="smtp"){let o=process.env.SMTP_HOST,n=process.env.SMTP_USER,a=process.env.SMTP_PASS;return !o||!n||!a?null:new i({provider:"smtp",from:t,fromName:r,replyTo:s,smtp:{host:o,port:parseInt(process.env.SMTP_PORT||"587",10),secure:process.env.SMTP_SECURE==="true",auth:{user:n,pass:a}}})}if(e==="resend"){let o=process.env.RESEND_API_KEY||process.env.SMTP_PASS;return o?new i({provider:"resend",from:t,fromName:r,replyTo:s,resend:{apiKey:o}}):null}if(e==="sendgrid"){let o=process.env.SENDGRID_API_KEY||process.env.SMTP_PASS;return o?new i({provider:"sendgrid",from:t,fromName:r,replyTo:s,sendgrid:{apiKey:o}}):null}if(e==="mailgun"){let o=process.env.MAILGUN_API_KEY||process.env.SMTP_PASS,n=process.env.MAILGUN_DOMAIN||process.env.SMTP_HOST;return !o||!n?null:new i({provider:"mailgun",from:t,fromName:r,replyTo:s,mailgun:{apiKey:o,domain:n,region:process.env.MAILGUN_REGION||(process.env.SMTP_SECURE==="true"?"eu":"us")}})}if(e==="ses"){let o=process.env.AWS_ACCESS_KEY_ID||process.env.SMTP_USER,n=process.env.AWS_SECRET_ACCESS_KEY||process.env.SMTP_PASS,a=process.env.AWS_REGION||process.env.SMTP_HOST||"us-east-1";return !o||!n?null:new i({provider:"ses",from:t,fromName:r,replyTo:s,ses:{accessKeyId:o,secretAccessKey:n,region:a}})}return null}};g$1();var U={minLength:12,requireUppercase:true,requireLowercase:true,requireNumbers:true,requireSpecialChars:true,preventReuse:5,maxLength:128},M=class{config;constructor(e={}){this.config={...U,...e};}validate(e){let t=[];return this.config.maxLength&&e.length>this.config.maxLength&&t.push(`Password must not exceed ${this.config.maxLength} characters`),e.length<this.config.minLength&&t.push(`Password must be at least ${this.config.minLength} characters`),this.config.requireUppercase&&!/[A-Z]/.test(e)&&t.push("Password must contain at least one uppercase letter"),this.config.requireLowercase&&!/[a-z]/.test(e)&&t.push("Password must contain at least one lowercase letter"),this.config.requireNumbers&&!/[0-9]/.test(e)&&t.push("Password must contain at least one number"),this.config.requireSpecialChars&&!/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(e)&&t.push("Password must contain at least one special character"),["password","123456","12345678","qwerty","abc123","monkey","1234567","letmein","trustno1","dragon","baseball","iloveyou","master","sunshine","ashley","football","password1","shadow","123123","654321"].includes(e.toLowerCase())&&t.push("This password is too common. Please choose a more secure password"),(/^[a-zA-Z]+$/.test(e)||/^[0-9]+$/.test(e))&&t.push("Password must contain a mix of letters, numbers, and/or special characters"),/(.)\1{2,}/.test(e)&&t.push("Password must not contain more than 2 consecutive identical characters"),/^(012|123|234|345|456|567|678|789|890|098|987|876|765|654|543|432|321|210)+$/i.test(e)&&t.push("Password must not contain sequential numbers or letters"),{valid:t.length===0,errors:t}}async checkReuse(e,t,r){return {valid:true,errors:[]}}async isInHistory(e,t,r){for(let s of t)if(await r(e,s))return true;return false}generatePassword(e=16){let t="ABCDEFGHIJKLMNOPQRSTUVWXYZ",r="abcdefghijklmnopqrstuvwxyz",s="0123456789",o="!@#$%^&*()_+-=[]{}|;:,.<>?",n="";n+=t[Math.floor(Math.random()*t.length)],n+=r[Math.floor(Math.random()*r.length)],n+=s[Math.floor(Math.random()*s.length)],n+=o[Math.floor(Math.random()*o.length)];let a=t+r+s+o;for(let l=n.length;l<e;l++)n+=a[Math.floor(Math.random()*a.length)];return n.split("").sort(()=>Math.random()-.5).join("")}getStrength(e){let t=0,r=[];e.length>=8&&(t+=1),e.length>=12&&(t+=1),e.length>=16&&(t+=1),/[a-z]/.test(e)&&(t+=1),/[A-Z]/.test(e)&&(t+=1),/[0-9]/.test(e)&&(t+=1),/[!@#$%^&*()_+\-=\[\]{}|;:,.<>?]/.test(e)&&(t+=1),e.length>8&&(t+=1),e.length>12&&(t+=1);let s=new Set(e).size;s>6&&(t+=1),s>10&&(t+=1);let o;return t<=3?(o="Weak",r.push("Add more characters"),r.push("Include uppercase and lowercase letters")):t<=5?(o="Fair",r.push("Add special characters"),r.push("Consider making it longer")):t<=7?(o="Good",r.push("Consider making it longer for extra security")):o="Strong",{score:t,label:o,feedback:r}}setConfig(e){this.config={...this.config,...e};}getConfig(){return {...this.config}}};
|
|
432
|
+
export{g as a,x as b,w as c,_ as d,C as e,S as f,T as g,k as h,E as i,v as j,A as k,P as l,R as m,I as n,O as o,b as p,K as q,M as r};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var
|
|
1
|
+
'use strict';var chunkXTTGHN3D_cjs=require('./chunk-XTTGHN3D.cjs'),chunkBHR7OAU4_cjs=require('./chunk-BHR7OAU4.cjs'),chunkBUNLC3II_cjs=require('./chunk-BUNLC3II.cjs');chunkBUNLC3II_cjs.h();async function g(t){let{adminEmail:e,adminPassword:r,adminRole:a="super_admin",tenantId:n,emailConfig:o,sendWelcomeEmail:c=false}=t,s=t.authAdapter||new chunkBHR7OAU4_cjs.a({path:t.authDbPath||"./data/auth.db"});try{await s.connect?.();}catch{return {success:false,error:"Failed to connect to auth storage"}}let u=new chunkXTTGHN3D_cjs.r().validate(r);if(!u.valid)return await s.disconnect?.(),{success:false,error:`Invalid password: ${u.errors.join(", ")}`};if(await s.findUserByEmail(e))return await s.disconnect?.(),{success:false,error:"Admin user already exists"};try{let i=await s.createUser({name:"Super Admin",email:e,password:r,role:a||"admin",tenantId:n});if(await s.updateUser?.(i.id,{emailVerified:!0}),c&&o){let l=new chunkXTTGHN3D_cjs.q(o),A=l.getTemplates().welcome(e.split("@")[0]);await l.send({to:e,...A});}return await s.disconnect?.(),{success:!0,user:i}}catch(i){return await s.disconnect?.(),{success:false,error:i instanceof Error?i.message:"Failed to create admin user"}}}async function U(t,e){return !await t.findUserByEmail(e)}function w(t){let e=t.KYRO_ADMIN_EMAIL,r=t.KYRO_ADMIN_PASSWORD;return !e||!r?null:{authDbPath:t.KYRO_AUTH_DB_PATH||"./data/auth.db",adminEmail:e,adminPassword:r,adminRole:t.KYRO_ADMIN_ROLE||"super_admin",tenantId:t.KYRO_ADMIN_TENANT_ID,emailConfig:t.SMTP_HOST?{provider:"smtp",smtp:{host:t.SMTP_HOST,port:parseInt(t.SMTP_PORT||"587",10),secure:t.SMTP_SECURE==="true",auth:{user:t.SMTP_USER||"",pass:t.SMTP_PASS||""}},from:t.SMTP_FROM||"noreply@example.com",fromName:t.SMTP_FROM_NAME}:void 0,sendWelcomeEmail:t.KYRO_ADMIN_SEND_WELCOME==="true"}}function h(){return w(process.env)}async function E(){try{let{env:t}=await import('cloudflare:workers');if(t){let e=w(t);if(e)return e}}catch{}return null}async function M(t){let e=h()||await E();if(!e)return null;t&&(e.authAdapter=t);try{if(await e.authAdapter?.connect?.(),await e.authAdapter?.findUserByEmail(e.adminEmail))return await e.authAdapter?.disconnect?.(),{success:!1,error:"Admin user already exists"}}catch{}let r=await g(e);return r.success||console.error(`Bootstrap failed: ${r.error}`),r}async function x(t,e=3,r=2e3){let a="";for(let n=0;n<e;n++){let o=await g(t);if(o.success||(a=o.error||"Unknown error",a.includes("already exists")))return o;n<e-1&&await new Promise(c=>setTimeout(c,r));}return {success:false,error:`Failed after ${e} retries: ${a}`}}exports.a=g;exports.b=U;exports.c=w;exports.d=h;exports.e=M;exports.f=x;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var
|
|
1
|
+
'use strict';var chunkWQCLLM4S_cjs=require('./chunk-WQCLLM4S.cjs'),chunkM56F4LQ5_cjs=require('./chunk-M56F4LQ5.cjs'),chunkOUMUIICN_cjs=require('./chunk-OUMUIICN.cjs'),chunkBHR7OAU4_cjs=require('./chunk-BHR7OAU4.cjs'),chunkTDGSIF5H_cjs=require('./chunk-TDGSIF5H.cjs'),chunkXBQ6HV3T_cjs=require('./chunk-XBQ6HV3T.cjs'),chunk7DUKWHRN_cjs=require('./chunk-7DUKWHRN.cjs'),chunkBUNLC3II_cjs=require('./chunk-BUNLC3II.cjs'),w=require('kyro:config');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var w__default=/*#__PURE__*/_interopDefault(w);chunkBUNLC3II_cjs.h();exports.a=null;var l=null;async function b(){if(!exports.a){if(globalThis.__KYRO_INSTANCE__)try{await globalThis.__KYRO_INSTANCE__.shutdown();}catch{}try{let e=w__default.default.default||w__default.default,t=e.adapter,o=t&&!t.dialect&&typeof t.connect=="function";if(globalThis.DB&&(!t||o)){let s=globalThis.DB;e.adapter=new chunkTDGSIF5H_cjs.c({type:"sqlite",client:s}),chunkWQCLLM4S_cjs.D.info("Hot-swapped to D1 DrizzleAdapter");}exports.a=chunkWQCLLM4S_cjs.A(e),await exports.a.init();let a=e.adapter,p=a&&a.dialect&&(a.dialect==="postgres"||a.dialect==="sqlite"),c=a&&a.dialect==="mongodb",n;if(p)a.dialect==="postgres"?n=new chunkXBQ6HV3T_cjs.a({db:a.client}):a.dialect==="sqlite"&&(n=new chunkOUMUIICN_cjs.fb({db:a.rawClient||a.client}));else if(o&&!globalThis.DB){let s=process.env.KYRO_AUTH_DB_PATH||"./data/auth.db";n=new chunkBHR7OAU4_cjs.a({path:s});}else c&&(n=new chunk7DUKWHRN_cjs.a({adapter:a}));if(n?.connect)try{await n.connect();}catch(s){chunkWQCLLM4S_cjs.D.warn("Auth connect warning:",s);}try{await exports.a.loadSettings();}catch(s){chunkWQCLLM4S_cjs.D.warn("loadSettings warning:",s);}try{await chunkM56F4LQ5_cjs.e(n);}catch(s){chunkWQCLLM4S_cjs.D.warn("autoBootstrap warning:",s);}globalThis.__KYRO_INSTANCE__=exports.a;}catch(e){throw exports.a=null,l=null,chunkWQCLLM4S_cjs.D.error("Init failed, will retry:",e),e}}}async function E(e){let t=globalThis.DB?globalThis:null;try{let{env:o}=await import('cloudflare:workers');o&&(t=o);}catch{}if(e)try{t=e.locals?.cfContext?.env||e?.env||t;}catch{}if(!t)try{t=process.env;}catch{}t?.DB&&(globalThis.DB=t.DB),t?.STORAGE_BUCKET&&(globalThis.STORAGE_BUCKET=t.STORAGE_BUCKET),l||(l=b()),await l;}var _={graphqlEnabled:false,trpcEnabled:false,wsEnabled:false,requireAuth:false};function T(e){return exports.a?exports.a.settings?.access?.apiAccess?.[e]??_[e]??true:_[e]??true}var R=async e=>{if(!exports.a)try{await Promise.race([E(e),new Promise((t,o)=>setTimeout(()=>o(new Error("Initialization timeout")),3e4))]);}catch(t){return console.error("[Kyro API] Warm error:",t?.stack||t?.message||t),new Response(JSON.stringify({error:"Service Unavailable",message:"Kyro CMS is still starting up. Please try again in a moment."}),{status:503,headers:{"Content-Type":"application/json","Retry-After":"5"}})}try{let o=new URL(e.request.url).pathname,a=__KYRO_API_PATH__;if(o===`${a}/graphql`&&typeof exports.a.getGraphQL=="function"){if(!T("graphqlEnabled"))return new Response(JSON.stringify({error:"GraphQL is disabled"}),{status:503,headers:{"Content-Type":"application/json"}});let n=await exports.a.getGraphQL().fetch(e.request,e.locals);return new Response(n.body,n)}if(o.startsWith(`${a}/trpc/`)&&typeof exports.a.getTRPC=="function"){if(!T("trpcEnabled"))return new Response(JSON.stringify({error:"tRPC is disabled"}),{status:503,headers:{"Content-Type":"application/json"}});let n=await exports.a.getTRPC().fetch(e.request,e.locals);return new Response(n.body,n)}return await(await exports.a.getREST()).fetch(e.request,e.locals)}catch(t){return console.error("[Kyro API Execution Error]:",t?.stack||t?.message||t),new Response(JSON.stringify({error:"Internal Server Error",message:t?.message||String(t),stack:t?.stack}),{status:500,headers:{"Content-Type":"application/json"}})}},L=R;exports.b=E;exports.c=R;exports.d=L;
|