from PyQt5.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QRadioButton, QPushButton, QLineEdit, QLabel, QMessageBox) from PyQt5.QtCore import QTimer, QTime import asyncio, traceback class TwoFactorAuthDialog(QMainWindow): def __init__(self): super().__init__() self.login_success_text = "" self.setWindowTitle("2단계 인증") self.setGeometry(300, 300, 400, 250) self.central_widget = QWidget() self.setCentralWidget(self.central_widget) self.layout = QVBoxLayout(self.central_widget) self.email_layout = QHBoxLayout() self.phone_layout = QHBoxLayout() self.code_layout = QHBoxLayout() # Email Auth Option self.email_radio = QRadioButton("이메일 인증") self.email_button = QPushButton("이메일 인증하기") self.email_button.clicked.connect(lambda: asyncio.ensure_future(self.email_auth())) self.email_layout.addWidget(self.email_radio) self.email_layout.addWidget(self.email_button) self.email_hint = QLabel("인증용 이메일 주소: example@example.com") # 기본 예시 이메일 주소 self.email_hint.setVisible(False) # Phone Auth Option self.phone_radio = QRadioButton("휴대폰 인증") self.phone_button = QPushButton("휴대폰 인증하기") self.phone_button.clicked.connect(lambda: asyncio.ensure_future(self.phone_auth())) self.phone_layout.addWidget(self.phone_radio) self.phone_layout.addWidget(self.phone_button) self.phone_hint = QLabel("인증용 휴대전화 번호: 010-1234-5678") # 기본 예시 휴대전화 번호 self.phone_hint.setVisible(False) # Code Entry self.codeWidget = QWidget() self.code_input = QLineEdit() self.code_input.setPlaceholderText("인증번호를 입력하세요") self.submit_button = QPushButton("확인") self.submit_button.clicked.connect(lambda: asyncio.ensure_future(self.submit_code())) self.code_layout.addWidget(self.code_input, 7) self.code_layout.addWidget(self.submit_button, 3) self.codeWidget.setLayout(self.code_layout) # self.codeWidget.setStyleSheet("border: 1px dashed black;") # Timer Label self.timer_label = QLabel("인증 유효 시간: 03:00") self.timer = QTimer() self.timer.timeout.connect(self.update_timer) self.time_left = QTime(0, 3, 0) self.layout.addLayout(self.email_layout,1) self.layout.addWidget(self.email_hint,1) self.layout.addLayout(self.phone_layout,1) self.layout.addWidget(self.phone_hint,1) self.layout.addWidget(self.codeWidget,4) self.layout.addWidget(self.timer_label,2) self.auth_method = None self.code = None self.popup_page = None def start_timer(self): self.time_left = QTime(0, 3, 0) self.timer.start(1000) def update_timer(self): self.time_left = self.time_left.addSecs(-1) self.timer_label.setText(f"인증 유효 시간: {self.time_left.toString('mm:ss')}") if self.time_left == QTime(0, 0, 0): self.timer.stop() QMessageBox.warning(self, "경고", "인증 시간이 초과되었습니다.") async def update_email_hint(self): email_hint_element = await self.popup_page.query_selector("input#auth_id.TextField_ipt__33BFT[placeholder='2단계 인증 이메일']") if email_hint_element: email_hint_text = await email_hint_element.get_attribute('value') self.email_hint.setText(f"인증용 이메일 주소: {email_hint_text}") self.email_hint.setVisible(True) async def update_phone_hint(self): phone_hint_element = await self.popup_page.query_selector("input#phone[placeholder='내용을 입력해주세요']") if phone_hint_element: phone_hint_text = await phone_hint_element.get_attribute('value') self.phone_hint.setText(f"인증용 휴대전화 번호: {phone_hint_text}") self.phone_hint.setVisible(True) async def email_auth(self): if self.email_radio.isChecked(): self.auth_method = 'email' self.email_hint.setVisible(True) self.phone_hint.setVisible(False) QMessageBox.information(self, "이메일 인증", "이메일로 인증 번호가 전송되었습니다.") print(f"1번 클릭 시작") await self.popup_page.click('div#root li:nth-child(1) > label') print(f"1번 클릭") await self.popup_page.click('div#root div.TextField_text_field__x1Wtz.TextField_field_email__2BzY5.TextField_disabled__2mxn3 > div > div > div.TextField_btn_box__2TdIe > button[type="button"]') print(f"2번 클릭") await self.popup_page.click('div#root button.PopupCommon_btn__33Of5[type="button"]') # 전송 확인 팝업의 확인 버튼 클릭 print(f"3번 클릭") self.start_timer() async def phone_auth(self): if self.phone_radio.isChecked(): self.auth_method = 'phone' self.email_hint.setVisible(False) self.phone_hint.setVisible(True) QMessageBox.information(self, "휴대폰 인증", "휴대폰으로 인증 번호가 전송되었습니다.") print(f"1번 클릭 시작") await self.popup_page.click('div#root li:nth-child(2) > label') print(f"1번 클릭") # await self.popup_page.click('div#root div.TextField_text_field__x1Wtz.TextField_field_phone__3MV-T.TextField_disabled__2mxn3 > div > div.TextField_btn_box__2TdIe > button[type="button"]') print(f"1-1번 클릭") await self.popup_page.click("#root > div > div.Layout_wrap__3uDBh > div > div > div > ul > li.TwoStepCertify_choice_item__2qian.TwoStepCertify_on__2Y_8N > div > div.TextField_text_field__x1Wtz.TextField_field_phone__3MV-T.TextField_disabled__2mxn3 > div > div.TextField_ipt_area__3lD1U > div.TextField_btn_box__2TdIe > button") print(f"2번 클릭") await self.popup_page.click('div#root button.PopupCommon_btn__33Of5[type="button"]') # 전송 확인 팝업의 확인 버튼 클릭 print(f"3번 클릭") self.start_timer() async def submit_code(self): try: self.code = self.code_input.text() if not self.code: QMessageBox.warning(self, "경고", "인증번호를 입력하세요.") else: if self.auth_method == 'email': await self.popup_page.fill('div#root input.TextField_ipt__33BFT[inputmode="numeric"][placeholder="인증번호 숫자 6자리"]', self.code) print(f"인증번호 [{self.code}] 입력") elif self.auth_method == 'phone': await self.popup_page.fill('div#root input.TextField_ipt__33BFT[inputmode="numeric"][placeholder="인증번호 숫자 6자리"]', self.code) print(f"인증번호 [{self.code}] 입력") await self.popup_page.click('div#root .TwoStepCertify_btn_box__3TSSP .Button_btn_plain__1j7dG[type="button"]') # 확인 버튼 클릭 print(f"인증 확인버튼 클릭") self.timer.stop() print(f"타이머 스탑") # 인증 완료 후 로그인 성공 여부 확인 try: # 로그인 성공 여부 확인 if not self.popup_page.is_closed(): login_success_check = await self.popup_page.wait_for_selector("ui-view .login-id.text-overflow", timeout=5000) self.login_success_text = await login_success_check.inner_text() print(f"로그인 ID : {self.login_success_text}") if self.login_success_text: print("로그인 성공") await self.popup_page.close() self.setVisible(False) print(f"setVisible - False") except Exception as e: print(f"로그인 성공 여부 확인 중 에러 발생: {e}") traceback.print_exc() self.setVisible(False) print(f"setVisible - False") except Exception as e: print(f"인증 코드 제출 중 에러 발생: {e}") traceback.print_exc() async def show_dialog(self): self.setVisible(True) # 이메일 인증 선택 및 힌트 업데이트 await self.popup_page.click('div#root li:nth-child(1) > label') await self.update_email_hint() # 휴대폰 인증 선택 및 힌트 업데이트 await self.popup_page.click('div#root li:nth-child(2) > label') await self.update_phone_hint() def email_auth_clicked(self): asyncio.ensure_future(self.email_auth()) def phone_auth_clicked(self): asyncio.ensure_future(self.phone_auth())