@porulle/core 0.74.1 → 0.74.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/runtime/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAQhD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAQzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAStE,KAAK,SAAS,GAAG;IACf,SAAS,EAAE;QACT,IAAI,EAAE,YAAY,CAAC;QACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAcvC;AAeD;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,cAAc;;;;;sBAwXxB,MAAM,UAAU,MAAM;GA8GtD"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/runtime/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAQhD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAQzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAStE,KAAK,SAAS,GAAG;IACf,SAAS,EAAE;QACT,IAAI,EAAE,YAAY,CAAC;QACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAcvC;AAeD;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,cAAc;;;;;sBAgYxB,MAAM,UAAU,MAAM;GA8GtD"}
@@ -166,11 +166,20 @@ export async function createServer(config) {
166
166
  ? trustedOrigins
167
167
  : (process.env.NODE_ENV === "production" ? [] : ["http://localhost:*"]),
168
168
  });
169
+ //
170
+ // The same reasoning covers a request that carries NO credential at all: with no cookie there is
171
+ // nothing ambient for a forged request to ride on. A store's webhook is exactly that — WooCommerce
172
+ // pings a new subscription with a cookieless, Origin-less form POST and refuses to create the
173
+ // subscription unless it is answered 2xx. The one cookieless forgery that matters is login CSRF
174
+ // (signing a victim into the attacker's account), so the auth routes keep the check regardless.
169
175
  app.use("/api/*", async (c, next) => {
170
176
  const authenticatedByKey = !!c.req.header("x-api-key") ||
171
177
  /^Bearer\s+/i.test(c.req.header("authorization") ?? "");
172
178
  if (authenticatedByKey)
173
179
  return next();
180
+ const ambientCredential = !!c.req.header("cookie");
181
+ if (!ambientCredential && !c.req.path.startsWith("/api/auth/"))
182
+ return next();
174
183
  // Run only the CSRF origin check here; invoke the real downstream afterwards
175
184
  // so a genuine 403 from a route handler can't be misattributed to CSRF.
176
185
  let passedCsrf = false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@porulle/core",
3
- "version": "0.74.1",
3
+ "version": "0.74.2",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -60,8 +60,8 @@
60
60
  "eslint": "^9.39.1",
61
61
  "typescript": "5.9.2",
62
62
  "vitest": "^3.2.4",
63
- "@porulle/eslint-config": "0.1.0",
64
- "@porulle/typescript-config": "0.1.0"
63
+ "@porulle/typescript-config": "0.1.0",
64
+ "@porulle/eslint-config": "0.1.0"
65
65
  },
66
66
  "publishConfig": {
67
67
  "access": "public"
@@ -204,11 +204,19 @@ export async function createServer(config: CommerceConfig) {
204
204
  ? trustedOrigins
205
205
  : (process.env.NODE_ENV === "production" ? [] : ["http://localhost:*"]),
206
206
  });
207
+ //
208
+ // The same reasoning covers a request that carries NO credential at all: with no cookie there is
209
+ // nothing ambient for a forged request to ride on. A store's webhook is exactly that — WooCommerce
210
+ // pings a new subscription with a cookieless, Origin-less form POST and refuses to create the
211
+ // subscription unless it is answered 2xx. The one cookieless forgery that matters is login CSRF
212
+ // (signing a victim into the attacker's account), so the auth routes keep the check regardless.
207
213
  app.use("/api/*", async (c, next) => {
208
214
  const authenticatedByKey =
209
215
  !!c.req.header("x-api-key") ||
210
216
  /^Bearer\s+/i.test(c.req.header("authorization") ?? "");
211
217
  if (authenticatedByKey) return next();
218
+ const ambientCredential = !!c.req.header("cookie");
219
+ if (!ambientCredential && !c.req.path.startsWith("/api/auth/")) return next();
212
220
 
213
221
  // Run only the CSRF origin check here; invoke the real downstream afterwards
214
222
  // so a genuine 403 from a route handler can't be misattributed to CSRF.