'use client' /** * * SAML 2.0 기반 SSO 로그인 요청을 시작하는 버튼 컴포넌트 * * */ import { useState } from 'react' import { Button } from '@/components/ui/button' import { toast } from '@/hooks/use-toast' import { Loader2, Shield } from 'lucide-react' import React from 'react' interface SAMLLoginButtonProps { className?: string children?: React.ReactNode variant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link' | 'samsung' size?: 'default' | 'sm' | 'lg' | 'icon' } const isSsoStage = process.env.SAML_IDP_SSO_URL?.includes('stage'); export function SAMLLoginButton({ className, children = "Knox SSO로 로그인하기", variant = "outline", size = "default" }: SAMLLoginButtonProps) { const [isLoading, setIsLoading] = useState(false) const handleSAMLLogin = async () => { try { setIsLoading(true) // 현재 페이지 경로를 RelayState로 설정 (로그인 후 이 페이지로 돌아옴) const currentPath = window.location.pathname + window.location.search const relayState = encodeURIComponent(currentPath) console.log('Setting RelayState to:', currentPath) // API 엔드포인트를 통해 SAML AuthnRequest URL 생성 const response = await fetch(`/api/auth/saml/authn-request?relayState=${relayState}`, { method: 'GET', headers: { 'Content-Type': 'application/json', }, }) if (!response.ok) { throw new Error('Failed to create SAML AuthnRequest') } const data = await response.json() if (!data.success || !data.loginUrl) { throw new Error(data.error || 'Failed to get SAML login URL') } console.log('SAML Login URL:', data.loginUrl) // data URL인지 확인 (브라우저 보안 정책으로 차단될 수 있음) if (data.loginUrl.startsWith('data:')) { console.warn('⚠️ Data URL detected - this may be blocked by browser security policies') toast({ title: '테스트 모드 감지', description: 'Mock SAML IdP 모드가 활성화되어 있습니다. 프로덕션에서는 SAML_MOCKING_IDP=false로 설정하세요.', variant: 'default', }) // data URL 대신 Mock IdP 페이지로 직접 리다이렉트 const baseUrl = window.location.origin const mockIdpUrl = `${baseUrl}/api/auth/saml/mock-idp` console.log('🎭 Redirecting to Mock IdP instead:', mockIdpUrl) window.location.href = mockIdpUrl return } // 일반적인 URL로 리다이렉트 window.location.href = data.loginUrl } catch (error) { console.error('SAML Login Error:', error) toast({ title: '로그인 오류', description: 'SAML 로그인을 시작할 수 없습니다.', variant: 'destructive', }) setIsLoading(false) } } return ( ) } // 간단한 Knox SSO 버튼 (props 없이) export function KnoxSSOButton() { return ( {isSsoStage ? 'Knox SSO (STAGE)' : 'Knox SSO'} ) }