@mindfulauth/core 2.0.0-beta.9 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/authScripts/ForgotPasswordScript.astro +64 -0
  2. package/dist/authScripts/LoginScript.astro +209 -0
  3. package/dist/authScripts/MagicLoginScript.astro +62 -0
  4. package/dist/authScripts/MagicRegisterScript.astro +73 -0
  5. package/dist/authScripts/MainScript.astro +236 -0
  6. package/dist/authScripts/RegisterPasswordScript.astro +118 -0
  7. package/dist/authScripts/ResendVerificationScript.astro +51 -0
  8. package/dist/authScripts/ResetPasswordScript.astro +155 -0
  9. package/dist/authScripts/SecurityScript.astro +449 -0
  10. package/dist/authScripts/TurnstileInit.astro +112 -0
  11. package/dist/authScripts/VerifyEmailScript.astro +72 -0
  12. package/dist/authScripts/VerifyMagicLinkScript.astro +195 -0
  13. package/dist/authScripts/index.d.ts +13 -0
  14. package/dist/authScripts/index.d.ts.map +1 -0
  15. package/dist/authScripts/index.js +15 -0
  16. package/dist/components/MAuthEmailInput.astro +12 -0
  17. package/dist/components/MAuthForm.astro +10 -0
  18. package/dist/components/MAuthMessage.astro +8 -0
  19. package/dist/components/MAuthNameInput.astro +11 -0
  20. package/dist/components/MAuthPasswordChangePending.astro +8 -0
  21. package/dist/components/MAuthPasswordInput.astro +12 -0
  22. package/dist/components/MAuthSubmitButton.astro +8 -0
  23. package/dist/components/MAuthTurnstile.astro +11 -0
  24. package/dist/components/MAuthTwoFACodeInput.astro +13 -0
  25. package/dist/components/MAuthTwoFASection.astro +11 -0
  26. package/dist/components/index.d.ts +11 -0
  27. package/dist/components/index.d.ts.map +1 -0
  28. package/dist/components/index.js +13 -0
  29. package/dist/core/auth-handler.d.ts.map +1 -1
  30. package/dist/core/auth-handler.js +2 -6
  31. package/dist/core/auth.d.ts +1 -1
  32. package/dist/core/auth.d.ts.map +1 -1
  33. package/dist/core/auth.js +1 -1
  34. package/dist/core/config.d.ts +1 -2
  35. package/dist/core/config.d.ts.map +1 -1
  36. package/dist/core/config.js +6 -5
  37. package/dist/core/csp.d.ts +2 -2
  38. package/dist/core/csp.js +3 -3
  39. package/dist/core/index.d.ts +5 -7
  40. package/dist/core/index.d.ts.map +1 -1
  41. package/dist/core/index.js +11 -9
  42. package/dist/core/middleware.js +3 -3
  43. package/dist/core/types.d.ts +0 -5
  44. package/dist/core/types.d.ts.map +1 -1
  45. package/dist/layouts/MAuthProtected.astro +56 -0
  46. package/dist/layouts/MAuthPublic.astro +68 -0
  47. package/package.json +17 -12
