UNPKG

@restnfeel/agentc-starter-kit

Version:

한국어 기업용 CMS 모듈 - Task Master AI와 함께 빠르게 웹사이트를 구현할 수 있는 재사용 가능한 컴포넌트 시스템

212 lines (188 loc) 6.05 kB
import { NextRequest, NextResponse } from "next/server"; import { getServerSession } from "next-auth"; import { authOptions } from "../../../../lib/auth"; import { UserRole, Permission, PermissionChecker, getUserPermissions, } from "../../../../lib/auth/roles"; import { sendInvitationEmail } from "../../../../lib/email/invitation"; import { generateInviteToken } from "../../../../lib/auth/tokens"; interface InviteUserRequest { email: string; role: UserRole; siteIds?: string[]; message?: string; } export async function POST(request: NextRequest) { try { const session = await getServerSession(authOptions); if (!session?.user) { return NextResponse.json( { error: "인증이 필요합니다." }, { status: 401 } ); } // Check if user has permission to invite users const userPermissions = getUserPermissions( (session.user as any).role as UserRole, (session.user as any).siteIds ); const permissionChecker = new PermissionChecker(userPermissions); if (!permissionChecker.hasPermission(Permission.INVITE_USER)) { return NextResponse.json( { error: "사용자 초대 권한이 없습니다." }, { status: 403 } ); } const body: InviteUserRequest = await request.json(); const { email, role, siteIds, message } = body; // Validate required fields if (!email || !role) { return NextResponse.json( { error: "이메일과 역할은 필수입니다." }, { status: 400 } ); } // Validate email format const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(email)) { return NextResponse.json( { error: "유효한 이메일 주소를 입력해주세요." }, { status: 400 } ); } // Validate role if (!Object.values(UserRole).includes(role)) { return NextResponse.json( { error: "유효하지 않은 역할입니다." }, { status: 400 } ); } // Check if user can assign this role if ( role === UserRole.SUPER_ADMIN && (session.user as any).role !== UserRole.SUPER_ADMIN ) { return NextResponse.json( { error: "슈퍼 관리자 역할은 슈퍼 관리자만 할당할 수 있습니다." }, { status: 403 } ); } // Validate site access for site-specific roles if (siteIds && siteIds.length > 0) { const accessibleSites = permissionChecker.getAccessibleSites(); if (accessibleSites.length > 0) { // If not super admin const invalidSites = siteIds.filter( (siteId) => !accessibleSites.includes(siteId) ); if (invalidSites.length > 0) { return NextResponse.json( { error: `다음 사이트에 대한 접근 권한이 없습니다: ${invalidSites.join( ", " )}`, }, { status: 403 } ); } } } // Check if user already exists // This would typically check your user database // For now, we'll assume the user doesn't exist // Generate invitation token const inviteToken = generateInviteToken({ email, role, siteIds, invitedBy: (session.user as any).id, expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 days }); // Store invitation in database // This would typically save to your database // For now, we'll simulate this // Send invitation email try { await sendInvitationEmail({ to: email, inviteToken, invitedBy: session.user.name || session.user.email || "관리자", role, siteIds, message, }); } catch (emailError) { console.error("Failed to send invitation email:", emailError); return NextResponse.json( { error: "초대 이메일 발송에 실패했습니다." }, { status: 500 } ); } return NextResponse.json({ message: "사용자 초대가 성공적으로 발송되었습니다.", invitation: { email, role, siteIds, invitedBy: session.user.name || session.user.email, invitedAt: new Date().toISOString(), }, }); } catch (error) { console.error("User invitation error:", error); return NextResponse.json( { error: "사용자 초대 중 오류가 발생했습니다." }, { status: 500 } ); } } export async function GET(_request: NextRequest) { try { const session = await getServerSession(authOptions); if (!session?.user) { return NextResponse.json( { error: "인증이 필요합니다." }, { status: 401 } ); } // Check if user has permission to view users const userPermissions = getUserPermissions( (session.user as any).role as UserRole, (session.user as any).siteIds ); const permissionChecker = new PermissionChecker(userPermissions); if (!permissionChecker.hasPermission(Permission.VIEW_USERS)) { return NextResponse.json( { error: "사용자 조회 권한이 없습니다." }, { status: 403 } ); } // Get pending invitations // This would typically query your database for pending invitations // For now, we'll return a mock response const pendingInvitations = [ { id: "1", email: "user@example.com", role: UserRole.EDITOR, siteIds: ["site1", "site2"], invitedBy: session.user.name || session.user.email, invitedAt: new Date().toISOString(), expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(), status: "pending", }, ]; return NextResponse.json({ invitations: pendingInvitations, }); } catch (error) { console.error("Get invitations error:", error); return NextResponse.json( { error: "초대 목록 조회 중 오류가 발생했습니다." }, { status: 500 } ); } }