@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.
@@ -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,badgeText:s="Security Notification",badgeType:o="info",bodyHtml:a,ctaText:n,ctaUrl:c,secondaryCtaText:d,secondaryCtaUrl:u}=i,f="#eff6ff",h="#bfdbfe",y="#1d4ed8";o==="success"?(f="#ecfdf5",h="#a7f3d0",y="#047857"):o==="warning"?(f="#fffbeb",h="#fde68a",y="#b45309"):o==="error"&&(f="#fef2f2",h="#fecaca",y="#b91c1c");let b=e?.siteName||"Kyro CMS",N=e?.logoUrl||"https://kyro-cms.com/logo.svg",D=e?.logoDarkUrl||e?.logoUrl||"https://kyro-cms.com/logo-white.svg",x=e?.appUrl||"https://kyro-cms.com";return `<!DOCTYPE html>
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: 36px 16px; background-color: #f4f4f5; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; color: #09090b; -webkit-font-smoothing: antialiased;">
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: 540px; margin: 0 auto; background-color: #ffffff; border: 1px solid #e4e4e7; border-radius: 12px; overflow: hidden; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.03);">
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: 22px 28px; border-bottom: 1px solid #f4f4f5; background-color: #ffffff;">
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="left" valign="middle">
49
- <a href="${x}" target="_blank" style="text-decoration: none; display: inline-flex; align-items: center; gap: 10px;">
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="${N}" alt="${b} Logo" class="logo-light" height="24" style="display: inline-block; border: 0; max-height: 24px; vertical-align: middle;" />
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="${D}" alt="${b} Logo" class="logo-dark" height="24" style="display: none; border: 0; max-height: 24px; vertical-align: middle;" />
54
- <span class="email-brand-text" style="font-size: 16px; font-weight: 700; color: #09090b; letter-spacing: -0.3px; vertical-align: middle;">${b}</span>
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: 28px;">
70
- <h1 class="email-title" style="margin: 0 0 12px; font-size: 20px; font-weight: 600; color: #09090b; letter-spacing: -0.3px;">
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
- ${a}
69
+ ${s}
75
70
 
76
- ${n&&c?`
71
+ ${o&&n?`
77
72
  <!-- Action Buttons -->
78
- <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="margin-top: 24px;">
73
+ <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="margin-top: 20px;">
79
74
  <tr>
80
- <td align="left">
81
- <a href="${c}" target="_blank" class="email-btn-primary" style="display: inline-block; padding: 11px 20px; background-color: #09090b; color: #ffffff; font-size: 13px; font-weight: 500; text-decoration: none; border-radius: 6px;">
82
- ${n} \u2192
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
- ${d&&u?`<a href="${u}" target="_blank" class="email-btn-secondary" style="display: inline-block; padding: 11px 16px; margin-left: 8px; background-color: #ffffff; border: 1px solid #e4e4e7; color: #09090b; font-size: 13px; font-weight: 500; text-decoration: none; border-radius: 6px;">
85
- ${d}
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: 18px 28px; border-top: 1px solid #f4f4f5; background-color: #fafafa; text-align: center;">
96
- <p class="email-footer-text" style="margin: 0 0 8px; font-size: 12px; color: #71717a;">
97
- Sent securely via <strong>${b} Authentication Engine</strong>.
98
- </p>
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> &nbsp;\u2022&nbsp;
101
- <a href="${x}/docs" target="_blank" class="email-footer-link" style="color: #09090b; text-decoration: none; font-weight: 500;">Docs</a> &nbsp;\u2022&nbsp;
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> &nbsp;\u2022&nbsp;
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 T(i,e="User",t){let r="Confirm your email address \u2014 Kyro CMS",s=`
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.",badgeText:"Action Required",badgeType:"warning",bodyHtml:s,ctaText:"Confirm Email Address",ctaUrl:i,secondaryCtaText:"Documentation",secondaryCtaUrl:"https://kyro-cms.com/docs"}),a=`Welcome, ${e}!
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:a}}g$1();function S(i,e="User",t){let r="Reset your password \u2014 Kyro CMS",s=`
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.",badgeText:"Security Action",badgeType:"warning",bodyHtml:s,ctaText:"Reset Password",ctaUrl:i}),a=`Hello ${e},
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:a}}g$1();function C(i="User",e="https://kyro-cms.com",t){let r="Welcome to Kyro CMS!",s=`
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.",badgeText:"Account Ready",badgeType:"success",bodyHtml:s,ctaText:"Open Dashboard",ctaUrl:e,secondaryCtaText:"Documentation",secondaryCtaUrl:"https://kyro-cms.com/docs"}),a=`Welcome to Kyro CMS, ${i}!
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:a}}g$1();function k(i="User",e){let t="Security Alert: Password Changed \u2014 Kyro CMS",r=new Date().toUTCString(),s=`
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>${r}</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: 8px; margin-bottom: 20px; padding: 14px; border-collapse: separate;">
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
- `,o=g({brand:e,title:"Password Updated",previewText:"Your Kyro CMS account password was updated.",badgeText:"Security Alert",badgeType:"warning",bodyHtml:s,ctaText:"Account Security",ctaUrl:"https://kyro-cms.com"}),a=`Security Alert: Your Kyro CMS password was updated at ${r}.
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:t,html:o,text:a}}g$1();function E(i,e,t="User",r){let s="Your one-time login link \u2014 Kyro CMS",o=`
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
- `,a=g({brand:r,title:"Sign in to Kyro CMS",previewText:"Your secure magic login link for Kyro CMS.",badgeText:"Instant Login",badgeType:"info",bodyHtml:o,ctaText:"Sign In Now",ctaUrl:i}),n=`Hello ${t},
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:a,text:n}}g$1();function v(i,e,t="User",r){let s="Security Alert: Account Temporarily Locked \u2014 Kyro CMS",o=`
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: 8px; margin-bottom: 20px; padding: 14px; border-collapse: separate;">
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
- `,a=g({brand:r,title:"Account Temporarily Locked",previewText:"Your Kyro CMS account was locked due to multiple failed login attempts.",badgeText:"Security Lockout",badgeType:"warning",bodyHtml:o,ctaText:"Unlock Instructions",ctaUrl:"https://kyro-cms.com/docs"}),n=`Security Alert: Account temporarily locked for ${t} after ${i} failed login attempts. Unlocks in ${e} minutes.
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:s,html:a,text:n}}g$1();function A(i,e="Editor",t="An Administrator",r){let s="You're invited to join Kyro CMS",o=`
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
- `,a=g({brand:r,title:"Workspace Invitation",previewText:`You have been invited to join Kyro CMS as an ${e}.`,badgeText:"Team Invite",badgeType:"info",bodyHtml:o,ctaText:"Accept Invitation",ctaUrl:i,secondaryCtaText:"Documentation",secondaryCtaUrl:"https://kyro-cms.com/docs"}),n=`You're invited to join Kyro CMS as an ${e} by ${t}.
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:a,text:n}}g$1();function R(i,e,t="User",r){let s="Security Alert: New Sign-in to Kyro CMS",o=`
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 #e4e4e7; border-radius: 8px; margin-bottom: 20px; padding: 14px; border-collapse: separate;">
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: 8px; margin-bottom: 20px; padding: 14px; border-collapse: separate;">
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.",badgeText:"Security Alert",badgeType:"warning",bodyHtml:o,ctaText:"Review Account Security",ctaUrl:"https://kyro-cms.com"}),n=`Security Alert: New Sign-in to Kyro CMS
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:s,html:a,text:n}}g$1();function P(i,e="Customer",t,r,s){let o=`Order Confirmation #${i}`,a=`
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
- `,n=g({brand:s,title:"Order Confirmed",previewText:`Your order #${i} has been confirmed.`,badgeText:"Confirmed",badgeType:"success",bodyHtml:a,ctaText:"View Order",ctaUrl:r||"https://kyro-cms.com"}),c=`Hi ${e},
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:n,text:c}}g$1();function I(i,e="Customer",t,r,s){let o=`Your Order #${i} is on the way!`,a=`
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
- `,n=g({brand:s,title:"Order Shipped",previewText:`Your order #${i} has shipped. Track your package now.`,badgeText:"Shipped",badgeType:"info",bodyHtml:a,ctaText:"Track Package",ctaUrl:r}),c=`Hi ${e},
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:n,text:c}}g$1();function O(i,e="Customer",t,r){let s=`Your Order #${i} has been delivered`,o=`
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
- `,a=g({brand:r,title:"Order Delivered",previewText:`Your order #${i} has arrived!`,badgeText:"Delivered",badgeType:"success",bodyHtml:o,ctaText:"Leave a Review",ctaUrl:t}),n=`Hi ${e},
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:a,text:n}}g$1();function K(i,e="Customer",t,r){let s=`Refund Processed for Order #${i}`,o=`
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
- `,a=g({brand:r,title:"Refund Processed",previewText:`We have processed a refund of ${t} for order #${i}.`,badgeText:"Refunded",badgeType:"info",bodyHtml:o,ctaText:"View Store",ctaUrl:"https://kyro-cms.com"}),n=`Hi ${e},
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:a,text:n}}g$1();function L(i="Customer",e,t){let r="You left something behind...",s=`
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.",badgeText:"Cart Reminder",badgeType:"warning",bodyHtml:s,ctaText:"Return to Checkout",ctaUrl:e}),a=`Hi ${i},
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:a}}g$1();function $(i){return {verifyEmail:(e,t)=>T(e,t,i),resetPassword:(e,t)=>S(e,t,i),welcome:(e,t)=>C(e,t,i),passwordChanged:e=>k(e,i),magicLink:(e,t,r)=>E(e,t,r,i),accountLocked:(e,t,r)=>v(e,t,r,i),newLogin:(e,t,r)=>R(e,t,r,i),userInvite:(e,t,r)=>A(e,t,r,i),orderConfirmation:(e,t,r,s)=>P(e,t,r||"0.00",s,i),orderShipped:(e,t,r,s)=>I(e,t,r||"",s||"",i),orderDelivered:(e,t,r)=>O(e,t,r||"",i),orderRefunded:(e,t,r)=>K(e,t,r||"0.00",i),abandonedCart:(e,t)=>L(e,t||"",i)}}g$1();var M=false,_=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(!M)try{if(typeof this.db?.execute=="function"){let{sql:e}=await import('./drizzle-orm-XRTSOQJS.js');await this.db.execute(e`
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
- `),M=!0;}else typeof this.db?.exec=="function"&&(this.db.exec(`
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,T as b,S as c,C as d,k as e,E as f,v as g,A as h,R as i,P as j,I as k,O as l,K as m,L as n,$ as o,_ as p,U as q,B as r};
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 chunkVKXWJOWI_cjs=require('./chunk-VKXWJOWI.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 chunkVKXWJOWI_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 chunkVKXWJOWI_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
+ '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 chunkT63QLFLZ_cjs=require('./chunk-T63QLFLZ.cjs'),chunkECFZEY5B_cjs=require('./chunk-ECFZEY5B.cjs'),chunkLBYY3W2D_cjs=require('./chunk-LBYY3W2D.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}),chunkT63QLFLZ_cjs.D.info("Hot-swapped to D1 DrizzleAdapter");}exports.a=chunkT63QLFLZ_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 chunkLBYY3W2D_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){chunkT63QLFLZ_cjs.D.warn("Auth connect warning:",s);}try{await exports.a.loadSettings();}catch(s){chunkT63QLFLZ_cjs.D.warn("loadSettings warning:",s);}try{await chunkECFZEY5B_cjs.e(n);}catch(s){chunkT63QLFLZ_cjs.D.warn("autoBootstrap warning:",s);}globalThis.__KYRO_INSTANCE__=exports.a;}catch(e){throw exports.a=null,l=null,chunkT63QLFLZ_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;
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;