From 0a5bbef2764c558280237e9108265284fa0dd722 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 04:06:01 +0000 Subject: [PATCH 1/3] Initial plan From d6486a04150d6f9e965f4ab1db85b36c549cb0ef Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 04:10:30 +0000 Subject: [PATCH 2/3] Add admin login-as feature to member admin list Add procMemberAdminLoginAs action that allows super admins to login as a specific non-admin member from the member admin list page. Includes CSRF protection, admin-only access check, and prevention of logging in as another admin user. Co-authored-by: Lastorder-DC <18280396+Lastorder-DC@users.noreply.github.com> --- modules/member/conf/module.xml | 1 + modules/member/lang/en.php | 3 ++ modules/member/lang/ko.php | 3 ++ modules/member/member.admin.controller.php | 40 ++++++++++++++++++++++ modules/member/tpl/member_list.html | 21 +++++++++++- 5 files changed, 67 insertions(+), 1 deletion(-) diff --git a/modules/member/conf/module.xml b/modules/member/conf/module.xml index a6aabadb5b..5e179fc0a5 100644 --- a/modules/member/conf/module.xml +++ b/modules/member/conf/module.xml @@ -118,6 +118,7 @@ + diff --git a/modules/member/lang/en.php b/modules/member/lang/en.php index 24eceb38ce..71dd2ac37a 100644 --- a/modules/member/lang/en.php +++ b/modules/member/lang/en.php @@ -407,3 +407,6 @@ $lang->member_number = 'Member identification number'; $lang->msg_change_after_click = 'Change after clicking link below'; $lang->msg_password_changed = 'Your password has been changed.'; + +$lang->cmd_login_as = 'Login as this member'; +$lang->msg_confirm_login_as = 'Are you sure you want to login as this member? Your current admin session will be terminated.'; diff --git a/modules/member/lang/ko.php b/modules/member/lang/ko.php index dee729b3b3..c3f776d8dd 100644 --- a/modules/member/lang/ko.php +++ b/modules/member/lang/ko.php @@ -411,3 +411,6 @@ $lang->member_number = '회원 번호'; $lang->msg_change_after_click = '아래 링크 클릭 후 변경 가능'; $lang->msg_password_changed = '비밀번호가 변경되었습니다.'; + +$lang->cmd_login_as = '해당 회원으로 로그인'; +$lang->msg_confirm_login_as = '해당 회원으로 로그인하시겠습니까? 현재 관리자 세션이 종료됩니다.'; diff --git a/modules/member/member.admin.controller.php b/modules/member/member.admin.controller.php index 1bc72fe411..1be80b0cba 100644 --- a/modules/member/member.admin.controller.php +++ b/modules/member/member.admin.controller.php @@ -1802,6 +1802,46 @@ function moveJoinFormDown($member_join_form_srl) return new BaseObject(); } + + /** + * Login as a specific member (admin only) + * @return void|BaseObject + */ + function procMemberAdminLoginAs() + { + // Check admin permission and CSRF token + $logged_info = Context::get('logged_info'); + if(!$logged_info || $logged_info->is_admin !== 'Y' || !Rhymix\Framework\Security::checkCSRF()) + { + throw new Rhymix\Framework\Exceptions\InvalidRequest; + } + + $member_srl = Context::get('member_srl'); + if(!$member_srl) + { + throw new Rhymix\Framework\Exceptions\InvalidRequest; + } + + // Get target member info + $member_info = MemberModel::getMemberInfoByMemberSrl($member_srl); + if(!$member_info || !$member_info->member_srl) + { + throw new Rhymix\Framework\Exceptions\InvalidRequest; + } + + // Do not allow login as another admin + if($member_info->is_admin === 'Y') + { + throw new Rhymix\Framework\Exceptions\NotPermitted; + } + + // Perform login as the target member + Rhymix\Framework\Session::login($member_info->member_srl); + $oMemberController = getController('member'); + $oMemberController->setSessionInfo(); + + $this->setRedirectUrl(getNotEncodedUrl('')); + } } /* End of file member.admin.controller.php */ /* Location: ./modules/member/member.admin.controller.php */ diff --git a/modules/member/tpl/member_list.html b/modules/member/tpl/member_list.html index 09ce416ade..e270e26672 100644 --- a/modules/member/tpl/member_list.html +++ b/modules/member/tpl/member_list.html @@ -97,7 +97,12 @@

{$lang->user_list}

{zdate($member_info['last_login'], 'Y-m-d')} {$member_info['group_list']}  - {$lang->inquiry}/{$lang->cmd_modify} + + {$lang->inquiry}/{$lang->cmd_modify} + + + + {@$used_values = ''} {@$used_values .= "\t".$member_info[$name]} @@ -245,5 +250,19 @@

{$lang->about_send_message}

} } }); + // Login as member + $('a._login_as').click(function(e){ + e.preventDefault(); + if(!confirm('{$lang->msg_confirm_login_as}')) return; + var member_srl = $(this).data('member-srl'); + var $form = $('#loginAsForm'); + $form.find('input[name=member_srl]').val(member_srl); + $form.submit(); + }); }); + From 4b32a2fc37e259154eb862dfe9767552ab9d5d34 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 04:11:36 +0000 Subject: [PATCH 3/3] Allow login-as for admin members, protect only super admin (member_srl=4) Changed the restriction so admins can login as other admin accounts, but member_srl 4 (super admin) is protected from impersonation. Co-authored-by: Lastorder-DC <18280396+Lastorder-DC@users.noreply.github.com> --- modules/member/member.admin.controller.php | 5 +++-- modules/member/tpl/member_list.html | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/member/member.admin.controller.php b/modules/member/member.admin.controller.php index 1be80b0cba..54fe90c244 100644 --- a/modules/member/member.admin.controller.php +++ b/modules/member/member.admin.controller.php @@ -1829,13 +1829,14 @@ function procMemberAdminLoginAs() throw new Rhymix\Framework\Exceptions\InvalidRequest; } - // Do not allow login as another admin - if($member_info->is_admin === 'Y') + // Do not allow login as the super admin (member_srl = 4) + if(intval($member_info->member_srl) === 4) { throw new Rhymix\Framework\Exceptions\NotPermitted; } // Perform login as the target member + // Session::login() sets the basic session variables, and setSessionInfo() populates Context with member details Rhymix\Framework\Session::login($member_info->member_srl); $oMemberController = getController('member'); $oMemberController->setSessionInfo(); diff --git a/modules/member/tpl/member_list.html b/modules/member/tpl/member_list.html index e270e26672..bb3f568d39 100644 --- a/modules/member/tpl/member_list.html +++ b/modules/member/tpl/member_list.html @@ -99,7 +99,7 @@

{$lang->user_list}

{$member_info['group_list']}  {$lang->inquiry}/{$lang->cmd_modify} - +