83 lines
2.5 KiB
TypeScript
83 lines
2.5 KiB
TypeScript
import { insertReturning, queryOne } from '../../utils/db'
|
|
import { getCurrentUserId } from '../../utils/user'
|
|
import crypto from 'crypto'
|
|
|
|
interface CreateBody {
|
|
serverId: number
|
|
vcsUsername: string
|
|
vcsEmail?: string
|
|
authType: string // password | token | ssh
|
|
credential?: string
|
|
}
|
|
|
|
// 간단한 암호화 (실제 운영에서는 더 강력한 방식 사용)
|
|
function encryptCredential(text: string): string {
|
|
const key = process.env.ENCRYPTION_KEY || 'weeklyreport-default-key-32byte!'
|
|
const iv = crypto.randomBytes(16)
|
|
const cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(key.padEnd(32, '0').slice(0, 32)), iv)
|
|
let encrypted = cipher.update(text, 'utf8', 'hex')
|
|
encrypted += cipher.final('hex')
|
|
return iv.toString('hex') + ':' + encrypted
|
|
}
|
|
|
|
/**
|
|
* VCS 계정 등록
|
|
* POST /api/vcs-account/create
|
|
*/
|
|
export default defineEventHandler(async (event) => {
|
|
const body = await readBody<CreateBody>(event)
|
|
const userId = await getCurrentUserId(event)
|
|
|
|
if (!body.serverId) {
|
|
throw createError({ statusCode: 400, message: 'VCS 서버를 선택해주세요.' })
|
|
}
|
|
|
|
if (!body.vcsUsername?.trim()) {
|
|
throw createError({ statusCode: 400, message: 'VCS 사용자명을 입력해주세요.' })
|
|
}
|
|
|
|
// 서버 존재 확인
|
|
const server = await queryOne('SELECT * FROM wr_vcs_server WHERE server_id = $1 AND is_active = true', [body.serverId])
|
|
if (!server) {
|
|
throw createError({ statusCode: 404, message: 'VCS 서버를 찾을 수 없습니다.' })
|
|
}
|
|
|
|
// 중복 확인
|
|
const existing = await queryOne(
|
|
'SELECT * FROM wr_employee_vcs_account WHERE employee_id = $1 AND server_id = $2',
|
|
[userId, body.serverId]
|
|
)
|
|
if (existing) {
|
|
throw createError({ statusCode: 400, message: '이미 해당 서버에 계정이 등록되어 있습니다.' })
|
|
}
|
|
|
|
// 자격증명 암호화
|
|
let encryptedCred = null
|
|
if (body.credential) {
|
|
encryptedCred = encryptCredential(body.credential)
|
|
}
|
|
|
|
const result = await insertReturning(`
|
|
INSERT INTO wr_employee_vcs_account (
|
|
employee_id, server_id, vcs_username, vcs_email, auth_type, encrypted_credential, is_active
|
|
) VALUES ($1, $2, $3, $4, $5, $6, true)
|
|
RETURNING *
|
|
`, [
|
|
userId,
|
|
body.serverId,
|
|
body.vcsUsername.trim(),
|
|
body.vcsEmail || null,
|
|
body.authType || 'password',
|
|
encryptedCred
|
|
])
|
|
|
|
return {
|
|
success: true,
|
|
account: {
|
|
accountId: result.account_id,
|
|
serverId: result.server_id,
|
|
vcsUsername: result.vcs_username
|
|
}
|
|
}
|
|
})
|