@@ -0,0 +1,195 @@
1
+ ---
2
+ // Mindful Auth - Verify Magic Link Script Component
3
+ // Provides: Magic link verification with 2FA support
4
+ ---
5
+ <script is:inline>
6
+ // Verify Magic Link Script - Astro Optimized
7
+
8
+ function getPathParams() {
9
+ const pathParts = window.location.pathname.split('/');
10
+ return {
11
+ recordid: pathParts[2],
12
+ token: pathParts[3]
13
+ };
14
+ }
15
+
16
+ async function handleVerifyMagicLinkSubmit(event) {
17
+ if (event) event.preventDefault();
18
+
19
+ const form = document.querySelector('[data-mindfulauth-form="verify-magic-link"]');
20
+ if (!form) return;
21
+ const messageEl = document.querySelector('[data-mindfulauth-field="message"]');
22
+ if (!messageEl) return;
23
+ const twoFACodeEl = form.querySelector('[data-mindfulauth-field="twofa-code"]');
24
+ const submitBtn = form.querySelector('button[type="submit"]');
25
+
26
+ // Skip API call on localhost to prevent production logs pollution
27
+ const hostname = window.location.hostname;
28
+ if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname.endsWith('.local')) {
29
+ messageEl.textContent = 'Magic link verification skipped on localhost.';
30
+ console.log('[Verify Magic Link] Skipping API call on localhost');
31
+ if (form) form.style.display = 'none';
32
+ return;
33
+ }
34
+
35
+ const { recordid, token } = getPathParams();
36
+
37
+ if (!recordid || !token) {
38
+ messageEl.textContent = "Invalid or expired magic link. Please request a new one.";
39
+ if (form) form.style.display = 'none';
40
+ return;
41
+ }
42
+
43
+ // Get Turnstile token
44
+ const turnstileToken = form.querySelector('[name="cf-turnstile-response"]')?.value;
45
+ if (!turnstileToken) {
46
+ messageEl.textContent = "Bot protection validation required.";
47
+ if (submitBtn) submitBtn.disabled = true;
48
+ return;
49
+ }
50
+
51
+ messageEl.textContent = "Verifying magic link...";
52
+ if (submitBtn) submitBtn.disabled = true;
53
+
54
+ try {
55
+ const requestBody = {
56
+ 'cf-turnstile-response': turnstileToken
57
+ };
58
+
59
+ // Include 2FA code if provided
60
+ if (twoFACodeEl && twoFACodeEl.value) {
61
+ requestBody.twoFACode = twoFACodeEl.value;
62
+ }
63
+
64
+ const endpoint = `/auth/verify-magic-link/${recordid}/${token}`;
65
+ console.log('[Verify Magic Link] Making request to:', endpoint);
66
+ console.log('[Verify Magic Link] Request body:', requestBody);
67
+
68
+ const response = await window.apiFetch(endpoint, {
69
+ body: JSON.stringify(requestBody)
70
+ });
71
+
72
+ console.log('[Verify Magic Link] Response status:', response.status);
73
+ const result = await response.json();
74
+ console.log('[Verify Magic Link] Response body:', result);
75
+
76
+ // Check if 2FA is required
77
+ if (result.requires2FA) {
78
+ // Reset Turnstile to generate a fresh token for the 2FA submission
79
+ // (Turnstile tokens are single-use; first request consumed it)
80
+ window.turnstile?.reset();
81
+
82
+ // Show the 2FA input field
83
+ const twoFAContainer = form.querySelector('[data-mindfulauth-field="twofa-code-container"]');
84
+ if (twoFAContainer) {
85
+ twoFAContainer.removeAttribute('hidden');
86
+ twoFAContainer.classList && twoFAContainer.classList.remove('hidden');
87
+ twoFAContainer.style.setProperty('display', 'block', 'important');
88
+ // Try common display values
89
+ if (window.getComputedStyle(twoFAContainer).display === 'none') {
90
+ twoFAContainer.style.setProperty('display', 'flex', 'important');
91
+ }
92
+ }
93
+ if (twoFACodeEl) {
94
+ twoFACodeEl.focus();
95
+ }
96
+ messageEl.textContent = '2FA code is required to complete login.';
97
+ if (submitBtn) {
98
+ submitBtn.textContent = 'Verify 2FA Code';
99
+ submitBtn.disabled = false;
100
+ }
101
+ return;
102
+ }
103
+
104
+ if (result.success) {
105
+ console.log('[Verify Magic Link] Verification successful');
106
+ messageEl.textContent = result.message || 'Login successful! Redirecting...';
107
+ if (form) form.style.display = 'none';
108
+
109
+ // Redirect to secure area (match login.js pattern)
110
+ if (result.redirect) {
111
+ console.log('[Verify Magic Link] Redirecting to:', result.redirect);
112
+ setTimeout(() => {
113
+ window.location.assign(result.redirect);
114
+ }, 200);
115
+ }
116
+ } else {
117
+ console.error('[Verify Magic Link] Verification failed:', result.message);
118
+ throw new Error(result.message || 'Verification failed.');
119
+ }
120
+ } catch (error) {
121
+ console.error('[Verify Magic Link] Error:', error);
122
+ messageEl.textContent = `Error: ${error.message}`;
123
+ if (submitBtn) submitBtn.disabled = false;
124
+ window.turnstile?.reset();
125
+ }
126
+ }
127
+
128
+ // --- MAIN EXECUTION ---
129
+ document.addEventListener('DOMContentLoaded', function() {
130
+ const form = document.querySelector('[data-mindfulauth-form="verify-magic-link"]');
131
+ if (!form) return;
132
+
133
+ // Initialize message and disable button until Turnstile is ready
134
+ const messageEl = document.querySelector('[data-mindfulauth-field="message"]');
135
+ const submitBtn = form.querySelector('button[type="submit"]');
136
+ if (messageEl) {
137
+ messageEl.textContent = 'Loading bot protection...';
138
+ }
139
+ if (submitBtn) {
140
+ submitBtn.disabled = true;
141
+ }
142
+
143
+ // Initially hide 2FA field - it will be shown if needed
144
+ const twoFAContainer = form.querySelector('[data-mindfulauth-field="twofa-code-container"]');
145
+ if (twoFAContainer) {
146
+ twoFAContainer.style.display = 'none';
147
+ }
148
+
149
+ // Wait for Turnstile to be ready
150
+ let turnstileReady = false;
151
+ const checkTurnstile = setInterval(() => {
152
+ const turnstileToken = form.querySelector('[name="cf-turnstile-response"]')?.value;
153
+ if (turnstileToken) {
154
+ console.log('[Verify Magic Link] Turnstile token loaded - ready for user verification');
155
+ clearInterval(checkTurnstile);
156
+ turnstileReady = true;
157
+ const messageEl = document.querySelector('[data-mindfulauth-field="message"]');
158
+ if (messageEl) {
159
+ messageEl.textContent = 'Ready to verify. Click the button below to sign in.';
160
+ }
161
+ const submitBtn = form.querySelector('button[type="submit"]');
162
+ if (submitBtn) {
163
+ submitBtn.disabled = false;
164
+ }
165
+ }
166
+ }, 100);
167
+
168
+ // Check for Turnstile load every 500ms for up to 30 seconds
169
+ // (don't show error proactively - only if user tries to submit)
170
+ let turnstileCheckCount = 0;
171
+ const extendedCheckTurnstile = setInterval(() => {
172
+ const turnstileToken = form.querySelector('[name="cf-turnstile-response"]')?.value;
173
+ if (turnstileToken && !turnstileReady) {
174
+ clearInterval(extendedCheckTurnstile);
175
+ turnstileReady = true;
176
+ const messageEl = document.querySelector('[data-mindfulauth-field="message"]');
177
+ if (messageEl) {
178
+ messageEl.textContent = 'Ready to verify. Click the button below to sign in.';
179
+ }
180
+ const submitBtn = form.querySelector('button[type="submit"]');
181
+ if (submitBtn) {
182
+ submitBtn.disabled = false;
183
+ }
184
+ }
185
+ turnstileCheckCount++;
186
+ // Stop checking after 30 seconds
187
+ if (turnstileCheckCount > 60) {
188
+ clearInterval(extendedCheckTurnstile);
189
+ }
190
+ }, 500);
191
+
192
+ // Also handle explicit form submission (for 2FA code entry)
193
+ form.addEventListener('submit', handleVerifyMagicLinkSubmit);
194
+ });
195
+ </script>
@@ -0,0 +1,13 @@
1
+ export { default as MAuthMainScript } from './MainScript.astro';
2
+ export { default as MAuthTurnstileInit } from './TurnstileInit.astro';
3
+ export { default as MAuthLoginScript } from './LoginScript.astro';
4
+ export { default as MAuthRegisterPasswordScript } from './RegisterPasswordScript.astro';
5
+ export { default as MAuthForgotPasswordScript } from './ForgotPasswordScript.astro';
6
+ export { default as MAuthMagicLoginScript } from './MagicLoginScript.astro';
7
+ export { default as MAuthMagicRegisterScript } from './MagicRegisterScript.astro';
8
+ export { default as MAuthResendVerificationScript } from './ResendVerificationScript.astro';
9
+ export { default as MAuthResetPasswordScript } from './ResetPasswordScript.astro';
10
+ export { default as MAuthVerifyEmailScript } from './VerifyEmailScript.astro';
11
+ export { default as MAuthVerifyMagicLinkScript } from './VerifyMagicLinkScript.astro';
12
+ export { default as MAuthSecurityScript } from './SecurityScript.astro';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/authScripts/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AACxF,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACpF,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAC5E,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAClF,OAAO,EAAE,OAAO,IAAI,6BAA6B,EAAE,MAAM,kCAAkC,CAAC;AAC5F,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAClF,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AACtF,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,15 @@
1
+ // Mindful Auth - Astro Components Barrel Export
2
+ // Usage: import { MAuthLoginScript, MAuthTurnstileInit } from '@mindfulauth/authScripts';
3
+ // or: import MAuthLoginScript from '@mindfulauth/authScripts/LoginScript.astro';
4
+ export { default as MAuthMainScript } from './MainScript.astro';
5
+ export { default as MAuthTurnstileInit } from './TurnstileInit.astro';
6
+ export { default as MAuthLoginScript } from './LoginScript.astro';
7
+ export { default as MAuthRegisterPasswordScript } from './RegisterPasswordScript.astro';
8
+ export { default as MAuthForgotPasswordScript } from './ForgotPasswordScript.astro';
9
+ export { default as MAuthMagicLoginScript } from './MagicLoginScript.astro';
10
+ export { default as MAuthMagicRegisterScript } from './MagicRegisterScript.astro';
11
+ export { default as MAuthResendVerificationScript } from './ResendVerificationScript.astro';
12
+ export { default as MAuthResetPasswordScript } from './ResetPasswordScript.astro';
13
+ export { default as MAuthVerifyEmailScript } from './VerifyEmailScript.astro';
14
+ export { default as MAuthVerifyMagicLinkScript } from './VerifyMagicLinkScript.astro';
15
+ export { default as MAuthSecurityScript } from './SecurityScript.astro';
@@ -0,0 +1,12 @@
1
+ ---
2
+ interface Props {
3
+ label?: string;
4
+ placeholder?: string;
5
+ class?: string;
6
+ }
7
+ const { label = 'Email', placeholder, class: classList } = Astro.props;
8
+ ---
9
+ <div class={classList}>
10
+ <label>{label}</label>
11
+ <input type="email" name="email" required data-mindfulauth-field="email" placeholder={placeholder} />
12
+ </div>
@@ -0,0 +1,10 @@
1
+ ---
2
+ interface Props {
3
+ formName: string;
4
+ class?: string;
5
+ }
6
+ const { formName, class: classList } = Astro.props;
7
+ ---
8
+ <form method="post" data-mindfulauth-form={formName} class={classList}>
9
+ <slot />
10
+ </form>
@@ -0,0 +1,8 @@
1
+ ---
2
+ interface Props {
3
+ defaultText?: string;
4
+ class?: string;
5
+ }
6
+ const { defaultText = '', class: classList } = Astro.props;
7
+ ---
8
+ <aside data-mindfulauth-field="message" class={classList}>{defaultText}</aside>
@@ -0,0 +1,11 @@
1
+ ---
2
+ interface Props {
3
+ label?: string;
4
+ class?: string;
5
+ }
6
+ const { label = 'Name', class: classList } = Astro.props;
7
+ ---
8
+ <div class={classList}>
9
+ <label>{label}</label>
10
+ <input type="text" name="name" required data-mindfulauth-field="name" />
11
+ </div>
@@ -0,0 +1,8 @@
1
+ ---
2
+ interface Props {
3
+ class?: string;
4
+ }
5
+ const { class: classList } = Astro.props;
6
+ // Message container appears when a user is redirected to the forgot-password page with ?reason=password_change_required in the URL. The script displays a security warning message "Your account requires a password change for security reasons. Please complete the form below to set a new password.".
7
+ ---
8
+ <div class={`hidden ${classList}`} data-mindfulauth-field="password-change-pending"></div>
@@ -0,0 +1,12 @@
1
+ ---
2
+ interface Props {
3
+ label: string;
4
+ fieldName?: 'password' | 'confirm-password' | 'new-password';
5
+ class?: string;
6
+ }
7
+ const { label, fieldName = 'password', class: classList } = Astro.props;
8
+ ---
9
+ <div class={classList}>
10
+ <label>{label}</label>
11
+ <input type="password" name={fieldName} required data-mindfulauth-field={fieldName} minlength={8} />
12
+ </div>
@@ -0,0 +1,8 @@
1
+ ---
2
+ interface Props {
3
+ label: string;
4
+ class?: string;
5
+ }
6
+ const { label, class: classList } = Astro.props;
7
+ ---
8
+ <button type="submit" class={classList}>{label}</button>
@@ -0,0 +1,11 @@
1
+ ---
2
+ interface Props {
3
+ theme?: 'light' | 'dark' | 'auto';
4
+ size?: 'flexible' | 'normal' | 'compact';
5
+ language?: 'auto' | string;
6
+ appearance?: 'always' | 'execute' | 'interaction-only';
7
+ class?: string;
8
+ }
9
+ const { theme = 'light', size = 'flexible', language = 'auto', appearance = 'always', class: classList } = Astro.props;
10
+ ---
11
+ <div data-mindfulauth-turnstile data-theme={theme} data-size={size} data-language={language} data-appearance={appearance} class={classList}></div>
@@ -0,0 +1,13 @@
1
+ ---
2
+ interface Props {
3
+ name: string;
4
+ label?: string;
5
+ class?: string;
6
+ }
7
+ const { name, label = '2FA Code', class: classList } = Astro.props;
8
+ ---
9
+ <div hidden data-mindfulauth-field="twofa-code-container" class={classList}>
10
+ <label>{label}</label>
11
+ <input type="text" name={name} inputmode="numeric" pattern="[0-9]{6}" maxlength="6" placeholder="Enter 6-digit code" data-mindfulauth-field="twofa-code" />
12
+ <small>Enter the 6-digit code from your authenticator app.</small>
13
+ </div>
@@ -0,0 +1,11 @@
1
+ ---
2
+ interface Props {
3
+ class?: string;
4
+ }
5
+ const { class: classList } = Astro.props;
6
+ ---
7
+ <div class={`hidden ${classList}`} data-mindfulauth-field="twofa-section">
8
+ <label>Authenticator Code</label>
9
+ <input type="text" name="twofa-code" pattern="[0-9]*" maxlength="6" placeholder="123456" inputmode="numeric" data-mindfulauth-field="twofa-code" />
10
+ <a href="#" data-mindfulauth-field="use-recovery-link">Use a recovery code instead</a>
11
+ </div>
@@ -0,0 +1,11 @@
1
+ export { default as MAuthForm } from './MAuthForm.astro';
2
+ export { default as MAuthEmailInput } from './MAuthEmailInput.astro';
3
+ export { default as MAuthPasswordInput } from './MAuthPasswordInput.astro';
4
+ export { default as MAuthNameInput } from './MAuthNameInput.astro';
5
+ export { default as MAuthTurnstile } from './MAuthTurnstile.astro';
6
+ export { default as MAuthSubmitButton } from './MAuthSubmitButton.astro';
7
+ export { default as MAuthMessage } from './MAuthMessage.astro';
8
+ export { default as MAuthTwoFASection } from './MAuthTwoFASection.astro';
9
+ export { default as MAuthTwoFACodeInput } from './MAuthTwoFACodeInput.astro';
10
+ export { default as MAuthPasswordChangePending } from './MAuthPasswordChangePending.astro';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACzE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACzE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,0BAA0B,EAAE,MAAM,oCAAoC,CAAC"}
@@ -0,0 +1,13 @@
1
+ // Mindful Auth - Astro Components Barrel Export
2
+ // Usage: import { MAuthForm, MAuthEmailInput } from '@mindfulauth/components';
3
+ // or: import MAuthForm from '@mindfulauth/components/MAuthForm.astro';
4
+ export { default as MAuthForm } from './MAuthForm.astro';
5
+ export { default as MAuthEmailInput } from './MAuthEmailInput.astro';
6
+ export { default as MAuthPasswordInput } from './MAuthPasswordInput.astro';
7
+ export { default as MAuthNameInput } from './MAuthNameInput.astro';
8
+ export { default as MAuthTurnstile } from './MAuthTurnstile.astro';
9
+ export { default as MAuthSubmitButton } from './MAuthSubmitButton.astro';
10
+ export { default as MAuthMessage } from './MAuthMessage.astro';
11
+ export { default as MAuthTwoFASection } from './MAuthTwoFASection.astro';
12
+ export { default as MAuthTwoFACodeInput } from './MAuthTwoFACodeInput.astro';
13
+ export { default as MAuthPasswordChangePending } from './MAuthPasswordChangePending.astro';
@@ -1 +1 @@
1
- {"version":3,"file":"auth-handler.d.ts","sourceRoot":"","sources":["../../src/core/auth-handler.ts"],"names":[],"mappings":"AAwEA,2EAA2E;AAC3E,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CA6BpH;AAED,gEAAgE;AAChE,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAyDrH"}
1
+ {"version":3,"file":"auth-handler.d.ts","sourceRoot":"","sources":["../../src/core/auth-handler.ts"],"names":[],"mappings":"AAoEA,2EAA2E;AAC3E,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CA6BpH;AAED,gEAAgE;AAChE,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAyDrH"}
@@ -1,12 +1,8 @@
1
1
  // Auth proxy handler for Mindful Auth
