create-oss-store 1.0.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.
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { createOssStore } from '../src/index.js';
4
+
5
+ const args = process.argv.slice(2);
6
+ const projectName = args[0];
7
+
8
+ createOssStore(projectName);
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "create-oss-store",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "description": "Create a new OSS – OopsSec Store instance for web security CTF training",
6
+ "author": "kOaDT",
7
+ "license": "MIT",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/kOaDT/oss-oopssec-store"
11
+ },
12
+ "keywords": [
13
+ "ctf",
14
+ "security",
15
+ "vulnerable",
16
+ "web-security",
17
+ "owasp",
18
+ "penetration-testing",
19
+ "create",
20
+ "cli"
21
+ ],
22
+ "bin": {
23
+ "create-oss-store": "./bin/create-oss-store.js"
24
+ },
25
+ "files": [
26
+ "bin",
27
+ "src"
28
+ ],
29
+ "engines": {
30
+ "node": ">=18.0.0"
31
+ },
32
+ "dependencies": {
33
+ "chalk": "^5.3.0",
34
+ "degit": "^2.8.4",
35
+ "ora": "^8.1.1"
36
+ }
37
+ }
package/src/index.js ADDED
@@ -0,0 +1,143 @@
1
+ import { spawn } from "child_process";
2
+ import { writeFileSync, existsSync } from "fs";
3
+ import { resolve, join } from "path";
4
+ import chalk from "chalk";
5
+ import ora from "ora";
6
+ import degit from "degit";
7
+
8
+ const REPO = "kOaDT/oss-oopssec-store";
9
+
10
+ export async function createOssStore(projectName) {
11
+ console.log();
12
+ console.log(chalk.bold("OSS – OopsSec Store"));
13
+ console.log(chalk.dim("Vulnerable Web Application for Security Training"));
14
+ console.log();
15
+
16
+ if (!projectName) {
17
+ projectName = "oss-oopssec-store";
18
+ console.log(
19
+ chalk.yellow(`No project name provided, using "${projectName}"`)
20
+ );
21
+ console.log();
22
+ }
23
+
24
+ const targetPath = resolve(process.cwd(), projectName);
25
+
26
+ if (existsSync(targetPath)) {
27
+ console.log(chalk.red(`Error: Directory "${projectName}" already exists.`));
28
+ process.exit(1);
29
+ }
30
+
31
+ // Clone repository
32
+ const cloneSpinner = ora("Cloning repository...").start();
33
+ try {
34
+ const emitter = degit(REPO, { cache: false, force: true });
35
+ await emitter.clone(targetPath);
36
+ cloneSpinner.succeed("Repository cloned");
37
+ } catch (error) {
38
+ cloneSpinner.fail("Failed to clone repository");
39
+ console.error(chalk.red(error.message));
40
+ process.exit(1);
41
+ }
42
+
43
+ // Create .env file
44
+ const envSpinner = ora("Creating .env file...").start();
45
+ try {
46
+ const envPath = join(targetPath, ".env");
47
+ const dbPath = join(targetPath, "prisma", "dev.db");
48
+ writeFileSync(envPath, `DATABASE_URL="file:${dbPath}"\n`);
49
+ envSpinner.succeed(".env file created");
50
+ } catch (error) {
51
+ envSpinner.fail("Failed to create .env file");
52
+ console.error(chalk.red(error.message));
53
+ process.exit(1);
54
+ }
55
+
56
+ // Install dependencies
57
+ const installSpinner = ora("Installing dependencies...").start();
58
+ try {
59
+ await runCommand("npm", ["install"], targetPath);
60
+ installSpinner.succeed("Dependencies installed");
61
+ } catch (error) {
62
+ installSpinner.fail("Failed to install dependencies");
63
+ console.error(chalk.red(error.message));
64
+ process.exit(1);
65
+ }
66
+
67
+ // Generate Prisma client
68
+ const prismaSpinner = ora("Generating Prisma client...").start();
69
+ try {
70
+ await runCommand("npm", ["run", "db:generate"], targetPath);
71
+ prismaSpinner.succeed("Prisma client generated");
72
+ } catch (error) {
73
+ prismaSpinner.fail("Failed to generate Prisma client");
74
+ console.error(chalk.red(error.message));
75
+ process.exit(1);
76
+ }
77
+
78
+ // Push database schema
79
+ const dbSpinner = ora("Setting up database...").start();
80
+ try {
81
+ await runCommand("npm", ["run", "db:push"], targetPath);
82
+ dbSpinner.succeed("Database schema pushed");
83
+ } catch (error) {
84
+ dbSpinner.fail("Failed to push database schema");
85
+ console.error(chalk.red(error.message));
86
+ process.exit(1);
87
+ }
88
+
89
+ // Seed database
90
+ const seedSpinner = ora("Seeding database with CTF flags...").start();
91
+ try {
92
+ await runCommand("npm", ["run", "db:seed"], targetPath);
93
+ seedSpinner.succeed("Database seeded");
94
+ } catch (error) {
95
+ seedSpinner.fail("Failed to seed database");
96
+ console.error(chalk.red(error.message));
97
+ process.exit(1);
98
+ }
99
+
100
+ // Success message
101
+ console.log();
102
+ console.log(chalk.green.bold("Setup complete!"));
103
+ console.log();
104
+ console.log("To start hunting for flags:");
105
+ console.log();
106
+ console.log(chalk.cyan(` cd ${projectName}`));
107
+ console.log(chalk.cyan(" npm run dev"));
108
+ console.log();
109
+ console.log(
110
+ `Then open ${chalk.underline("http://localhost:3000")} in your browser.`
111
+ );
112
+ console.log();
113
+ console.log(chalk.dim("Good luck finding all the flags!"));
114
+ console.log();
115
+ }
116
+
117
+ function runCommand(command, args, cwd) {
118
+ return new Promise((resolve, reject) => {
119
+ const child = spawn(command, args, {
120
+ cwd,
121
+ stdio: "pipe",
122
+ shell: process.platform === "win32",
123
+ });
124
+
125
+ let stderr = "";
126
+
127
+ child.stderr.on("data", (data) => {
128
+ stderr += data.toString();
129
+ });
130
+
131
+ child.on("close", (code) => {
132
+ if (code === 0) {
133
+ resolve();
134
+ } else {
135
+ reject(new Error(stderr || `Command failed with code ${code}`));
136
+ }
137
+ });
138
+
139
+ child.on("error", (error) => {
140
+ reject(error);
141
+ });
142
+ });
143
+ }