summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
Diffstat (limited to 'components')
-rw-r--r--components/login/login-form-shi.tsx18
-rw-r--r--components/login/saml-login-button.tsx98
2 files changed, 116 insertions, 0 deletions
diff --git a/components/login/login-form-shi.tsx b/components/login/login-form-shi.tsx
index d22e15a8..6be8d5c8 100644
--- a/components/login/login-form-shi.tsx
+++ b/components/login/login-form-shi.tsx
@@ -21,6 +21,7 @@ import { verifyTokenAction } from "@/lib/users/verifyToken";
import { buttonVariants } from "@/components/ui/button"
import Link from "next/link"
import Image from 'next/image'; // 추가: Image 컴포넌트 import
+import { KnoxSSOButton } from './saml-login-button'; // SAML 로그인 버튼 import
export function LoginFormSHI({
className,
@@ -225,6 +226,23 @@ export function LoginFormSHI({
<Button type="submit" className="w-full" variant="samsung" disabled={isLoading}>
{isLoading ? t('sending') : t('ContinueWithEmail')}
</Button>
+
+ {/* 구분선과 "Or continue with" 섹션 추가 */}
+ <div className="relative">
+ <div className="absolute inset-0 flex items-center">
+ <span className="w-full border-t"></span>
+ </div>
+ <div className="relative flex justify-center text-xs uppercase">
+ <span className="bg-background px-2 text-muted-foreground">
+ {t('orContinueWith')}
+ </span>
+ </div>
+ </div>
+
+ {/* SAML 로그인 버튼 - 로직 분리 */}
+ <KnoxSSOButton />
+
+ {/* 언어 선택 드롭다운 */}
<div className="text-center text-sm mx-auto">
<DropdownMenu>
<DropdownMenuTrigger asChild>
diff --git a/components/login/saml-login-button.tsx b/components/login/saml-login-button.tsx
new file mode 100644
index 00000000..2f23bedf
--- /dev/null
+++ b/components/login/saml-login-button.tsx
@@ -0,0 +1,98 @@
+'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'
+}
+
+export function SAMLLoginButton({
+ className,
+ children = "Knox SSO로 로그인하기",
+ variant = "outline",
+ size = "default"
+}: SAMLLoginButtonProps) {
+ const [isLoading, setIsLoading] = useState(false)
+
+ const handleSAMLLogin = async () => {
+ try {
+ setIsLoading(true)
+
+ // API 엔드포인트를 통해 SAML AuthnRequest URL 생성
+ const response = await fetch('/api/auth/saml/authn-request', {
+ 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)
+
+ // IdP로 리다이렉트
+ window.location.href = data.loginUrl
+
+ } catch (error) {
+ console.error('SAML Login Error:', error)
+ toast({
+ title: '로그인 오류',
+ description: 'SAML 로그인을 시작할 수 없습니다.',
+ variant: 'destructive',
+ })
+ setIsLoading(false)
+ }
+ }
+
+ return (
+ <Button
+ type="button"
+ variant={variant}
+ size={size}
+ className={className}
+ onClick={handleSAMLLogin}
+ disabled={isLoading}
+ >
+ {isLoading ? (
+ <Loader2 className="h-4 w-4 animate-spin mr-2" />
+ ) : (
+ <Shield className="h-4 w-4 mr-2" />
+ )}
+ {children}
+ </Button>
+ )
+}
+
+// 간단한 Knox SSO 버튼 (props 없이)
+export function KnoxSSOButton() {
+ return (
+ <SAMLLoginButton
+ className="w-full"
+ variant="outline"
+ >
+ Knox SSO (STAGE 단계)
+ </SAMLLoginButton>
+ )
+}