2
2
  // Forwards authentication requests to the central Mindful Auth service
3
- //
4
- // ASTRO 6 MIGRATION:
5
- // - Astro v6 removed context.locals.runtime.env. Env vars now import from 'cloudflare:workers'.
6
- // - Note: @cloudflare/workers-types must be installed and referenced in env.d.ts.
7
3
  import { env } from 'cloudflare:workers';
8
- import { CENTRAL_AUTH_ORIGIN, ALLOWED_AUTH_METHODS, MAX_BODY_SIZE_BYTES, AUTH_PROXY_TIMEOUT_MS } from './config';
9
- import { sanitizeEndpoint } from './security';
4
+ import { CENTRAL_AUTH_ORIGIN, ALLOWED_AUTH_METHODS, MAX_BODY_SIZE_BYTES, AUTH_PROXY_TIMEOUT_MS } from './config.js';
5
+ import { sanitizeEndpoint } from './security.js';
10
6
  const JSON_HEADERS = { 'Content-Type': 'application/json' };
11
7
  const jsonError = (error, status) => new Response(JSON.stringify({ error }), { status, headers: JSON_HEADERS });
12
8
  /** Build proxy headers from incoming request */
@@ -1,4 +1,4 @@
1
- import type { SessionValidationResult } from './types';
1
+ import type { SessionValidationResult } from './types.js';
2
2
  /** Validate session with Mindful Auth central service */
