@mindfulauth/core 1.0.2 → 1.1.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/config.d.ts +55 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +124 -36
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +3 -4
- package/package.json +2 -2
package/dist/config.d.ts
CHANGED
|
@@ -4,8 +4,61 @@ export declare const ALLOWED_AUTH_METHODS: string[];
|
|
|
4
4
|
export declare const MAX_BODY_SIZE_BYTES = 1048576;
|
|
5
5
|
export declare const AUTH_PROXY_TIMEOUT_MS = 15000;
|
|
6
6
|
export declare const SESSION_VALIDATION_TIMEOUT_MS = 10000;
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Returns the combined list of assets to skip session validation for.
|
|
9
|
+
* Merges defaults with any custom assets configured via mauthSecurityConfig().
|
|
10
|
+
*/
|
|
11
|
+
export declare function GET_SKIP_ASSETS(): string[];
|
|
8
12
|
export declare const PUBLIC_ROUTES: string[];
|
|
9
13
|
export declare const PUBLIC_PREFIXES: string[];
|
|
10
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Configure Mindful Auth security settings including CSP sources and static
|
|
16
|
+
* assets to skip. Returns the options to be passed to getMauthViteDefines().
|
|
17
|
+
*
|
|
18
|
+
* Call in astro.config.mjs and pass the result to vite.define:
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* // astro.config.mjs
|
|
22
|
+
* const mauthCfg = mauthSecurityConfig({
|
|
23
|
+
* skipAssets: ['/sitemap.xml', '/manifest.webmanifest'],
|
|
24
|
+
* csp: {
|
|
25
|
+
* scriptSources: ['https://analytics.example.com'],
|
|
26
|
+
* connectSources: ['https://api.example.com'],
|
|
27
|
+
* frameSources: ['https://stripe.com'],
|
|
28
|
+
* fontSources: ['https://fonts.googleapis.com']
|
|
29
|
+
* }
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* export default defineConfig({
|
|
33
|
+
* vite: { define: getMauthViteDefines(mauthCfg) }
|
|
34
|
+
* });
|
|
35
|
+
*/
|
|
36
|
+
export declare function mauthSecurityConfig(options?: {
|
|
37
|
+
skipAssets?: string[];
|
|
38
|
+
csp?: {
|
|
39
|
+
scriptSources?: string[];
|
|
40
|
+
connectSources?: string[];
|
|
41
|
+
frameSources?: string[];
|
|
42
|
+
fontSources?: string[];
|
|
43
|
+
};
|
|
44
|
+
}): typeof options;
|
|
45
|
+
/**
|
|
46
|
+
* Converts the result of mauthSecurityConfig() into Vite define entries.
|
|
47
|
+
* Pass the output to vite.define in astro.config.mjs so custom values are
|
|
48
|
+
* baked into the SSR bundle at build time.
|
|
49
|
+
*/
|
|
50
|
+
export declare function getMauthViteDefines(options?: {
|
|
51
|
+
skipAssets?: string[];
|
|
52
|
+
csp?: {
|
|
53
|
+
scriptSources?: string[];
|
|
54
|
+
connectSources?: string[];
|
|
55
|
+
frameSources?: string[];
|
|
56
|
+
fontSources?: string[];
|
|
57
|
+
};
|
|
58
|
+
}): Record<string, string>;
|
|
59
|
+
/**
|
|
60
|
+
* Get security headers with CSP sources merged from defaults and build-time
|
|
61
|
+
* custom values injected via vite.define (from getMauthViteDefines()).
|
|
62
|
+
*/
|
|
63
|
+
export declare function GET_SECURITY_HEADERS(): Record<string, string>;
|
|
11
64
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,mBAAmB,gCAAgC,CAAC;AACjE,eAAO,MAAM,UAAU,gCAAgC,CAAC;AAGxD,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;AAID,eAAO,MAAM,aAAa,UAQzB,CAAC;AAIF,eAAO,MAAM,eAAe,UAO3B,CAAC;AAyCF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE;IAC1C,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,GAAG,CAAC,EAAE;QACF,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;QAC1B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;KAC1B,CAAC;CACL,GAAG,OAAO,OAAO,CAEjB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE;IAC1C,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,GAAG,CAAC,EAAE;QACF,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;QAC1B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;KAC1B,CAAC;CACL,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQzB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA6C7D"}
|
package/dist/config.js
CHANGED
|
@@ -1,18 +1,31 @@
|
|
|
1
|
+
// ============================================================================
|
|
1
2
|
// Configuration for the Astro Portal
|
|
3
|
+
// ============================================================================
|
|
4
|
+
// API Endpoints
|
|
2
5
|
export const CENTRAL_AUTH_ORIGIN = 'https://api.mindfulauth.com';
|
|
3
6
|
export const CDN_ORIGIN = 'https://cdn.mindfulauth.com';
|
|
7
|
+
// Request & Timeout Configuration
|
|
4
8
|
export const ALLOWED_AUTH_METHODS = ['GET', 'POST'];
|
|
5
9
|
export const MAX_BODY_SIZE_BYTES = 1048576; // 1MB limit
|
|
6
10
|
export const AUTH_PROXY_TIMEOUT_MS = 15000;
|
|
7
11
|
export const SESSION_VALIDATION_TIMEOUT_MS = 10000;
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Static Assets & Route Configuration
|
|
14
|
+
// ============================================================================
|
|
8
15
|
// Static assets to skip session validation (favicon, robots.txt, etc.)
|
|
9
16
|
// SECURITY CRITICAL: Only add actual static file requests here.
|
|
10
17
|
// Examples of safe entries: /favicon.ico, /robots.txt, /sitemap.xml
|
|
11
18
|
// NEVER add application routes like /dashboard, /profile, /secure/* - this COMPLETELY bypasses authentication. If you add a route here, unauthenticated users can access it without logging in.
|
|
12
|
-
|
|
19
|
+
const DEFAULT_SKIP_ASSETS = ['/favicon.ico', '/robots.txt', '/.well-known/security.txt'];
|
|
20
|
+
/**
|
|
21
|
+
* Returns the combined list of assets to skip session validation for.
|
|
22
|
+
* Merges defaults with any custom assets configured via mauthSecurityConfig().
|
|
23
|
+
*/
|
|
24
|
+
export function GET_SKIP_ASSETS() {
|
|
25
|
+
return [...DEFAULT_SKIP_ASSETS, ...__MAUTH_SKIP_ASSETS__];
|
|
26
|
+
}
|
|
13
27
|
// Public routes that do not require authentication
|
|
14
28
|
// ⚠️ DO NOT EDIT - These are critical for the authentication system to work correctly
|
|
15
|
-
// If you need public content in your portal, host it on your main website instead
|
|
16
29
|
export const PUBLIC_ROUTES = [
|
|
17
30
|
'/',
|
|
18
31
|
'/login',
|
|
@@ -24,44 +37,119 @@ export const PUBLIC_ROUTES = [
|
|
|
24
37
|
];
|
|
25
38
|
// Dynamic public routes (prefix matching)
|
|
26
39
|
// ⚠️ DO NOT EDIT - These are critical for the authentication system to work correctly
|
|
27
|
-
// If you need public content in your portal, host it on your main website instead
|
|
28
40
|
export const PUBLIC_PREFIXES = [
|
|
29
|
-
'/auth/',
|
|
41
|
+
'/auth/',
|
|
30
42
|
'/email-verified/',
|
|
31
43
|
'/reset-password/',
|
|
32
44
|
'/verify-email/',
|
|
33
45
|
'/verify-magic-link/',
|
|
34
|
-
'/api/public/',
|
|
46
|
+
'/api/public/',
|
|
35
47
|
];
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
//
|
|
41
|
-
// - cdn.jsdelivr.net: External dependencies for QR Code library (for 2fa auth)
|
|
48
|
+
// ============================================================================
|
|
49
|
+
// Security Headers & CSP Configuration
|
|
50
|
+
// ============================================================================
|
|
51
|
+
// Default allowed script sources for CSP
|
|
52
|
+
// ⚠️ IMPORTANT: Do not remove these domains - they are critical for authentication:
|
|
42
53
|
// Removing these will break authentication and user will be unable to log in.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
'
|
|
52
|
-
'
|
|
53
|
-
'
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
54
|
+
const DEFAULT_SCRIPT_SOURCES = [
|
|
55
|
+
"'self'",
|
|
56
|
+
'https://*.cloudflare.com',
|
|
57
|
+
'https://cdn.mindfulauth.com',
|
|
58
|
+
'https://api.mindfulauth.com'
|
|
59
|
+
];
|
|
60
|
+
// Default allowed connection sources for CSP
|
|
61
|
+
const DEFAULT_CONNECT_SOURCES = [
|
|
62
|
+
"'self'",
|
|
63
|
+
'https://*.cloudflare.com',
|
|
64
|
+
'https://api.mindfulauth.com'
|
|
65
|
+
];
|
|
66
|
+
// Default allowed frame sources for CSP
|
|
67
|
+
const DEFAULT_FRAME_SOURCES = [
|
|
68
|
+
"'self'",
|
|
69
|
+
'https://*.cloudflare.com'
|
|
70
|
+
];
|
|
71
|
+
// Default allowed font sources for CSP
|
|
72
|
+
const DEFAULT_FONT_SOURCES = [
|
|
73
|
+
"'self'",
|
|
74
|
+
'data:'
|
|
75
|
+
];
|
|
76
|
+
/**
|
|
77
|
+
* Configure Mindful Auth security settings including CSP sources and static
|
|
78
|
+
* assets to skip. Returns the options to be passed to getMauthViteDefines().
|
|
79
|
+
*
|
|
80
|
+
* Call in astro.config.mjs and pass the result to vite.define:
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* // astro.config.mjs
|
|
84
|
+
* const mauthCfg = mauthSecurityConfig({
|
|
85
|
+
* skipAssets: ['/sitemap.xml', '/manifest.webmanifest'],
|
|
86
|
+
* csp: {
|
|
87
|
+
* scriptSources: ['https://analytics.example.com'],
|
|
88
|
+
* connectSources: ['https://api.example.com'],
|
|
89
|
+
* frameSources: ['https://stripe.com'],
|
|
90
|
+
* fontSources: ['https://fonts.googleapis.com']
|
|
91
|
+
* }
|
|
92
|
+
* });
|
|
93
|
+
*
|
|
94
|
+
* export default defineConfig({
|
|
95
|
+
* vite: { define: getMauthViteDefines(mauthCfg) }
|
|
96
|
+
* });
|
|
97
|
+
*/
|
|
98
|
+
export function mauthSecurityConfig(options) {
|
|
99
|
+
return options;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Converts the result of mauthSecurityConfig() into Vite define entries.
|
|
103
|
+
* Pass the output to vite.define in astro.config.mjs so custom values are
|
|
104
|
+
* baked into the SSR bundle at build time.
|
|
105
|
+
*/
|
|
106
|
+
export function getMauthViteDefines(options) {
|
|
107
|
+
return {
|
|
108
|
+
__MAUTH_SKIP_ASSETS__: JSON.stringify(options?.skipAssets ?? []),
|
|
109
|
+
__MAUTH_SCRIPT_SOURCES__: JSON.stringify(options?.csp?.scriptSources ?? []),
|
|
110
|
+
__MAUTH_CONNECT_SOURCES__: JSON.stringify(options?.csp?.connectSources ?? []),
|
|
111
|
+
__MAUTH_FRAME_SOURCES__: JSON.stringify(options?.csp?.frameSources ?? []),
|
|
112
|
+
__MAUTH_FONT_SOURCES__: JSON.stringify(options?.csp?.fontSources ?? []),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Get security headers with CSP sources merged from defaults and build-time
|
|
117
|
+
* custom values injected via vite.define (from getMauthViteDefines()).
|
|
118
|
+
*/
|
|
119
|
+
export function GET_SECURITY_HEADERS() {
|
|
120
|
+
// Custom sources are baked in at build time via vite.define
|
|
121
|
+
const SCRIPT_SOURCES = [...DEFAULT_SCRIPT_SOURCES, ...__MAUTH_SCRIPT_SOURCES__];
|
|
122
|
+
const CONNECT_SOURCES = [...DEFAULT_CONNECT_SOURCES, ...__MAUTH_CONNECT_SOURCES__];
|
|
123
|
+
const FRAME_SOURCES = [...DEFAULT_FRAME_SOURCES, ...__MAUTH_FRAME_SOURCES__];
|
|
124
|
+
const FONT_SOURCES = [...DEFAULT_FONT_SOURCES, ...__MAUTH_FONT_SOURCES__];
|
|
125
|
+
return {
|
|
126
|
+
'X-Content-Type-Options': 'nosniff',
|
|
127
|
+
'X-Frame-Options': 'SAMEORIGIN',
|
|
128
|
+
'Referrer-Policy': 'strict-origin-when-cross-origin',
|
|
129
|
+
'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
|
|
130
|
+
'Permissions-Policy': 'geolocation=(), microphone=(), camera=()',
|
|
131
|
+
'Content-Security-Policy': [
|
|
132
|
+
// Default policy
|
|
133
|
+
"default-src 'self'",
|
|
134
|
+
// Scripts
|
|
135
|
+
`script-src ${SCRIPT_SOURCES.join(' ')}`,
|
|
136
|
+
// Styles
|
|
137
|
+
"style-src 'self' 'unsafe-inline'",
|
|
138
|
+
// Images
|
|
139
|
+
"img-src 'self' data: https:",
|
|
140
|
+
// Connections
|
|
141
|
+
`connect-src ${CONNECT_SOURCES.join(' ')}`,
|
|
142
|
+
// Frames
|
|
143
|
+
`frame-src ${FRAME_SOURCES.join(' ')}`,
|
|
144
|
+
// Fonts
|
|
145
|
+
`font-src ${FONT_SOURCES.join(' ')}`,
|
|
146
|
+
// Disallow object/embed tags (Flash, Java, etc.)
|
|
147
|
+
"object-src 'none'",
|
|
148
|
+
// Security directives
|
|
149
|
+
"base-uri 'self'",
|
|
150
|
+
"form-action 'self'",
|
|
151
|
+
"upgrade-insecure-requests",
|
|
152
|
+
"block-all-mixed-content"
|
|
153
|
+
].join('; ')
|
|
154
|
+
};
|
|
155
|
+
}
|
package/dist/middleware.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,SAAS,mCA8DpB,CAAC"}
|
package/dist/middleware.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Global middleware for session validation
|
|
2
2
|
// Runs before all route handlers to enforce authentication
|
|
3
3
|
import { defineMiddleware } from 'astro:middleware';
|
|
4
|
-
import { PUBLIC_ROUTES, PUBLIC_PREFIXES,
|
|
4
|
+
import { PUBLIC_ROUTES, PUBLIC_PREFIXES, GET_SECURITY_HEADERS, GET_SKIP_ASSETS } from './config';
|
|
5
5
|
import { sanitizePath } from './security';
|
|
6
6
|
import { validateSession, validateMemberIdInUrl } from './auth';
|
|
7
7
|
/** Check if a path is a public route (no auth required) */
|
|
@@ -11,7 +11,7 @@ function isPublicRoute(pathname) {
|
|
|
11
11
|
}
|
|
12
12
|
/** Add security headers to a response */
|
|
13
13
|
function addSecurityHeaders(response) {
|
|
14
|
-
Object.entries(
|
|
14
|
+
Object.entries(GET_SECURITY_HEADERS()).forEach(([key, value]) => {
|
|
15
15
|
response.headers.set(key, value);
|
|
16
16
|
});
|
|
17
17
|
return response;
|
|
@@ -23,12 +23,11 @@ export const onRequest = defineMiddleware(async (context, next) => {
|
|
|
23
23
|
// Type assertion for locals (users should extend App.Locals in their project)
|
|
24
24
|
const authLocals = locals;
|
|
25
25
|
// Skip middleware for static assets FIRST (before dev mode)
|
|
26
|
-
if (
|
|
26
|
+
if (GET_SKIP_ASSETS().includes(pathname)) {
|
|
27
27
|
return next();
|
|
28
28
|
}
|
|
29
29
|
// DEV MODE: Skip auth on localhost
|
|
30
30
|
if (import.meta.env.DEV && (url.hostname === 'localhost' || url.hostname === '127.0.0.1')) {
|
|
31
|
-
// Check if public route first
|
|
32
31
|
if (isPublicRoute(pathname)) {
|
|
33
32
|
authLocals.recordId = null;
|
|
34
33
|
return next();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mindfulauth/core",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Mindful Auth core authentication library for Astro",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"astro": "^5.0.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"astro": "^5.17.
|
|
48
|
+
"astro": "^5.17.3",
|
|
49
49
|
"typescript": "^5.9.3"
|
|
50
50
|
}
|
|
51
51
|
}
|