@xleddyl/nuxt-cms 0.1.37 → 0.1.39

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/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xleddyl/nuxt-cms",
3
3
  "configKey": "cms",
4
- "version": "0.1.37",
4
+ "version": "0.1.39",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "unknown"
@@ -2,6 +2,7 @@ import { createHash, timingSafeEqual } from "node:crypto";
2
2
  import { createError, defineEventHandler, getRequestIP, readValidatedBody } from "h3";
3
3
  import { z } from "zod";
4
4
  import { setUserSession, useRuntimeConfig, useStorage } from "#imports";
5
+ import { assertSameOrigin } from "../../utils/require-admin.js";
5
6
  const credentialsSchema = z.object({
6
7
  email: z.string().trim().min(1),
7
8
  password: z.string().min(1)
@@ -47,6 +48,7 @@ function safeEqual(a, b) {
47
48
  return timingSafeEqual(hashA, hashB);
48
49
  }
49
50
  export default defineEventHandler(async (event) => {
51
+ assertSameOrigin(event);
50
52
  const ip = rateKey(getRequestIP(event, { xForwardedFor: true }) ?? "unknown");
51
53
  const now = Date.now();
52
54
  const [attempts, globalFailures] = await Promise.all([
@@ -1,2 +1,3 @@
1
1
  import type { H3Event } from 'h3';
2
+ export declare function assertSameOrigin(event: H3Event): void;
2
3
  export declare function requireAdmin(event: H3Event): Promise<void>;
@@ -1,17 +1,27 @@
1
1
  import { createError, getRequestHeader, getRequestHost } from "h3";
2
2
  import { getUserSession, useRuntimeConfig } from "#imports";
3
- function assertSameOrigin(event) {
4
- const origin = getRequestHeader(event, "origin");
5
- if (!origin) return;
6
- let originHost;
3
+ const ORIGINLESS_SAFE_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD", "OPTIONS"]);
4
+ function hostOfUrl(value) {
5
+ if (!value) return void 0;
7
6
  try {
8
- originHost = new URL(origin).host;
7
+ const url = new URL(value);
8
+ return url.protocol === "http:" || url.protocol === "https:" ? url.host : void 0;
9
9
  } catch {
10
- originHost = void 0;
10
+ return void 0;
11
11
  }
12
- if (!originHost || originHost !== getRequestHost(event, { xForwardedHost: true })) {
13
- throw createError({ statusCode: 403, statusMessage: "Cross-origin request rejected" });
12
+ }
13
+ function rejectCrossOrigin() {
14
+ throw createError({ statusCode: 403, statusMessage: "Cross-origin request rejected" });
15
+ }
16
+ export function assertSameOrigin(event) {
17
+ const expectedHost = getRequestHost(event);
18
+ const origin = getRequestHeader(event, "origin");
19
+ if (origin) {
20
+ if (hostOfUrl(origin) !== expectedHost) rejectCrossOrigin();
21
+ return;
14
22
  }
23
+ if (ORIGINLESS_SAFE_METHODS.has(event.method)) return;
24
+ if (hostOfUrl(getRequestHeader(event, "referer")) !== expectedHost) rejectCrossOrigin();
15
25
  }
16
26
  export async function requireAdmin(event) {
17
27
  assertSameOrigin(event);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xleddyl/nuxt-cms",
3
- "version": "0.1.37",
3
+ "version": "0.1.39",
4
4
  "description": "Lightweight CMS that ships with your Nuxt app: runs on the Nitro server, content types defined in code, /cms admin panel, GraphQL API, SQLite or Postgres. No external CMS needed!",
5
5
  "license": "MIT",
6
6
  "author": "Edoardo Alberti (https://github.com/xleddyl)",
@@ -123,6 +123,6 @@
123
123
  "test": "vitest run",
124
124
  "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit",
125
125
  "format": "prettier --write \"**/*.{ts,tsx,js,jsx,md,html,json,sql,vue}\" --log-level error",
126
- "release": "changelogen --release --no-github && git push origin main && git push origin v$(node -p \"require('./package.json').version\")"
126
+ "release": "sh -c 'changelogen --release --no-github ${1:+--$1} && git push origin main --follow-tags' --"
127
127
  }
128
128
  }