3
3
  export declare function validateSession(request: Request, tenantDomain: string, pathname: string, internalApiKey: string): Promise<SessionValidationResult>;
4
4
  /** Validate memberid in URL matches session (or just check structure if sessionRecordId is null) */
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/core/auth.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAEvD,yDAAyD;AACzD,wBAAsB,eAAe,CACjC,OAAO,EAAE,OAAO,EAChB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,GACvB,OAAO,CAAC,uBAAuB,CAAC,CAsClC;AAED,oGAAoG;AACpG,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,CAerI"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/core/auth.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAE1D,yDAAyD;AACzD,wBAAsB,eAAe,CACjC,OAAO,EAAE,OAAO,EAChB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,GACvB,OAAO,CAAC,uBAAuB,CAAC,CAsClC;AAED,oGAAoG;AACpG,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,CAerI"}
package/dist/core/auth.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // Authentication and session validation for Mindful Auth
2
- import { CENTRAL_AUTH_ORIGIN, SESSION_VALIDATION_TIMEOUT_MS } from './config';
2
+ import { CENTRAL_AUTH_ORIGIN, SESSION_VALIDATION_TIMEOUT_MS } from './config.js';
3
3
  /** Validate session with Mindful Auth central service */
4
4
  export async function validateSession(request, tenantDomain, pathname, internalApiKey) {
5
5
  const sessionId = request.headers.get('Cookie')?.match(/session_id=([^;]+)/)?.[1];
@@ -41,8 +41,7 @@ export declare const PUBLIC_PREFIXES: string[];
41
41
  * Astro 6's native security.csp in astro.config.mjs using hashes.
42
42
  * The remaining headers here cover transport security, framing, and permissions.
43
43
  *
44
- * Note: X-Frame-Options: SAMEORIGIN covers clickjacking protection
45
- * (equivalent to CSP frame-ancestors 'self', which cannot be set via meta tag).
44
+ * Note: X-Frame-Options: DENY prevents this portal from being embedded in iframes on any domain, protecting against clickjacking attacks.
46
45
  */
47
46
  export declare function GET_SECURITY_HEADERS(): Record<string, string>;
48
47
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,mBAAmB,gCAAgC,CAAC;AAGjE,eAAO,MAAM,oBAAoB,UAAkB,CAAC;AACpD,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAC3C,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAC3C,eAAO,MAAM,6BAA6B,QAAQ,CAAC;AAenD;;;GAGG;AACH,wBAAgB,eAAe,IAAI,MAAM,EAAE,CAE1C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE;IAC1C,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB,GAAG,OAAO,OAAO,CAEjB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE;IAC1C,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIzB;AAID,eAAO,MAAM,aAAa,UAQzB,CAAC;AAIF,eAAO,MAAM,eAAe,UAO3B,CAAC;AAMF;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQ7D"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,mBAAmB,gCAAgC,CAAC;AAGjE,eAAO,MAAM,oBAAoB,UAAkB,CAAC;AACpD,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAC3C,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAC3C,eAAO,MAAM,6BAA6B,QAAQ,CAAC;AAenD;;;GAGG;AACH,wBAAgB,eAAe,IAAI,MAAM,EAAE,CAE1C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE;IAC1C,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB,GAAG,OAAO,OAAO,CAEjB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE;IAC1C,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIzB;AAID,eAAO,MAAM,aAAa,UAQzB,CAAC;AAIF,eAAO,MAAM,eAAe,UAO3B,CAAC;AAMF;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAU7D"}
@@ -80,15 +80,16 @@ export const PUBLIC_PREFIXES = [
80
80
  * Astro 6's native security.csp in astro.config.mjs using hashes.
81
81
  * The remaining headers here cover transport security, framing, and permissions.
82
82
  *
83
- * Note: X-Frame-Options: SAMEORIGIN covers clickjacking protection
84
- * (equivalent to CSP frame-ancestors 'self', which cannot be set via meta tag).
83
+ * Note: X-Frame-Options: DENY prevents this portal from being embedded in iframes on any domain, protecting against clickjacking attacks.
85
84
  */
86
85
  export function GET_SECURITY_HEADERS() {
87
86
  return {
88
87
  'X-Content-Type-Options': 'nosniff',
89
- 'X-Frame-Options': 'SAMEORIGIN',
88
+ 'X-Frame-Options': 'DENY',
90
89
  'Referrer-Policy': 'strict-origin-when-cross-origin',
91
- 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
92
- 'Permissions-Policy': 'geolocation=(), microphone=(), camera=()',
90
+ 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload',
91
+ 'Permissions-Policy': 'geolocation=(), microphone=(), camera=(), payment=(), usb=(), magnetometer=(), gyroscope=(), accelerometer=()',
92
+ 'Cross-Origin-Opener-Policy': 'same-origin',
93
+ 'Cross-Origin-Resource-Policy': 'same-origin',
93
94
  };
94
95
  }
@@ -1,12 +1,12 @@
1
1
  /**
2
- * Scans the mindfulauth/astro/ directory at build time and returns SHA-384
2
+ * Scans the mindfulauth/authScripts/ directory at build time and returns SHA-384
3
3
  * hashes for all <script is:inline> blocks found in .astro component files.
4
4
  *
5
5
  * Astro's static CSP analysis cannot resolve dynamically rendered components,
6
6
  * so hashes must be declared manually in astro.config.mjs. This function
7
7
  * computes them automatically so no manual maintenance is needed.
8
8
  *
9
- * When published as a package, this function resolves the astro/ directory
9
+ * When published as a package, this function resolves the authScripts/ directory
10
10
  * relative to its own location — no consumer configuration required.
11
11
  *
12
12
  * @example
package/dist/core/csp.js CHANGED
@@ -8,14 +8,14 @@ import { join, dirname } from 'path';
8
8
  import { fileURLToPath } from 'url';
9
9
  const __dirname = dirname(fileURLToPath(import.meta.url));
10
10
  /**
11
- * Scans the mindfulauth/astro/ directory at build time and returns SHA-384
11
+ * Scans the mindfulauth/authScripts/ directory at build time and returns SHA-384
12
12
  * hashes for all <script is:inline> blocks found in .astro component files.
13
13
  *
14
14
  * Astro's static CSP analysis cannot resolve dynamically rendered components,
15
15
  * so hashes must be declared manually in astro.config.mjs. This function
16
16
  * computes them automatically so no manual maintenance is needed.
17
17
  *
18
- * When published as a package, this function resolves the astro/ directory
18
+ * When published as a package, this function resolves the authScripts/ directory
19
19
  * relative to its own location — no consumer configuration required.
20
20
  *
21
21
  * @example
@@ -25,7 +25,7 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
25
25
  * scriptDirective: { hashes: getScriptHashes() }
26
26
  */
27
27
  export function getScriptHashes() {
28
- const dir = join(__dirname, '../astro');
28
+ const dir = join(__dirname, '../authScripts');
29
29
  return readdirSync(dir)
30
30
  .filter(f => f.endsWith('.astro'))
31
31
  .flatMap(file => {
@@ -1,8 +1,6 @@
1
- export * from './types';
2
- export * from './config';
3
- export * from './auth';
4
- export * from './auth-handler';
5
- export * from './security';
6
- export * from './middleware';
7
- export * from './csp';
1
+ export * from './types.js';
2
+ export * from './config.js';
3
+ export * from './auth.js';
4
+ export * from './security.js';
5
+ export * from './csp.js';
8
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAGA,cAAc,SAAS,CAAC;AAGxB,cAAc,UAAU,CAAC;AAGzB,cAAc,QAAQ,CAAC;AAGvB,cAAc,gBAAgB,CAAC;AAG/B,cAAc,YAAY,CAAC;AAG3B,cAAc,cAAc,CAAC;AAG7B,cAAc,OAAO,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAGA,cAAc,YAAY,CAAC;AAG3B,cAAc,aAAa,CAAC;AAG5B,cAAc,WAAW,CAAC;AAM1B,cAAc,eAAe,CAAC;AAQ9B,cAAc,UAAU,CAAC"}
@@ -1,15 +1,17 @@
1
1
  // Mindful Auth Core - Main exports
2
2
  // Types
3
- export * from './types';
3
+ export * from './types.js';
4
4
  // Configuration
5
- export * from './config';
5
+ export * from './config.js';
6
6
  // Authentication
7
- export * from './auth';
8
- // Auth handler for API routes
9
- export * from './auth-handler';
7
+ export * from './auth.js';
8
+ // Auth handler for API routes — NOT re-exported here.
9
+ // auth-handler.ts imports 'cloudflare:workers' which is only available at runtime (SSR), not at config-load time. Import it directly where needed: import { handleAuthProxy } from './auth-handler.js';
10
10
  // Security utilities
11
- export * from './security';
12
- // Middleware
13
- export * from './middleware';
11
+ export * from './security.js';
12
+ // Middleware — NOT re-exported here.
13
+ // middleware.ts imports 'astro:middleware' and 'cloudflare:workers' which are
14
+ // only available at runtime (SSR), not at config-load time.
15
+ // Import it directly: import { onRequest } from './middleware.js';
14
16
  // Build-time CSP utilities
15
- export * from './csp';
17
+ export * from './csp.js';
@@ -7,9 +7,9 @@
7
7
  // - Dev mode bypass uses import.meta.env.DEV (build-time constant: true in dev, false in prod).
8
8
  import { defineMiddleware } from 'astro:middleware';
9
9
  import { env } from 'cloudflare:workers';
10
- import { PUBLIC_ROUTES, PUBLIC_PREFIXES, GET_SECURITY_HEADERS, GET_SKIP_ASSETS } from './config';
11
- import { sanitizePath } from './security';
12
- import { validateSession, validateMemberIdInUrl } from './auth';
10
+ import { PUBLIC_ROUTES, PUBLIC_PREFIXES, GET_SECURITY_HEADERS, GET_SKIP_ASSETS } from './config.js';
11
+ import { sanitizePath } from './security.js';
12
+ import { validateSession, validateMemberIdInUrl } from './auth.js';
13
13
  /** Check if a path is a public route (no auth required) */
14
14
  function isPublicRoute(pathname) {
15
15
  return PUBLIC_ROUTES.includes(pathname) ||
@@ -1,11 +1,6 @@
1
1
  import type { MiddlewareHandler } from 'astro';
2
2
  export interface MindfulAuthLocals {
3
3
  recordId: string | null;
4
- runtime?: {
5
- env?: {
6
- INTERNAL_API_KEY?: string;
7
- };
8
- };
9
4
  }
10
5
  declare global {
11
6
  namespace App {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAG/C,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE;QACR,GAAG,CAAC,EAAE;YACJ,gBAAgB,CAAC,EAAE,MAAM,CAAC;SAC3B,CAAC;KACH,CAAC;CACH;AAGD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,GAAG,CAAC;QACZ,UAAU,MAAO,SAAQ,iBAAiB;SAAG;KAC9C;CACF;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,qBAAqB,GAAG,iBAAiB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAG/C,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAGD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,GAAG,CAAC;QACZ,UAAU,MAAO,SAAQ,iBAAiB;SAAG;KAC9C;CACF;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,qBAAqB,GAAG,iBAAiB,CAAC"}