Compare commits

...

2 Commits

Author SHA1 Message Date
ced3fd03e4 Add admin password reset script with mysql2 dependency
Some checks failed
Deploy to Vercel / deploy (push) Has been cancelled
Deploy to Railway / deploy (push) Has been cancelled
2025-08-22 12:21:24 +09:00
1a053ca047 Fix MariaDB connection to use Unix socket 2025-08-22 11:23:39 +09:00
5 changed files with 199 additions and 15 deletions

View File

@@ -47,7 +47,8 @@
"Bash(npm install)", "Bash(npm install)",
"Bash(powershell:*)", "Bash(powershell:*)",
"Bash(schtasks:*)", "Bash(schtasks:*)",
"Bash(cmd //c:*)" "Bash(cmd //c:*)",
"Bash(npm install:*)"
], ],
"deny": [], "deny": [],
"ask": [], "ask": [],

View File

@@ -5,15 +5,11 @@ class MariaDBHelper {
constructor() { constructor() {
this.connection = null; this.connection = null;
this.config = { this.config = {
host: 'localhost', socketPath: '/run/mysqld/mysqld10.sock',
port: 3306,
user: 'jaryo_user', user: 'jaryo_user',
password: 'JaryoPass2024!@#', password: 'JaryoPass2024!@#',
database: 'jaryo', database: 'jaryo',
charset: 'utf8mb4', charset: 'utf8mb4'
timezone: '+09:00',
acquireTimeout: 60000,
timeout: 60000
}; };
} }
@@ -21,7 +17,7 @@ class MariaDBHelper {
try { try {
if (!this.connection || this.connection.connection._closing) { if (!this.connection || this.connection.connection._closing) {
this.connection = await mysql.createConnection(this.config); this.connection = await mysql.createConnection(this.config);
console.log('✅ MariaDB 연결 성공'); console.log('✅ MariaDB 연결 성공 (Unix Socket)');
} }
return this.connection; return this.connection;
} catch (error) { } catch (error) {

122
package-lock.json generated
View File

@@ -14,6 +14,7 @@
"express": "^4.18.2", "express": "^4.18.2",
"express-session": "^1.17.3", "express-session": "^1.17.3",
"multer": "^1.4.5-lts.1", "multer": "^1.4.5-lts.1",
"mysql2": "^3.14.3",
"sqlite3": "^5.1.6", "sqlite3": "^5.1.6",
"uuid": "^9.0.1" "uuid": "^9.0.1"
}, },
@@ -1115,6 +1116,15 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/aws-ssl-profiles": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz",
"integrity": "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==",
"license": "MIT",
"engines": {
"node": ">= 6.0.0"
}
},
"node_modules/balanced-match": { "node_modules/balanced-match": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -1575,6 +1585,15 @@
"integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/denque": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
"integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==",
"license": "Apache-2.0",
"engines": {
"node": ">=0.10"
}
},
"node_modules/depd": { "node_modules/depd": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -2479,6 +2498,15 @@
"node": "^12.13.0 || ^14.15.0 || >=16.0.0" "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
} }
}, },
"node_modules/generate-function": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz",
"integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==",
"license": "MIT",
"dependencies": {
"is-property": "^1.0.2"
}
},
"node_modules/generic-pool": { "node_modules/generic-pool": {
"version": "3.4.2", "version": "3.4.2",
"resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.4.2.tgz", "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.4.2.tgz",
@@ -2913,6 +2941,12 @@
"node": ">=0.12.0" "node": ">=0.12.0"
} }
}, },
"node_modules/is-property": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
"integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==",
"license": "MIT"
},
"node_modules/is-stream": { "node_modules/is-stream": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
@@ -2968,6 +3002,12 @@
"graceful-fs": "^4.1.6" "graceful-fs": "^4.1.6"
} }
}, },
"node_modules/long": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
"license": "Apache-2.0"
},
"node_modules/lru-cache": { "node_modules/lru-cache": {
"version": "6.0.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -2981,6 +3021,21 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/lru.min": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.2.tgz",
"integrity": "sha512-Nv9KddBcQSlQopmBHXSsZVY5xsdlZkdH/Iey0BlcBYggMd4two7cZnKOK9vmy3nY0O5RGH99z1PCeTpPqszUYg==",
"license": "MIT",
"engines": {
"bun": ">=1.0.0",
"deno": ">=1.30.0",
"node": ">=8.0.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wellwelwel"
}
},
"node_modules/make-dir": { "node_modules/make-dir": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
@@ -3439,6 +3494,59 @@
"node": ">= 6.0.0" "node": ">= 6.0.0"
} }
}, },
"node_modules/mysql2": {
"version": "3.14.3",
"resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.14.3.tgz",
"integrity": "sha512-fD6MLV8XJ1KiNFIF0bS7Msl8eZyhlTDCDl75ajU5SJtpdx9ZPEACulJcqJWr1Y8OYyxsFc4j3+nflpmhxCU5aQ==",
"license": "MIT",
"dependencies": {
"aws-ssl-profiles": "^1.1.1",
"denque": "^2.1.0",
"generate-function": "^2.3.1",
"iconv-lite": "^0.6.3",
"long": "^5.2.1",
"lru.min": "^1.0.0",
"named-placeholders": "^1.1.3",
"seq-queue": "^0.0.5",
"sqlstring": "^2.3.2"
},
"engines": {
"node": ">= 8.0"
}
},
"node_modules/mysql2/node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/named-placeholders": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz",
"integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==",
"license": "MIT",
"dependencies": {
"lru-cache": "^7.14.1"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/named-placeholders/node_modules/lru-cache": {
"version": "7.18.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
"integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
"license": "ISC",
"engines": {
"node": ">=12"
}
},
"node_modules/napi-build-utils": { "node_modules/napi-build-utils": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
@@ -4197,6 +4305,11 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/seq-queue": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz",
"integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q=="
},
"node_modules/serve-static": { "node_modules/serve-static": {
"version": "1.16.2", "version": "1.16.2",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
@@ -4460,6 +4573,15 @@
} }
} }
}, },
"node_modules/sqlstring": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz",
"integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/ssri": { "node_modules/ssri": {
"version": "8.0.1", "version": "8.0.1",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",

View File

@@ -9,18 +9,22 @@
"build": "echo 'Build complete'" "build": "echo 'Build complete'"
}, },
"dependencies": { "dependencies": {
"express": "^4.18.2",
"cors": "^2.8.5",
"multer": "^1.4.5-lts.1",
"bcrypt": "^5.1.1", "bcrypt": "^5.1.1",
"cors": "^2.8.5",
"express": "^4.18.2",
"express-session": "^1.17.3", "express-session": "^1.17.3",
"uuid": "^9.0.1", "multer": "^1.4.5-lts.1",
"sqlite3": "^5.1.6" "mysql2": "^3.14.3",
"sqlite3": "^5.1.6",
"uuid": "^9.0.1"
}, },
"devDependencies": { "devDependencies": {
"vercel": "^32.0.0" "vercel": "^32.0.0"
}, },
"keywords": ["file-manager", "admin"], "keywords": [
"file-manager",
"admin"
],
"author": "Claude Code", "author": "Claude Code",
"license": "MIT", "license": "MIT",
"engines": { "engines": {

61
reset-admin.js Normal file
View File

@@ -0,0 +1,61 @@
const bcrypt = require('bcrypt');
const MariaDBHelper = require('./database/mariadb-helper');
async function resetAdminPassword() {
const dbHelper = new MariaDBHelper();
try {
console.log('🔄 관리자 비밀번호 초기화 시작...');
const password = 'Hee150603!';
const saltRounds = 10;
const hashedPassword = await bcrypt.hash(password, saltRounds);
console.log('🔐 해시된 비밀번호:', hashedPassword);
// 관리자 사용자 확인
const existingUser = await dbHelper.getUserByEmail('admin@jaryo.com');
if (existingUser) {
// 기존 사용자 비밀번호 업데이트
const conn = await dbHelper.connect();
const [result] = await conn.execute(
'UPDATE users SET password_hash = ? WHERE email = ?',
[hashedPassword, 'admin@jaryo.com']
);
console.log('✅ 기존 관리자 비밀번호가 업데이트되었습니다.');
} else {
// 새 관리자 사용자 생성
const adminData = {
email: 'admin@jaryo.com',
password_hash: hashedPassword,
name: '관리자',
role: 'admin'
};
const result = await dbHelper.createUser(adminData);
console.log('✅ 새 관리자 사용자가 생성되었습니다.');
}
// 로그인 테스트
const user = await dbHelper.getUserByEmail('admin@jaryo.com');
const isValid = await bcrypt.compare(password, user.password_hash);
console.log('🧪 로그인 테스트 결과:', isValid ? '성공' : '실패');
if (isValid) {
console.log('🎉 관리자 계정 설정 완료!');
console.log('📧 이메일: admin@jaryo.com');
console.log('🔑 비밀번호: Hee150603!');
}
await dbHelper.close();
} catch (error) {
console.error('❌ 오류 발생:', error);
await dbHelper.close();
process.exit(1);
}
}
resetAdminPassword();