create-mantiq 0.5.9 → 0.5.10

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-mantiq",
3
- "version": "0.5.9",
3
+ "version": "0.5.10",
4
4
  "description": "Scaffold a new MantiqJS application",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -3,13 +3,24 @@ function getCookie(name: string): string | null {
3
3
  return match ? decodeURIComponent(match[1]!) : null
4
4
  }
5
5
 
6
+ /** Ensure a session + XSRF-TOKEN cookie exists before mutating requests. */
7
+ let csrfReady: Promise<void> | null = null
8
+ async function ensureCsrf(): Promise<void> {
9
+ if (getCookie('XSRF-TOKEN')) return
10
+ if (!csrfReady) {
11
+ csrfReady = fetch('/csrf-cookie', { credentials: 'same-origin' }).then(() => { csrfReady = null })
12
+ }
13
+ await csrfReady
14
+ }
15
+
6
16
  export async function api<T = any>(url: string, opts: RequestInit = {}): Promise<{ ok: boolean; status: number; data: T }> {
7
17
  const headers: Record<string, string> = { Accept: 'application/json', ...(opts.headers as Record<string, string>) }
8
18
 
9
- // Attach XSRF token for CSRF protection on mutating requests
10
- const xsrf = getCookie('XSRF-TOKEN')
11
- if (xsrf && opts.method && !['GET', 'HEAD', 'OPTIONS'].includes(opts.method)) {
12
- headers['X-XSRF-TOKEN'] = xsrf
19
+ // For mutating requests, ensure CSRF cookie exists then attach it
20
+ if (opts.method && !['GET', 'HEAD', 'OPTIONS'].includes(opts.method)) {
21
+ await ensureCsrf()
22
+ const xsrf = getCookie('XSRF-TOKEN')
23
+ if (xsrf) headers['X-XSRF-TOKEN'] = xsrf
13
24
  }
14
25
 
15
26
  const res = await fetch(url, { ...opts, credentials: 'same-origin', headers })
@@ -18,6 +18,13 @@ export default function (router: Router) {
18
18
  router.get('/account/security', [PageController, 'security']).middleware('auth')
19
19
  router.get('/account/preferences', [PageController, 'preferences']).middleware('auth')
20
20
 
21
+ // CSRF cookie — SPA calls this on mount to establish session + XSRF token
22
+ router.get('/csrf-cookie', (request: any) => {
23
+ // Session middleware already started the session and CSRF middleware
24
+ // will attach the XSRF-TOKEN cookie on the response. Just return 204.
25
+ return new Response(null, { status: 204 })
26
+ })
27
+
21
28
  // Auth actions
22
29
  router.post('/login', [AuthController, 'login'])
23
30
  router.post('/register', [AuthController, 'register'])
@@ -3,13 +3,24 @@ function getCookie(name: string): string | null {
3
3
  return match ? decodeURIComponent(match[1]!) : null
4
4
  }
5
5
 
6
+ /** Ensure a session + XSRF-TOKEN cookie exists before mutating requests. */
7
+ let csrfReady: Promise<void> | null = null
8
+ async function ensureCsrf(): Promise<void> {
9
+ if (getCookie('XSRF-TOKEN')) return
10
+ if (!csrfReady) {
11
+ csrfReady = fetch('/csrf-cookie', { credentials: 'same-origin' }).then(() => { csrfReady = null })
12
+ }
13
+ await csrfReady
14
+ }
15
+
6
16
  export async function api<T = any>(url: string, opts: RequestInit = {}): Promise<{ ok: boolean; status: number; data: T }> {
7
17
  const headers: Record<string, string> = { Accept: 'application/json', ...(opts.headers as Record<string, string>) }
8
18
 
9
- // Attach XSRF token for CSRF protection on mutating requests
10
- const xsrf = getCookie('XSRF-TOKEN')
11
- if (xsrf && opts.method && !['GET', 'HEAD', 'OPTIONS'].includes(opts.method)) {
12
- headers['X-XSRF-TOKEN'] = xsrf
19
+ // For mutating requests, ensure CSRF cookie exists then attach it
20
+ if (opts.method && !['GET', 'HEAD', 'OPTIONS'].includes(opts.method)) {
21
+ await ensureCsrf()
22
+ const xsrf = getCookie('XSRF-TOKEN')
23
+ if (xsrf) headers['X-XSRF-TOKEN'] = xsrf
13
24
  }
14
25
 
15
26
  const res = await fetch(url, { ...opts, credentials: 'same-origin', headers })
@@ -3,13 +3,24 @@ function getCookie(name: string): string | null {
3
3
  return match ? decodeURIComponent(match[1]!) : null
4
4
  }
5
5
 
6
+ /** Ensure a session + XSRF-TOKEN cookie exists before mutating requests. */
7
+ let csrfReady: Promise<void> | null = null
8
+ async function ensureCsrf(): Promise<void> {
9
+ if (getCookie('XSRF-TOKEN')) return
10
+ if (!csrfReady) {
11
+ csrfReady = fetch('/csrf-cookie', { credentials: 'same-origin' }).then(() => { csrfReady = null })
12
+ }
13
+ await csrfReady
14
+ }
15
+
6
16
  export async function api<T = any>(url: string, opts: RequestInit = {}): Promise<{ ok: boolean; status: number; data: T }> {
7
17
  const headers: Record<string, string> = { Accept: 'application/json', ...(opts.headers as Record<string, string>) }
8
18
 
9
- // Attach XSRF token for CSRF protection on mutating requests
10
- const xsrf = getCookie('XSRF-TOKEN')
11
- if (xsrf && opts.method && !['GET', 'HEAD', 'OPTIONS'].includes(opts.method)) {
12
- headers['X-XSRF-TOKEN'] = xsrf
19
+ // For mutating requests, ensure CSRF cookie exists then attach it
20
+ if (opts.method && !['GET', 'HEAD', 'OPTIONS'].includes(opts.method)) {
21
+ await ensureCsrf()
22
+ const xsrf = getCookie('XSRF-TOKEN')
23
+ if (xsrf) headers['X-XSRF-TOKEN'] = xsrf
13
24
  }
14
25
 
15
26
  const res = await fetch(url, { ...opts, credentials: 'same-origin', headers })