@dupecom/botcha-cloudflare 0.3.3 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analytics.d.ts +60 -0
- package/dist/analytics.d.ts.map +1 -0
- package/dist/analytics.js +130 -0
- package/dist/apps.d.ts +159 -0
- package/dist/apps.d.ts.map +1 -0
- package/dist/apps.js +307 -0
- package/dist/auth.d.ts +93 -6
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +251 -9
- package/dist/challenges.d.ts +31 -7
- package/dist/challenges.d.ts.map +1 -1
- package/dist/challenges.js +551 -144
- package/dist/dashboard/api.d.ts +70 -0
- package/dist/dashboard/api.d.ts.map +1 -0
- package/dist/dashboard/api.js +546 -0
- package/dist/dashboard/auth.d.ts +183 -0
- package/dist/dashboard/auth.d.ts.map +1 -0
- package/dist/dashboard/auth.js +401 -0
- package/dist/dashboard/device-code.d.ts +43 -0
- package/dist/dashboard/device-code.d.ts.map +1 -0
- package/dist/dashboard/device-code.js +77 -0
- package/dist/dashboard/index.d.ts +31 -0
- package/dist/dashboard/index.d.ts.map +1 -0
- package/dist/dashboard/index.js +64 -0
- package/dist/dashboard/layout.d.ts +47 -0
- package/dist/dashboard/layout.d.ts.map +1 -0
- package/dist/dashboard/layout.js +38 -0
- package/dist/dashboard/pages.d.ts +11 -0
- package/dist/dashboard/pages.d.ts.map +1 -0
- package/dist/dashboard/pages.js +18 -0
- package/dist/dashboard/styles.d.ts +11 -0
- package/dist/dashboard/styles.d.ts.map +1 -0
- package/dist/dashboard/styles.js +633 -0
- package/dist/email.d.ts +44 -0
- package/dist/email.d.ts.map +1 -0
- package/dist/email.js +119 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +644 -50
- package/dist/rate-limit.d.ts +11 -1
- package/dist/rate-limit.d.ts.map +1 -1
- package/dist/rate-limit.js +13 -2
- package/dist/routes/stream.js +1 -1
- package/dist/static.d.ts +728 -0
- package/dist/static.d.ts.map +1 -0
- package/dist/static.js +818 -0
- package/package.json +1 -1
package/dist/email.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BOTCHA Email — Resend Integration
|
|
3
|
+
*
|
|
4
|
+
* Sends transactional emails via Resend API.
|
|
5
|
+
* Falls back to console.log when RESEND_API_KEY is not set (local dev).
|
|
6
|
+
*
|
|
7
|
+
* Uses onboarding@resend.dev (Resend test domain) until botcha.ai
|
|
8
|
+
* is verified as a sending domain.
|
|
9
|
+
*/
|
|
10
|
+
const RESEND_API = 'https://api.resend.com/emails';
|
|
11
|
+
const FROM_ADDRESS = 'BOTCHA <onboarding@resend.dev>';
|
|
12
|
+
/**
|
|
13
|
+
* Send an email via Resend. Falls back to console logging if no API key.
|
|
14
|
+
*/
|
|
15
|
+
export async function sendEmail(apiKey, options) {
|
|
16
|
+
// Fall back to logging when no API key (local dev)
|
|
17
|
+
if (!apiKey) {
|
|
18
|
+
console.log('[BOTCHA Email] No RESEND_API_KEY — logging instead of sending:');
|
|
19
|
+
console.log(` To: ${options.to}`);
|
|
20
|
+
console.log(` Subject: ${options.subject}`);
|
|
21
|
+
console.log(` Body: ${options.text || options.html.substring(0, 200)}`);
|
|
22
|
+
return { success: true, id: 'dev-logged' };
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const resp = await fetch(RESEND_API, {
|
|
26
|
+
method: 'POST',
|
|
27
|
+
headers: {
|
|
28
|
+
Authorization: `Bearer ${apiKey}`,
|
|
29
|
+
'Content-Type': 'application/json',
|
|
30
|
+
},
|
|
31
|
+
body: JSON.stringify({
|
|
32
|
+
from: FROM_ADDRESS,
|
|
33
|
+
to: [options.to],
|
|
34
|
+
subject: options.subject,
|
|
35
|
+
html: options.html,
|
|
36
|
+
text: options.text,
|
|
37
|
+
}),
|
|
38
|
+
});
|
|
39
|
+
if (!resp.ok) {
|
|
40
|
+
const text = await resp.text();
|
|
41
|
+
console.error(`[BOTCHA Email] Resend error ${resp.status}:`, text);
|
|
42
|
+
return { success: false, error: `Resend ${resp.status}: ${text.substring(0, 200)}` };
|
|
43
|
+
}
|
|
44
|
+
const data = (await resp.json());
|
|
45
|
+
return { success: true, id: data.id };
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.error('[BOTCHA Email] Send failed:', error);
|
|
49
|
+
return {
|
|
50
|
+
success: false,
|
|
51
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// ============ EMAIL TEMPLATES ============
|
|
56
|
+
/**
|
|
57
|
+
* Email verification code email.
|
|
58
|
+
*/
|
|
59
|
+
export function verificationEmail(code) {
|
|
60
|
+
return {
|
|
61
|
+
to: '', // caller fills in
|
|
62
|
+
subject: `BOTCHA: Your verification code is ${code}`,
|
|
63
|
+
html: `
|
|
64
|
+
<div style="font-family: 'Courier New', monospace; max-width: 480px; margin: 0 auto; padding: 2rem;">
|
|
65
|
+
<h1 style="font-size: 1.5rem; margin-bottom: 1rem;">BOTCHA</h1>
|
|
66
|
+
<p>Your email verification code:</p>
|
|
67
|
+
<div style="background: #f5f5f5; border: 2px solid #333; padding: 1.5rem; text-align: center; font-size: 2rem; font-weight: bold; letter-spacing: 0.3em; margin: 1.5rem 0;">
|
|
68
|
+
${code}
|
|
69
|
+
</div>
|
|
70
|
+
<p style="color: #666; font-size: 0.875rem;">This code expires in 10 minutes.</p>
|
|
71
|
+
<p style="color: #666; font-size: 0.875rem;">If you didn't request this, ignore this email.</p>
|
|
72
|
+
<hr style="border: none; border-top: 1px solid #ddd; margin: 2rem 0;">
|
|
73
|
+
<p style="color: #999; font-size: 0.75rem;">BOTCHA — Prove you're a bot. Humans need not apply.</p>
|
|
74
|
+
</div>`,
|
|
75
|
+
text: `BOTCHA: Your verification code is ${code}\n\nThis code expires in 10 minutes.\nIf you didn't request this, ignore this email.`,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Account recovery device code email.
|
|
80
|
+
*/
|
|
81
|
+
export function recoveryEmail(code, loginUrl) {
|
|
82
|
+
return {
|
|
83
|
+
to: '', // caller fills in
|
|
84
|
+
subject: `BOTCHA: Your recovery code is ${code}`,
|
|
85
|
+
html: `
|
|
86
|
+
<div style="font-family: 'Courier New', monospace; max-width: 480px; margin: 0 auto; padding: 2rem;">
|
|
87
|
+
<h1 style="font-size: 1.5rem; margin-bottom: 1rem;">BOTCHA</h1>
|
|
88
|
+
<p>Someone requested access to your BOTCHA dashboard. Enter this code to log in:</p>
|
|
89
|
+
<div style="background: #f5f5f5; border: 2px solid #333; padding: 1.5rem; text-align: center; font-size: 2rem; font-weight: bold; letter-spacing: 0.15em; margin: 1.5rem 0;">
|
|
90
|
+
${code}
|
|
91
|
+
</div>
|
|
92
|
+
<p>Enter this code at: <a href="${loginUrl}">${loginUrl}</a></p>
|
|
93
|
+
<p style="color: #666; font-size: 0.875rem;">This code expires in 10 minutes.</p>
|
|
94
|
+
<p style="color: #666; font-size: 0.875rem;">If you didn't request this, ignore this email. Your account is still secure.</p>
|
|
95
|
+
<hr style="border: none; border-top: 1px solid #ddd; margin: 2rem 0;">
|
|
96
|
+
<p style="color: #999; font-size: 0.75rem;">BOTCHA — Prove you're a bot. Humans need not apply.</p>
|
|
97
|
+
</div>`,
|
|
98
|
+
text: `BOTCHA: Your recovery code is ${code}\n\nEnter this code at: ${loginUrl}\n\nThis code expires in 10 minutes.\nIf you didn't request this, ignore this email.`,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* New secret notification email (sent after secret rotation).
|
|
103
|
+
*/
|
|
104
|
+
export function secretRotatedEmail(appId) {
|
|
105
|
+
return {
|
|
106
|
+
to: '', // caller fills in
|
|
107
|
+
subject: 'BOTCHA: Your app secret was rotated',
|
|
108
|
+
html: `
|
|
109
|
+
<div style="font-family: 'Courier New', monospace; max-width: 480px; margin: 0 auto; padding: 2rem;">
|
|
110
|
+
<h1 style="font-size: 1.5rem; margin-bottom: 1rem;">BOTCHA</h1>
|
|
111
|
+
<p>The secret for app <strong>${appId}</strong> was just rotated.</p>
|
|
112
|
+
<p>The old secret is no longer valid. Update your agent configuration with the new secret.</p>
|
|
113
|
+
<p style="color: #666; font-size: 0.875rem;">If you didn't do this, someone with access to your dashboard rotated your secret. Log in and rotate again immediately.</p>
|
|
114
|
+
<hr style="border: none; border-top: 1px solid #ddd; margin: 2rem 0;">
|
|
115
|
+
<p style="color: #999; font-size: 0.75rem;">BOTCHA — Prove you're a bot. Humans need not apply.</p>
|
|
116
|
+
</div>`,
|
|
117
|
+
text: `BOTCHA: The secret for app ${appId} was just rotated.\n\nThe old secret is no longer valid. Update your agent configuration with the new secret.\n\nIf you didn't do this, log in and rotate again immediately.`,
|
|
118
|
+
};
|
|
119
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,9 +7,12 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { Hono } from 'hono';
|
|
9
9
|
import { type KVNamespace } from './challenges';
|
|
10
|
+
import { type AnalyticsEngineDataset } from './analytics';
|
|
10
11
|
type Bindings = {
|
|
11
12
|
CHALLENGES: KVNamespace;
|
|
12
13
|
RATE_LIMITS: KVNamespace;
|
|
14
|
+
APPS: KVNamespace;
|
|
15
|
+
ANALYTICS?: AnalyticsEngineDataset;
|
|
13
16
|
JWT_SECRET: string;
|
|
14
17
|
BOTCHA_VERSION: string;
|
|
15
18
|
};
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,EAYL,KAAK,WAAW,EACjB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,EAYL,KAAK,WAAW,EACjB,MAAM,cAAc,CAAC;AAetB,OAAO,EACL,KAAK,sBAAsB,EAM5B,MAAM,aAAa,CAAC;AAGrB,KAAK,QAAQ,GAAG;IACd,UAAU,EAAE,WAAW,CAAC;IACxB,WAAW,EAAE,WAAW,CAAC;IACzB,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,CAAC,EAAE,sBAAsB,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,KAAK,SAAS,GAAG;IACf,YAAY,CAAC,EAAE;QACb,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,iBAAiB,CAAC;QACxB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH,CAAC;AAEF,QAAA,MAAM,GAAG;cAAwB,QAAQ;eAAa,SAAS;yCAAK,CAAC;AAusDrE,eAAe,GAAG,CAAC;AAGnB,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,yBAAyB,EACzB,uBAAuB,EACvB,0BAA0B,EAC1B,wBAAwB,EACxB,uBAAuB,EACvB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EACL,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,KAAK,EACV,KAAK,YAAY,GAClB,MAAM,SAAS,CAAC"}
|