Files
weeklyreport/backend/api/vcs-account/create.post.ts

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
}
}
})