create-kide-app 0.0.26 → 0.0.28

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/index.js CHANGED
@@ -291,8 +291,8 @@ async function main() {
291
291
  s.stop("Demo content seeded");
292
292
  } catch (err) {
293
293
  s.stop("Seeding failed — run `pnpm cms:seed` manually");
294
- if (err.stderr) console.error(err.stderr.toString().slice(-1500));
295
- if (err.stdout) console.error(err.stdout.toString().slice(-1500));
294
+ if (err.stderr) console.error(err.stderr.toString());
295
+ if (err.stdout) console.error(err.stdout.toString());
296
296
  }
297
297
  } else if (seedDemo && target === "cloudflare") {
298
298
  p.note(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-kide-app",
3
- "version": "0.0.26",
3
+ "version": "0.0.28",
4
4
  "description": "Scaffold a new Kide CMS project",
5
5
  "author": "Matti Hernesniemi",
6
6
  "license": "MIT",
@@ -4,8 +4,17 @@ import path from "node:path";
4
4
 
5
5
  const publicDir = path.join(process.cwd(), "public");
6
6
 
7
+ // Resolve storagePath safely under publicDir, rejecting any traversal attempts
8
+ function safeResolve(storagePath: string): string {
9
+ const resolved = path.resolve(publicDir, storagePath.replace(/^\/+/, ""));
10
+ if (!resolved.startsWith(publicDir + path.sep) && resolved !== publicDir) {
11
+ throw new Error(`Invalid storage path: ${storagePath}`);
12
+ }
13
+ return resolved;
14
+ }
15
+
7
16
  export async function putFile(storagePath: string, data: ArrayBuffer | Uint8Array): Promise<void> {
8
- const filePath = path.join(publicDir, storagePath);
17
+ const filePath = safeResolve(storagePath);
9
18
  const dir = path.dirname(filePath);
10
19
  if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
11
20
  const buffer = data instanceof Uint8Array ? data : new Uint8Array(data);
@@ -13,14 +22,14 @@ export async function putFile(storagePath: string, data: ArrayBuffer | Uint8Arra
13
22
  }
14
23
 
15
24
  export async function getFile(storagePath: string): Promise<ArrayBuffer | null> {
16
- const filePath = path.join(publicDir, storagePath);
25
+ const filePath = safeResolve(storagePath);
17
26
  if (!existsSync(filePath)) return null;
18
27
  const buffer = await readFile(filePath);
19
28
  return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
20
29
  }
21
30
 
22
31
  export async function deleteFile(storagePath: string): Promise<void> {
23
- const filePath = path.join(publicDir, storagePath);
32
+ const filePath = safeResolve(storagePath);
24
33
  try {
25
34
  await unlink(filePath);
26
35
  } catch {
@@ -1,3 +1,4 @@
1
+ import path from "node:path";
1
2
  import { defineConfig } from "drizzle-kit";
2
3
 
3
4
  export default defineConfig({
@@ -5,6 +6,6 @@ export default defineConfig({
5
6
  out: "./src/cms/migrations",
6
7
  dialect: "sqlite",
7
8
  dbCredentials: {
8
- url: process.env.CMS_DATABASE_URL ?? "file:./data/cms.db",
9
+ url: process.env.CMS_DATABASE_URL ?? `file:${path.resolve("./data/cms.db")}`,
9
10
  },
10
11
  });