Compare commits

...
47 Commits
Author SHA1 Message Date
thisgun dfca17a599 버전 5.6.30 수정 2026-06-16 03:33:14 +00:00
thisgun 5ed691136d 나이스페이 가상계좌 취소금액 보정 2026-06-16 03:26:42 +00:00
thisgun cdda832081 Fix register form member defaults 2026-06-16 03:26:42 +00:00
thisgun 5374fb5f74 NHN KCP 본인확인 v2 설정 안내 보완 2026-06-16 03:17:44 +00:00
thisgun 16a8dca6f7 버전 5.6.29 수정 2026-06-09 02:34:30 +00:00
thisgun b00fc18275 Merge branch 'master' into tmp_install 2026-06-09 02:27:41 +00:00
thisgun 0c6ff731f6 관리권한 부여 목록에서 최고관리자 전용 메뉴 제외 2026-06-09 02:26:01 +00:00
thisgun 77835010df 메일 테스트 발송 안내 개선 2026-06-09 02:26:01 +00:00
thisgunandClaude Opus 4.8 33416852fc 나이스페이 가상계좌 채번 시 od_app_no 누락 수정
가상계좌(4100) 채번 시 od_app_no가 빈 AuthCode로 남아
입금통보 매칭(od_app_no = VbankNum)이 실패하던 문제 수정

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 01:34:33 +00:00
thisgun 3a4612420c Improve installer validation and error handling 2026-06-08 02:09:17 +00:00
thisgunandClaude Opus 4.8 6a55f1457d 현재접속자 처리 시 카운트 접근 null 보정 (PHP 8 호환)
html_process 의 접속자 처리에서 count 조회 결과 접근을 empty() 로
보정. 쿼리 실패 등 비정상 상황에서 빈 배열/undefined 키 접근으로
PHP 8.0+ 경고가 나는 경우를 예방. 동작 변화 없음.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 07:32:50 +00:00
thisgunandClaude Opus 4.8 76d83c2bae 게시판 정렬 필드 화이트리스트 검증 추가
게시판 설정의 bo_sort_field 가 허용 목록 검증 없이 저장·사용되어
목록 조회 ORDER BY 절에 임의 표현식이 들어갈 수 있던 문제 수정.
정렬값은 따옴표로 감싸지 않아 escape 로 막히지 않으므로,
게시판 관리 권한 계정이 저장한 값이 비로그인 목록 조회에서
실행될 수 있었음.

get_board_sort_fields() 의 허용 목록(관리자 드롭다운과 동일)으로
저장(adm/board_form_update.php)과 사용(bbs/list.php) 양쪽을 검증.
허용 목록 외 값은 기본 정렬로 무력화하여 이미 저장된 값도 차단.
function_exists 가드로 부분 패치 환경 대비.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 07:20:58 +00:00
thisgunandClaude Opus 4.8 afd8b35423 SMS 회원정보 업데이트 토큰 방식 불일치 수정
member_update.php 가 get_token()(HMAC) 으로 발급한 토큰을
member_update_run.php 가 check_admin_token()(세션) 으로 검증해
항상 불일치 → 오류 HTML 반환으로 AJAX JSON 파싱이 실패하던 문제 수정.

sms_admin 의 다른 _run 들과 동일하게 검증측(check_admin_token)은
유지하고, 실행 시 ajax.token.php 로 세션 토큰을 발급받아 본 요청에
사용하도록 변경. check_admin_token 의 1회용 소거 특성상 재실행에도
견고함.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 08:22:03 +00:00
thisgunandClaude Opus 4.8 e7c89675b6 회원관리/비디오 필터 null 인자 보정 (PHP 8.1 호환)
내장함수에 null 이 전달되어 PHP 8.1+ 에서 경고가 발생하던 것을
isset 삼항 / 문자열 캐스팅으로 보정.

- adm/member_form.php: number_format(mb_point), substr(mb_id) 2곳,
  substr(mp_register_day) — null/미정의 시 0 또는 빈 문자열 처리
- plugin/htmlpurifier/extend.video.php: strstr 인자 (string) 캐스팅

표시·동작 변화 없음. PHP 5.2~8.3 호환 유지(?? 미사용).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 07:55:39 +00:00
thisgun 10c6c18857 Fix JavaScript alert string escaping 2026-06-01 10:26:44 +00:00
thisgun 3e002199d5 버전 5.6.28 수정 2026-06-01 03:40:35 +00:00
thisgunandClaude Opus 4.8 7dde02d396 SMS 모듈 Add/Add2 매개변수 기본값 보정 (PHP 8 호환)
기본값 있는 $strDate 뒤에 기본값 없는 $nCount 가 선언되어 PHP 8.0+
에서 경고가 발생하던 것을 $nCount=0 기본값 부여로 해소.

- plugin/sms5/sms5.lib.php: Add(), Add2()
- lib/icode.lms.lib.php: Add() (LMS 부모 클래스 동일 패턴)

LMS 분기 호출부는 $strDate, $nCount 를 항상 함께 전달하므로
동작 변화 없음. PHP 5.2~8.3 호환 유지.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 01:02:26 +00:00
thisgunandClaude Opus 4.8 31871ee3e6 [security] 주문자 휴대폰 출력 인코딩 및 리다이렉트 URL 호스트 검증
- adm/shop_admin/orderform.php: 주문상세 hidden 의 od_hp 출력에
  get_text() 적용 (인접한 od_name 과 동일 처리, 누락분 보완)
- bbs/member_cert_refresh_update.php: 본인확인 갱신 후 이동 URL 에
  check_url_host() 적용
- plugin/social/includes/functions.php: 소셜 로그인/연동 후 이동
  URL 2곳에 동일하게 check_url_host() 적용

login_check.php 등 기존 코드와 동일한 호스트 검증 패턴으로,
같은 도메인/상대경로 복귀는 그대로 동작하고 타 도메인 이동만 차단.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 09:16:29 +00:00
thisgun ff9a7534ed Restore data htaccess on admin and write upload 2026-05-29 07:22:08 +00:00
thisgunandClaude Opus 4.8 9869be5970 [security] 토스 결제창 customerName 출력 시 get_text 인코딩 적용
토스페이먼츠 결제 요청 폼의 customerName hidden 필드에 주문자명
($od_name)이 인코딩 없이 출력되던 것을 get_text() 적용으로 정리.
직전 주문 필드 인코딩 처리와 동일한 맥락의 마무리.

hidden value 의 엔티티는 결제 SDK 가 값을 읽을 때 브라우저가
디코딩하므로 토스로 전달되는 구매자명에는 영향 없음.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 06:30:29 +00:00
thisgunandClaude Opus 4.8 1fa4467cd1 [security] 주문 관련 필드 출력 시 get_text 인코딩 적용
영카트 주문자명/받는분/입금자명(od_name, od_b_name, od_deposit_name)
이 일부 출력 지점에서 인코딩 없이 노출되어, 저장된 값이 HTML/속성
컨텍스트에서 그대로 렌더링되던 문제 수정. 다음 출력에 get_text() 적용:

- adm/shop_admin/orderform.php, sale1today.php (관리자 주문 화면)
- shop/orderinquiryview.php (PC/모바일/테마 주문조회)
- shop/{inicis,kcp,lg,nicepay,toss}/taxsave_form.php (현금영수증 발행 폼)
- shop/mail/orderupdate{1,2,3}.mail.php, ordermail.mail.php (주문 메일)

비회원 주문 시 입력값이 관리자 화면에서 실행될 수 있는 경로를 차단.
폼 value 의 엔티티는 브라우저 제출 시 디코딩되므로 PG 전송값 및
정상 표시에는 영향 없음.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 06:25:12 +00:00
thisgun 3e75ccea65 NHN KCP 휴대폰 본인확인(api_v2) 버전 추가 2026-05-29 06:14:21 +00:00
thisgun be9f50f96b Fix RSS warnings for invalid board requests 2026-05-29 01:33:45 +00:00
thisgun 7c217cb41b Restore alert newline handling 2026-05-28 06:23:04 +00:00
thisgun 5fc1c3bc27 버전 5.6.27 수정 2026-05-27 03:35:09 +00:00
thisgunandClaude Opus 4.7 d707c5abac data/ 디렉터리 git 추적 제외 (.htaccess 인덱스 제거)
.gitignore 에는 이미 data/ 가 등록되어 있으나 data/.htaccess
한 파일이 이전부터 트래킹되고 있어 배포본에 함께 포함되던 문제 정리.
디스크 파일은 그대로 두고 인덱스에서만 제거.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 02:28:39 +00:00
thisgunandClaude Opus 4.7 eeea46cb69 NHN KCP 가상계좌 발급 응답 코드 V000 허용
KCP 가이드 개정으로 가상계좌 발급 정상 응답이 0000 에서 V000 으로
변경되어, 기존 코드가 발급 성공을 실패로 인식하던 문제를 수정.
결제 hub 의 res_cd 비교 두 곳에서 V000 을 0000 과 동등하게 처리.

가상계좌 입금 완료 처리는 Webhook 입금통보가 담당하므로 본 변경과
무관. 취소/현금영수증/본인인증 경로는 V000 응답 대상이 아니므로
0000 단독 비교 유지.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 11:55:56 +00:00
thisgunandClaude Opus 4.7 669cce7011 주소 jibeon 값 화이트리스트에 'J' 추가
카카오 우편번호 서비스의 oncomplete 콜백이 userSelectedType
으로 'R'(도로명) 또는 'J'(지번)을 반환하는데, 서버 측 정규식이
'N|R' 만 허용해 지번 선택 시 빈 문자열로 저장되던 문제를 수정.
N 은 print_address() 의 도로명 표기 분기를 위한 레거시 값으로
호환을 위해 유지.

적용 위치: 회원가입(bbs/register_form_update.php), PC/모바일
주문(shop/, mobile/shop/ orderformupdate.php), 관리자 미완료
주문(adm/shop_admin/inorderformupdate.php) 의 7곳.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 11:46:36 +00:00
thisgunandClaude Opus 4.7 ee8b57eb13 미완료 주문 목록 PG 표시에 토스페이먼츠/NICEPAY 케이스 추가
dt_pg 값이 'toss' 또는 'nicepay' 인 건이 default 분기로 빠져
일괄 'KCP' 로 잘못 표시되던 문제 수정.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 11:40:18 +00:00
thisgun c927925a05 Fix PHP 5.2 compatibility issues 2026-05-26 09:34:18 +00:00
thisgun d914a7843d Fix PHP legacy array syntax 2026-05-26 08:10:57 +00:00
thisgun c04591e24a NHN_KCP 가상계좌 테스트 url 변경 2026-05-26 07:34:49 +00:00
thisgunandClaude Opus 4.7 a6fbbe6ad2 [security] 엑셀/CSV 다운로드 출력값 안전 처리
lib/common.lib.php 에 csv_safe_cell() 헬퍼 추가 (function_exists
가드 포함). 셀 값이 = + - @ TAB CR 로 시작하면 작은따옴표를 prefix
하여 스프레드시트가 수식으로 해석하지 못하도록 변환.

다음 출력 지점에서 사용자 입력 컬럼에 적용:
- adm/shop_admin/orderprintresult.php (CSV + XLS 두 분기)
- adm/shop_admin/orderdeliveryexcel.php
- adm/member_list_exel_export.php
- adm/sms_admin/num_book_file_download.php

호출부는 function_exists('csv_safe_cell') ? ... : 원본 폴백 형태로
감싸서 lib 미업데이트 환경에서도 fatal error 없이 동작하도록 함.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 07:30:21 +00:00
thisgunandClaude Opus 4.7 4c00c60006 [security]KVE-2026-0882 race condition 잔액 부족 시 결제 취소 처리로 변경
이전 커밋(e53689ac3)의 미수금 처리 방식은 사용자에게 결제 금액과
다른 청구가 발생해 혼란/분쟁을 유발할 수 있어, 동시 주문 race 로
포인트 잔액이 부족하면 결제 자체를 취소하는 방식으로 변경.

- PG 결제가 진행된 경우 (\$tno 존재): cancel_pg.inc.php 로 환불 요청
- 장바구니 복구: 기존 line 839 동일 패턴 (od_id = tmp_cart_id, ct_status = '쇼핑')
- 주문 삭제: g5_shop_order_table 에서 od_id 제거
- 사용자에게 die 로 명확한 오류 메시지 표시

lock timeout 케이스도 동일하게 결제 취소 처리 (보수적).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 07:10:53 +00:00
thisgunandClaude Opus 4.7 56b1958d37 [security]KVE-2026-0882 주문 포인트 차감 Race Condition (Double Spend) 수정
shop/orderformupdate.php / mobile/shop/orderformupdate.php 의 포인트
검증과 차감 사이에 TOCTOU race 가 존재하여, 동일 회원이 여러 세션으로
동시에 주문 제출 시 같은 포인트 잔액을 반복 검증 통과 → 다중 차감으로
mb_point 가 음수가 되는 double spend 가 가능했음.

insert_point() 의 기존 named lock 은 (mb_id, rel_table, rel_id, rel_action)
조합 키 기반이라 서로 다른 od_id 주문 간에는 lock 이 다르고, 주문 차감
호출에 rel_* 가 전달되지 않아 lock 미적용 상태였음.

조치: KVE-2026-0687 (쇼핑몰 쿠폰) 와 동일한 회원 단위 MySQL GET_LOCK
패턴을 적용. lock 획득 후 g5_point SUM 으로 잔액을 재조회하여
- 충분하면 정상 차감
- race 로 부족하면 사용 가능한 만큼만 차감 + 부족분은 od_receipt_point
  보정 + od_misu(미수금) 으로 반영하여 매장 손실 방지.

MyISAM 정책상 트랜잭션 금지이므로 named lock 으로 직렬화하는 방식이
가장 적합. 데스크톱·모바일 동일 패턴 적용.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 06:52:25 +00:00
thisgunandClaude Opus 4.7 6b2f9e094c [security] ORDER BY sst/sod 화이트리스트 누락 Blind SQL Injection 수정
KVE-2026-0876 동일 패턴 추가 발견 5건 일괄 수정.

- shop/itemuselist.php / mobile/shop/itemuselist.php (상품후기 목록)
- shop/itemqalist.php / mobile/shop/itemqalist.php (상품문의 목록)
  → 비회원 접근 가능한 공개 페이지에서 sst/sod 가 ORDER BY 절에
    검증 없이 삽입되어 CASE WHEN/SLEEP 기반 blind SQLi 가능했음.
    sst 는 컬럼 화이트리스트, sod 는 asc/desc 정규식으로 검증.

- bbs/list.php (게시판 목록)
  → sst 는 wr_datetime/wr_hit/wr_good/wr_nogood 화이트리스트 적용
    되어 있으나 sod 가 검증 누락되어 ORDER BY 절에 함수 표현식
    삽입이 가능했음. sod 에 asc/desc 정규식 검증 추가.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 06:32:28 +00:00
thisgun a781b4aef3 [KVE-2026-0876] 모바일 상품 리스트 sort 파라미터 Blind SQL Injection 수정 2026-05-26 06:27:53 +00:00
thisgun 8be4476f56 [KVE-2026-0869] 인스톨러 관리자 입력값 SQL Injection 수정 2026-05-26 05:22:52 +00:00
thisgunandClaude Opus 4.7 59d0b3c19c [security]KVE-2026-0859 KCP CLI Windows 환경 명령 인젝션(RCE) 수정
shop/kcp/pp_cli_hub_lib.php, shop/kcp/pp_ax_hub_lib.php 의
mf_do_tx() Windows 분기가 사용자 입력이 포함된 KCP CLI 인자를
큰따옴표로 감싼 단일 문자열로 만들어 mf_exec() 첫 인자로 전달했고,
mf_exec() 는 첫 인자를 escape 없이 exec() 에 넘겨 Windows cmd.exe
메타문자(`"`, `&` 등)로 인증 없는 OS 명령 실행이 가능했음.

Linux 분기와 동일하게 실행 파일 경로와 콤마 구분 인자 문자열을
분리하여 mf_exec($bin_exe, $args) 형태로 호출하도록 변경.
mf_exec() 의 foreach 가 두 번째 이후 인자에 escapeshellarg() 를
자동 적용하여 cmd.exe 메타문자가 안전하게 wrapping 됨.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 03:35:51 +00:00
thisgunandClaude Opus 4.7 f4f8c57a74 [security] 관리자 영역 권한 검증 누락 및 CSRF 토큰 누락 수정
- adm/qa_config_update.php / adm/contentformupdate.php :
  qa_include_head/tail, co_include_head/tail 가 super 가드 없이 변경 가능해
  하위 관리자가 임의 PHP 경로를 include 시킬 수 있던 LFI 위험을
  board_form_update.php 와 동일한 패턴(super 외에는 기존 값 유지)으로 차단.

- adm/member_form_update.php / adm/member_list_update.php :
  신규 회원 생성·일괄 수정 시 부여하려는 mb_level 상한 검증이 없어
  하위 관리자가 자기보다 높은 등급을 부여할 수 있던 권한 상승을 차단.

- adm/shop_admin/categorylistupdate.php /
  adm/shop_admin/itemformupdate.php :
  is_include_path_check 호출에서 두 번째 인자(is_input=1) 누락으로
  rar/php/zip wrapper 등 경로 wrapper 차단이 동작하지 않던 부분을
  is_include_path_check($file, 1) 로 강화.

- adm/shop_admin/orderdeliveryupdate.php /
  adm/shop_admin/orderpartcancelupdate.php /
  adm/sendmail_test.php :
  상태 변경 동작에 check_admin_token() 누락으로 발생하던 CSRF 위험을
  토큰 검증 추가로 차단. sendmail_test 폼에는 hidden token 필드 추가.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 03:35:29 +00:00
thisgunandClaude Opus 4.7 d5619707bc [security] 인스톨러 g5_shop_prefix PHP 코드 인젝션(RCE) 수정
install/install_db.php 의 g5_shop_prefix 가 dbconfig.php 의
define('G5_SHOP_TABLE_PREFIX','...') 문자열에 작은따옴표 escape 없이
삽입되어, 설치 전 노출된 인스톨러를 통해 임의 PHP 코드 주입 후 RCE
가능하던 문제를 수정. table_prefix·admin_id 와 동일하게 [^0-9a-z_]+
정규식 검증을 추가하여 영문자·숫자·언더스코어만 허용하도록 함.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 03:34:55 +00:00
thisgunandClaude Opus 4.7 9e7465319b [security]KVE-2026-0822 댓글 수정 textarea wr_content 미이스케이프 Stored XSS 수정
view_comment.skin.php 8종(skin/, mobile/skin/, theme/basic/ 하위 basic·
gallery)에서 댓글 수정($w == 'cu') 시 \$c_wr_content 가 textarea 내부에
이스케이프 없이 출력되어 </textarea> 페이로드로 탈출 가능하던 문제를
get_text() 적용으로 일괄 수정. 게시글 본문 수정(bbs/write.php) 과
동일한 escape 패턴을 댓글 수정에도 적용함.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 03:32:43 +00:00
thisgunandClaude Opus 4.7 f1f2150c67 [security]KVE-2026-0795 게시물 이동/복사 시 대상 게시판 권한 검증 누락 수정
bbs/move_update.php 가 원본 게시판 기준 $is_admin 만 검사하고 사용자
입력 chk_bo_table[] 의 대상 게시판에 대해서는 존재 여부만 확인하던
문제를 수정. 게시판 관리자(board)·그룹 관리자(group) 권한일 경우
대상 게시판의 bo_admin 또는 그룹의 gr_admin 이 본인인지 재검증하고,
일치하지 않으면 해당 대상 게시판 처리를 건너뛰도록 함. super 관리자는
기존 동작 유지.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 03:32:18 +00:00
thisgunandClaude Opus 4.7 3de722d3df [security]KVE-2026-0787 alert() JavaScript 이스케이프 누락 Stored XSS 수정
bbs/alert.php, bbs/alert_close.php 가 alert("$msg") 형태로 메시지를
JS 문자열 컨텍스트에 직접 삽입하던 부분을 수정. lib/common.lib.php 에
PHP 5.2 호환 폴백을 갖춘 get_js_safe_string() 헬퍼를 추가하고,
호출부에는 function_exists 가드를 걸어 부분 패치 환경에서도 안전하게
폴백되도록 함.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 03:31:24 +00:00
thisgunandClaude Opus 4.7 7119b4f612 [security]KVE-2026-0711 PG 리턴 처리 POST 키 이름 Reflected XSS 수정
XenoPostToForm::makeInputArray() 에서 POST 값·배열 인덱스는 이스케이프
되지만 최상위 POST 키 이름이 name 속성에 그대로 삽입되던 문제를 수정.
재귀 진입 시점에 htmlspecialchars() 로 키를 이스케이프하여 모든 깊이에서
안전하도록 함.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 03:30:47 +00:00
thisgunandClaude Opus 4.7 efaefbbd0e [security]KVE-2026-0687 쇼핑몰 쿠폰 다운로드 TOCTOU Race Condition 수정
MySQL GET_LOCK 으로 동일 회원·동일 쿠폰 다운로드 요청을 직렬화하여,
동시 요청 시 is_coupon_downloaded() 체크를 중복 통과해 쿠폰이 중복
발급되는 문제를 방지함.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 03:30:19 +00:00
thisgun b12bf551ec [security]XSS 취약점 및 token 추가 2026-05-26 03:29:51 +00:00
143 changed files with 2564 additions and 794 deletions
+4
View File
@@ -3,6 +3,10 @@ define('G5_IS_ADMIN', true);
require_once '../common.php';
require_once G5_ADMIN_PATH . '/admin.lib.php';
if (function_exists('g5_check_data_htaccess')) {
g5_check_data_htaccess();
}
if (isset($token)) {
$token = @htmlspecialchars(strip_tags($token), ENT_QUOTES);
}
+105 -1
View File
@@ -610,6 +610,110 @@ function admin_menu_find_by($call, $search_key)
return '';
}
function admin_menu_local_path($url)
{
$url = (string) $url;
if (!$url) {
return '';
}
$url = preg_replace('/[?#].*$/', '', $url);
$maps = array(
G5_ADMIN_URL => G5_ADMIN_PATH,
);
if (defined('G5_SMS5_ADMIN_URL') && defined('G5_SMS5_ADMIN_PATH')) {
$maps[G5_SMS5_ADMIN_URL] = G5_SMS5_ADMIN_PATH;
}
foreach ($maps as $base_url => $base_path) {
if (strpos($url, $base_url) !== 0) {
continue;
}
$path = $base_path.substr($url, strlen($base_url));
if (substr($path, -1) === '/') {
$path .= 'index.php';
}
return $path;
}
return '';
}
function admin_menu_is_super_only($menu_item)
{
static $cache = array();
$sub_menu = isset($menu_item[0]) ? (string) $menu_item[0] : '';
if (!$sub_menu) {
return false;
}
if (isset($cache[$sub_menu])) {
return $cache[$sub_menu];
}
// 향후 메뉴 정의에서 명시적으로 최고관리자 전용 표시가 필요할 때 사용한다.
if (isset($menu_item[4]) && $menu_item[4] === 'super') {
return $cache[$sub_menu] = true;
}
$path = admin_menu_local_path(isset($menu_item[2]) ? $menu_item[2] : '');
if (!$path || !is_readable($path)) {
return $cache[$sub_menu] = false;
}
$content = file_get_contents($path, false, null, 0, 12000);
if ($content === false) {
return $cache[$sub_menu] = false;
}
$pattern = '/if\s*\([^\)]*\$is_admin\s*(?:!==|!=)\s*[\'"]super[\'"][^\)]*\)\s*\{?[\s\S]{0,250}(?:alert|alert_close|die)\s*\([^\;]*(?:최고관리자만|최고관리자로)/u';
return $cache[$sub_menu] = (bool) preg_match($pattern, $content);
}
function admin_get_assignable_auth_menu()
{
global $menu;
$assignable_auth_menu = array();
if (!isset($menu) || !is_array($menu)) {
return $assignable_auth_menu;
}
foreach ($menu as $menu_group) {
if (!is_array($menu_group)) {
continue;
}
for ($i=1; $i<count($menu_group); $i++) {
if (!isset($menu_group[$i]) || !is_array($menu_group[$i])) {
continue;
}
$sub_menu = isset($menu_group[$i][0]) ? $menu_group[$i][0] : '';
if (!$sub_menu || $sub_menu === '-' || substr($sub_menu, -3) === '000') {
continue;
}
if (admin_menu_is_super_only($menu_group[$i])) {
continue;
}
$assignable_auth_menu[$sub_menu] = isset($menu_group[$i][1]) ? $menu_group[$i][1] : '';
}
}
return $assignable_auth_menu;
}
// 접근 권한 검사
if (!$member['mb_id']) {
alert('로그인 하십시오.', G5_BBS_URL . '/login.php?url=' . urlencode(correct_goto_url(G5_ADMIN_URL)));
@@ -698,4 +802,4 @@ if (run_replace('safe_admin_add_script_boolean', false) === false) {
$config['cf_analytics'] = '';
$config['cf_add_script'] = '';
$config['cf_add_meta'] = '';
}
}
+6 -4
View File
@@ -54,6 +54,8 @@ $listall = '<a href="' . $_SERVER['SCRIPT_NAME'] . '" class="ov_listall btn_ov02
$g5['title'] = "관리권한설정";
require_once './admin.head.php';
$assignable_auth_menu = admin_get_assignable_auth_menu();
$colspan = 5;
?>
@@ -105,8 +107,8 @@ $colspan = 5;
$is_continue = true;
}
// 메뉴번호가 바뀌는 경우에 현재 없는 저장된 메뉴는 삭제함
if (!isset($auth_menu[$row['au_menu']])) {
// 메뉴번호가 바뀌거나 권한 부여 대상이 아닌 메뉴는 삭제함
if (!isset($assignable_auth_menu[$row['au_menu']])) {
sql_query(" delete from {$g5['auth_table']} where au_menu = '{$row['au_menu']}' ");
$is_continue = true;
}
@@ -130,7 +132,7 @@ $colspan = 5;
<td class="td_auth_mbnick"><?php echo $mb_nick ?></td>
<td class="td_menu">
<?php echo $row['au_menu'] ?>
<?php echo $auth_menu[$row['au_menu']] ?>
<?php echo $assignable_auth_menu[$row['au_menu']] ?>
</td>
<td class="td_auth"><?php echo $row['au_auth'] ?></td>
</tr>
@@ -205,7 +207,7 @@ echo $pagelist;
<select id="au_menu" name="au_menu" required class="required">
<option value=''>선택하세요</option>
<?php
foreach ($auth_menu as $key => $value) {
foreach ($assignable_auth_menu as $key => $value) {
if (!(substr($key, -3) == '000' || $key == '-' || !$key)) {
echo '<option value="' . $key . '">' . $key . ' ' . $value . '</option>';
}
+5
View File
@@ -19,6 +19,11 @@ if (!(isset($mb['mb_id']) && $mb['mb_id'])) {
check_admin_token();
$assignable_auth_menu = admin_get_assignable_auth_menu();
if (!$au_menu || !isset($assignable_auth_menu[$au_menu])) {
alert('해당 메뉴는 관리권한을 부여할 수 없습니다.');
}
require_once G5_CAPTCHA_PATH . '/captcha.lib.php';
if (!chk_captcha()) {
+11 -1
View File
@@ -176,7 +176,17 @@ $bo_write_min = isset($_POST['bo_write_min']) ? (int) $_POST['bo_write_min'] : 0
$bo_write_max = isset($_POST['bo_write_max']) ? (int) $_POST['bo_write_max'] : 0;
$bo_comment_min = isset($_POST['bo_comment_min']) ? (int) $_POST['bo_comment_min'] : 0;
$bo_comment_max = isset($_POST['bo_comment_max']) ? (int) $_POST['bo_comment_max'] : 0;
$bo_sort_field = isset($_POST['bo_sort_field']) ? addslashes(clean_xss_tags(stripslashes($_POST['bo_sort_field']), 1, 1)) : '';
$bo_sort_field = isset($_POST['bo_sort_field']) ? trim(stripslashes($_POST['bo_sort_field'])) : '';
$bo_allowed_sort_field = array('');
if (function_exists('get_board_sort_fields')) {
foreach (get_board_sort_fields(isset($board) ? $board : array()) as $bo_sort_v) {
$bo_allowed_sort_field[] = $bo_sort_v[0];
}
}
if (!in_array($bo_sort_field, $bo_allowed_sort_field, true)) {
$bo_sort_field = '';
}
$bo_sort_field = addslashes($bo_sort_field);
if (strpbrk($bo_skin.$bo_mobile_skin, "?%*:|\"<>") !== false) {
alert('스킨 디렉토리명 오류!');
+1 -1
View File
@@ -21,7 +21,7 @@ if (!is_file(G5_DATA_PATH . '/cache/browscap_cache.php')) {
}
require_once G5_PLUGIN_PATH . '/browscap/Browscap.php';
$browscap = new phpbrowscap\Browscap(G5_DATA_PATH . '/cache');
$browscap = new Browscap(G5_DATA_PATH . '/cache');
$browscap->doAutoUpdate = false;
$browscap->cacheFilename = 'browscap_cache.php';
+1 -1
View File
@@ -17,7 +17,7 @@ if ($is_admin != 'super') {
require_once G5_PLUGIN_PATH . '/browscap/Browscap.php';
$browscap = new phpbrowscap\Browscap(G5_DATA_PATH . '/cache');
$browscap = new Browscap(G5_DATA_PATH . '/cache');
$browscap->updateMethod = 'cURL';
$browscap->cacheFilename = 'browscap_cache.php';
$browscap->updateCache();
+29 -6
View File
@@ -415,10 +415,10 @@ if (!isset($config['cf_cert_use_seed'])) {
sql_query($sql, false);
}
if (!isset($config['cf_cert_kcp_enckey'])) {
$sql = "ALTER TABLE `{$g5['config_table']}`
$sql = "ALTER TABLE `{$g5['config_table']}`
ADD COLUMN `cf_cert_kcp_enckey` VARCHAR(100) NOT NULL DEFAULT '' AFTER `cf_cert_kcp_cd`; ";
sql_query($sql, false);
$config['cf_cert_kcp_enckey'] = '';
}
@@ -1068,7 +1068,24 @@ if ($config['cf_sms_use'] && $config['cf_icode_id'] && $config['cf_icode_pw']) {
<?php echo option_selected("", $config['cf_cert_hp'], "사용안함"); ?>
<?php echo option_selected("kcb", $config['cf_cert_hp'], "코리아크레딧뷰로(KCB) 휴대폰 본인확인"); ?>
<?php echo option_selected("kcp", $config['cf_cert_hp'], "NHN KCP 휴대폰 본인확인"); ?>
<?php echo option_selected("kcp_v2", $config['cf_cert_hp'], "NHN KCP 휴대폰 본인확인(api_v2)"); ?>
</select>
<div id="cf_cert_hp_kcp_v2_notice" style="display:<?php echo ($config['cf_cert_hp'] == 'kcp_v2') ? 'block' : 'none'; ?>; margin-top:8px; padding:10px 12px; background:#fff8e1; border:1px solid #ffd54f; border-radius:4px; color:#5d4037; line-height:1.5;">
<strong>NHN KCP 휴대폰 본인확인(api_v2)</strong> 사용 시,<br>
NHN KCP 상점관리자 &gt; 부가서비스 &gt; 휴대폰본인확인 &gt; 연동방식 설정 에서 <strong>신규 연동방식(V2) 사용여부를 &lsquo;사용&rsquo;</strong> 으로 변경해야 정상 동작합니다.<br>
PHP 7.0 이상 환경에서만 동작하며, PHP 7.0 미만에서는 사용할 수 없습니다.
</div>
<script>
jQuery(function($){
function toggle_kcp_v2_notice() {
var is_kcp_v2 = $('#cf_cert_hp').val() === 'kcp_v2';
$('#cf_cert_hp_kcp_v2_notice').toggle(is_kcp_v2);
}
$('#cf_cert_hp').on('change', toggle_kcp_v2_notice);
toggle_kcp_v2_notice();
});
</script>
</td>
</tr>
<tr>
@@ -1104,16 +1121,22 @@ if ($config['cf_sms_use'] && $config['cf_icode_id'] && $config['cf_icode_pw']) {
<tr>
<th scope="row" class="cf_cert_service"><label for="cf_cert_kcp_cd">NHN KCP 사이트코드</label></th>
<td class="cf_cert_service">
<?php
$cf_cert_kcp_cd = get_sanitize_input($config['cf_cert_kcp_cd']);
if (preg_match('/^SM([A-Z0-9]{3})$/i', $cf_cert_kcp_cd, $matches)) {
$cf_cert_kcp_cd = $matches[1];
}
?>
<?php echo help('SM으로 시작하는 5자리 사이트 코드중 뒤의 3자리만 입력해 주십시오.<br>서비스에 가입되어 있지 않다면, 본인확인 서비스 신청페이지에서 서비스 신청 후 사이트코드를 발급 받으실 수 있습니다.') ?>
<span class="sitecode">SM</span>
<input type="text" name="cf_cert_kcp_cd" value="<?php echo get_sanitize_input($config['cf_cert_kcp_cd']); ?>" id="cf_cert_kcp_cd" class="frm_input" size="3"> <a href="http://sir.kr/main/service/p_cert.php" target="_blank" class="btn_frmline">NHN KCP 휴대폰 본인확인 서비스 신청페이지</a>
<span class="sitecode" id="cf_cert_kcp_cd_prefix">SM</span>
<input type="text" name="cf_cert_kcp_cd" value="<?php echo $cf_cert_kcp_cd; ?>" id="cf_cert_kcp_cd" class="frm_input" size="3" maxlength="3"> <a href="http://sir.kr/main/service/p_cert.php" target="_blank" class="btn_frmline">NHN KCP 휴대폰 본인확인 서비스 신청페이지</a>
</td>
</tr>
<tr>
<th scope="row" class="cf_cert_service"><label for="cf_cert_kcp_enckey">NHN KCP 가맹점 인증키</label></th>
<td class="cf_cert_service">
<?php echo help('(선택사항, 추후 NHN_KCP 상점관리자에서 인증키 발급 메뉴 오픈일정 이후부터 적용되는 내용입니다.)<br>NHN_KCP 상점관리자 > 기술관리센터 > 인증센터 > 가맹점 인증키관리 에서 인증키 발급 후에 인증키 정보를 입력') ?>
<input type="text" name="cf_cert_kcp_enckey" value="<?php echo get_sanitize_input($config['cf_cert_kcp_enckey']); ?>" id="cf_cert_kcp_enckey" class="frm_input" maxlength="100" size="40"> <a href="https://partner.kcp.co.kr" target="_blank" class="btn_frmline">NHN KCP 상점관리자</a>
<?php echo help('NHN KCP 상점관리자 > 기술관리센터 > 인증센터 > 가맹점 인증키관리 에서 인증키를 발급받아 입력해 주십시오.<br>NHN KCP 휴대폰 본인확인(api_v2)도 이 인증키 값을 사용합니다.') ?>
<input type="text" name="cf_cert_kcp_enckey" value="<?php echo get_sanitize_input($config['cf_cert_kcp_enckey']); ?>" id="cf_cert_kcp_enckey" class="frm_input" maxlength="100" size="70"> <a href="https://partner.kcp.co.kr" target="_blank" class="btn_frmline">NHN KCP 상점관리자</a>
</td>
</tr>
<tr>
+11
View File
@@ -29,6 +29,17 @@ $co_id = isset($_REQUEST['co_id']) ? preg_replace('/[^a-z0-9_]/i', '', $_REQUEST
$co_subject = isset($_POST['co_subject']) ? strip_tags(clean_xss_attributes($_POST['co_subject'])) : '';
$co_include_head = isset($_POST['co_include_head']) ? preg_replace(array("#[\\\]+$#", "#(<\?php|<\?)#i"), "", substr($_POST['co_include_head'], 0, 255)) : '';
$co_include_tail = isset($_POST['co_include_tail']) ? preg_replace(array("#[\\\]+$#", "#(<\?php|<\?)#i"), "", substr($_POST['co_include_tail'], 0, 255)) : '';
// 최고 관리자가 아니면 include 경로 변경 불가 (board_form_update.php 와 동일 정책)
if ($is_admin !== 'super') {
if ($w == 'u') {
$co_include_head = isset($co_row['co_include_head']) ? $co_row['co_include_head'] : '';
$co_include_tail = isset($co_row['co_include_tail']) ? $co_row['co_include_tail'] : '';
} else {
$co_include_head = '';
$co_include_tail = '';
}
}
$co_tag_filter_use = isset($_POST['co_tag_filter_use']) ? (int) $_POST['co_tag_filter_use'] : 1;
$co_himg_del = (isset($_POST['co_himg_del']) && $_POST['co_himg_del']) ? 1 : 0;
$co_timg_del = (isset($_POST['co_timg_del']) && $_POST['co_timg_del']) ? 1 : 0;
+4 -4
View File
@@ -275,7 +275,7 @@ add_javascript(G5_POSTCODE_JS, 0); //다음 주소 js
<th scope="row"><label for="mb_level">회원 권한</label></th>
<td><?php echo get_member_level_select('mb_level', 1, $member['mb_level'], $mb['mb_level']) ?></td>
<th scope="row">포인트</th>
<td><a href="./point_list.php?sfl=mb_id&amp;stx=<?php echo $mb['mb_id'] ?>" target="_blank"><?php echo number_format($mb['mb_point']) ?></a> 점</td>
<td><a href="./point_list.php?sfl=mb_id&amp;stx=<?php echo $mb['mb_id'] ?>" target="_blank"><?php echo number_format(isset($mb['mb_point']) ? $mb['mb_point'] : 0) ?></a> 점</td>
</tr>
<tr>
<th scope="row"><label for="mb_email">E-mail<strong class="sound_only">필수</strong></label></th>
@@ -338,7 +338,7 @@ add_javascript(G5_POSTCODE_JS, 0); //다음 주소 js
<?php echo help('이미지 크기는 <strong>넓이 ' . $config['cf_member_icon_width'] . '픽셀 높이 ' . $config['cf_member_icon_height'] . '픽셀</strong>로 해주세요.') ?>
<input type="file" name="mb_icon" id="mb_icon">
<?php
$mb_dir = substr($mb['mb_id'], 0, 2);
$mb_dir = substr(isset($mb['mb_id']) ? $mb['mb_id'] : '', 0, 2);
$icon_file = G5_DATA_PATH . '/member/' . $mb_dir . '/' . get_mb_icon_name($mb['mb_id']) . '.gif';
if (file_exists($icon_file)) {
$icon_url = str_replace(G5_DATA_PATH, G5_DATA_URL, $icon_file);
@@ -355,7 +355,7 @@ add_javascript(G5_POSTCODE_JS, 0); //다음 주소 js
<?php echo help('이미지 크기는 <strong>넓이 ' . $config['cf_member_img_width'] . '픽셀 높이 ' . $config['cf_member_img_height'] . '픽셀</strong>로 해주세요.') ?>
<input type="file" name="mb_img" id="mb_img">
<?php
$mb_dir = substr($mb['mb_id'], 0, 2);
$mb_dir = substr(isset($mb['mb_id']) ? $mb['mb_id'] : '', 0, 2);
$icon_file = G5_DATA_PATH . '/member_image/' . $mb_dir . '/' . get_mb_icon_name($mb['mb_id']) . '.gif';
if (file_exists($icon_file)) {
echo get_member_profile_img($mb['mb_id']);
@@ -559,7 +559,7 @@ add_javascript(G5_POSTCODE_JS, 0); //다음 주소 js
<span class="provider_name"><?php echo $provider_name; //서비스이름 ?> ( <?php echo $account['displayname']; ?> )</span>
<span class="account_hidden" style="display:none"><?php echo $account['mb_id']; ?></span>
</div>
<div class="btn_info"><a href="<?php echo G5_SOCIAL_LOGIN_URL . '/unlink.php?mp_no=' . $account['mp_no'] ?>" class="social_unlink" data-provider="<?php echo $account['mp_no']; ?>">연동해제</a> <span class="sound_only"><?php echo substr($account['mp_register_day'], 2, 14); ?></span></div>
<div class="btn_info"><a href="<?php echo G5_SOCIAL_LOGIN_URL . '/unlink.php?mp_no=' . $account['mp_no'] ?>" class="social_unlink" data-provider="<?php echo $account['mp_no']; ?>">연동해제</a> <span class="sound_only"><?php echo substr(isset($account['mp_register_day']) ? $account['mp_register_day'] : '', 2, 14); ?></span></div>
</div>
<?php } //end foreach ?>
</li>
+7 -2
View File
@@ -127,6 +127,11 @@ $sql_common = " mb_name = '{$posts['mb_name']}',
mb_9 = '{$posts['mb_9']}',
mb_10 = '{$posts['mb_10']}' ";
// 부여하려는 mb_level 상한 검증 (자기보다 높은 권한 부여 차단)
if ($is_admin !== 'super' && (int) $posts['mb_level'] >= (int) $member['mb_level']) {
alert('자신보다 권한이 높거나 같은 등급은 부여할 수 없습니다.');
}
if ($w == '') {
$mb = get_member($mb_id);
if (isset($mb['mb_id']) && $mb['mb_id']) {
@@ -147,7 +152,7 @@ if ($w == '') {
alert('이미 존재하는 이메일입니다.\\nID : ' . $row['mb_id'] . '\\n이름 : ' . $row['mb_name'] . '\\n닉네임 : ' . $row['mb_nick'] . '\\n메일 : ' . $row['mb_email']);
}
$agree_items = [];
$agree_items = array();
// 마케팅 목적의 개인정보 수집 및 이용
if ($mb_marketing_agree == 1) {
$sql_common .= " , mb_marketing_date = '".G5_TIME_YMDHIS."' ";
@@ -230,7 +235,7 @@ if ($w == '') {
// 현재 데이터 조회
$row = sql_fetch("select * from {$g5['member_table']} where mb_id = '{$mb_id}' ");
$agree_items = [];
$agree_items = array();
// 마케팅 목적의 개인정보 수집 및 이용
$sql_marketing_date = "";
+25 -19
View File
@@ -21,8 +21,8 @@ define('MEMBER_LOG_DIR', G5_DATA_PATH . "/" . MEMBER_BASE_DIR . "/" . "log");
*/
function get_export_config($type = null)
{
$config = [
'sfl_list' => [
$config = array(
'sfl_list' => array(
'mb_id'=>'아이디',
'mb_name'=>'이름',
'mb_nick'=>'닉네임',
@@ -30,26 +30,26 @@ function get_export_config($type = null)
'mb_tel'=>'전화번호',
'mb_hp'=>'휴대폰번호',
'mb_addr1'=>'주소'
],
'point_cond_map' => [
),
'point_cond_map' => array(
'gte'=>'≥',
'lte'=>'≤',
'eq'=>'='
],
'intercept_list' => [
),
'intercept_list' => array(
'exclude'=>'차단회원 제외',
'only'=>'차단회원만'
],
'ad_range_list' => [
),
'ad_range_list' => array(
'all' => '수신동의 회원 전체',
'mailling_only' => '이메일 수신동의 회원만',
'sms_only' => 'SMS/카카오톡 수신동의 회원만',
'month_confirm' => date('m월').' 수신동의 확인 대상만',
'custom_period' => '수신동의 기간 직접 입력'
],
];
),
);
return $type ? (isset($config[$type]) ? $config[$type] : []) : $config;
return $type ? (isset($config[$type]) ? $config[$type] : array()) : $config;
}
/**
@@ -59,14 +59,14 @@ function get_member_export_params()
{
// 친구톡 양식 - 엑셀 양식에 포함할 항목
$fieldArray = array_map('trim', explode(',', isset($_GET['fields']) ? $_GET['fields'] : ''));
$vars = [];
$vars = array();
foreach ($fieldArray as $index => $field) {
if(!empty($field)){
$vars['var' . ($index + 1)] = $field;
}
}
$params = [
$params = array(
'page' => 1,
'formatType' => (int)(isset($_GET['formatType']) ? $_GET['formatType'] : 1),
'use_stx' => isset($_GET['use_stx']) ? $_GET['use_stx'] : 0,
@@ -92,24 +92,30 @@ function get_member_export_params()
'use_intercept' => isset($_GET['use_intercept']) ? $_GET['use_intercept'] : 0,
'intercept' => clean_xss_tags(isset($_GET['intercept']) ? $_GET['intercept'] : 'exclude'),
'vars' => $vars,
];
);
// 레벨 범위 검증
if ($params['level_start'] > $params['level_end']) {
[$params['level_start'] , $params['level_end']] = [$params['level_end'], $params['level_start']];
$tmp_level = $params['level_start'];
$params['level_start'] = $params['level_end'];
$params['level_end'] = $tmp_level;
}
// 가입기간 - 날짜 범위 검증
if ($params['use_date'] && $params['date_start'] && $params['date_end']) {
if ($params['date_start'] > $params['date_end']) {
[$params['date_start'] , $params['date_end']] = [$params['date_end'], $params['date_start']];
$tmp_date = $params['date_start'];
$params['date_start'] = $params['date_end'];
$params['date_end'] = $tmp_date;
}
}
// 수신동의기간 - 날짜 범위 검증
if ($params['ad_range_type'] == 'custom_period' && $params['agree_date_start'] && $params['agree_date_end']) {
if ($params['agree_date_start'] > $params['agree_date_end']) {
[$params['agree_date_start'] , $params['agree_date_end']] = [$params['agree_date_end'], $params['agree_date_start']];
$tmp_agree_date = $params['agree_date_start'];
$params['agree_date_start'] = $params['agree_date_end'];
$params['agree_date_end'] = $tmp_agree_date;
}
}
@@ -141,7 +147,7 @@ function member_export_get_total_count($params)
function member_export_build_where($params)
{
global $config;
$conditions = [];
$conditions = array();
// 기본 조건 - 탈퇴하지 않은 사용자
$conditions[] = "mb_leave_date = ''";
@@ -263,7 +269,7 @@ function member_export_build_where($params)
$conditions[] = "0=1"; // 둘 다 해제 ⇒ 결과 0건
} else {
// 조건 조립
$parts = [];
$parts = array();
if ($useEmail) $parts[] = "(mb_mailling = 1 AND {$emailDateCond})";
if ($useSms) $parts[] = "(mb_sms = 1 AND {$smsDateCond})";
+4 -4
View File
@@ -191,12 +191,12 @@ $colspan = 14;
<?php
$thirdpartyLbl = (!empty($config['cf_sms_use'])) ? ' / <b>개인정보 제3자 제공</b>' : '';
$ad_range_text = [
$ad_range_text = array(
'all' => "* <b>광고성 정보 수신(이메일 또는 SMS/카카오톡)</b> / <b>마케팅 목적의 개인정보 수집 및 이용</b>{$thirdpartyLbl}에 모두 동의한 회원을 선택합니다.",
'mailling_only' => "* <b>광고성 이메일 수신</b> / <b>마케팅 목적의 개인정보 수집 및 이용</b>{$thirdpartyLbl}에 모두 동의한 회원을 선택합니다.",
'sms_only' => "* <b>광고성 SMS/카카오톡 수신</b> / <b>마케팅 목적의 개인정보 수집 및 이용</b>{$thirdpartyLbl}에 모두 동의한 회원을 선택합니다.",
'month_confirm' => "* 23개월 전(" . date('Y년 m월', strtotime('-23 month')) . ") <b>광고성 정보 수신 동의(이메일 또는 SMS/카카오톡)</b>한 회원을 선택합니다."
];
);
if (isset($_GET['ad_range_only'], $_GET['ad_range_type']) && isset($ad_range_text[$_GET['ad_range_type']])) {
echo '<div class="ad_range_box"><p>' . $ad_range_text[$_GET['ad_range_type']] . '</p></div>';
@@ -210,7 +210,7 @@ $colspan = 14;
</div>
<!-- 채널 체크박스 -->
<div class="sch_row <?php echo isset($_GET['ad_range_only']) && in_array($_GET['ad_range_type'], ['month_confirm', 'custom_period']) ? '' : 'is-hidden'; ?>">
<div class="sch_row <?php echo isset($_GET['ad_range_only']) && in_array($_GET['ad_range_type'], array('month_confirm', 'custom_period')) ? '' : 'is-hidden'; ?>">
<div class="ad_range_wrap">
<div class="ad_range_box">
<div class="label">
@@ -480,4 +480,4 @@ function triggerAutoDownload(url, filename) {
</script>
<?php
require_once './admin.tail.php';
require_once './admin.tail.php';
+67 -53
View File
@@ -14,7 +14,7 @@ session_write_close(); // 세션 종료 및 잠금 해제 (백그라운드 작
$params = get_member_export_params();
if (!$params || !is_array($params)) {
member_export_send_progress("error", "데이터가 올바르게 전달되지 않아 작업에 실패하였습니다.");
member_export_write_log([], ['success' => false, 'error' => '데이터가 올바르게 전달되지 않아 작업에 실패하였습니다.']);
member_export_write_log(array(), array('success' => false, 'error' => '데이터가 올바르게 전달되지 않아 작업에 실패하였습니다.'));
exit;
}
@@ -28,7 +28,7 @@ member_export_set_sse_headers();
$mode = isset($_GET['mode']) ? $_GET['mode'] : '';
if ($mode !== 'start') {
member_export_send_progress("error", "잘못된 요청 입니다.");
member_export_write_log($params, ['success' => false, 'error' => '잘못된 요청 입니다.']);
member_export_write_log($params, array('success' => false, 'error' => '잘못된 요청 입니다.'));
exit;
}
@@ -43,7 +43,7 @@ catch (Exception $e)
// 에러 로그 저장 및 SSE 에러 전송
error_log("[Member Export Error] " . $e->getMessage());
member_export_send_progress("error", $e->getMessage());
member_export_write_log($params, ['success' => false, 'error' => $e->getMessage()]);
member_export_write_log($params, array('success' => false, 'error' => $e->getMessage()));
}
/**
@@ -62,7 +62,7 @@ function main_member_export($params)
}
$fileName = 'member_'.MEMBER_BASE_DATE;
$fileList = [];
$fileList = array();
$zipFileName = '';
if ($total > MEMBER_EXPORT_PAGE_SIZE) {
@@ -88,7 +88,7 @@ function main_member_export($params)
$zipResult = member_export_create_zip($fileList, $fileName); // 압축 파일 생성
if($zipResult['error']){
member_export_write_log($params, ['success' => false, 'error' => $zipResult['error']]);
member_export_write_log($params, array('success' => false, 'error' => $zipResult['error']));
member_export_send_progress("zippingError", $zipResult['error']);
}
@@ -107,19 +107,19 @@ function main_member_export($params)
member_export_send_progress("progress", "", 1, $total, $total);
}
member_export_write_log($params, ['success' => true, 'total' => $total, 'files' => $fileList, 'zip' => isset($zipFileName) ? $zipFileName : null]);
member_export_write_log($params, array('success' => true, 'total' => $total, 'files' => $fileList, 'zip' => isset($zipFileName) ? $zipFileName : null));
member_export_send_progress("done", "", 2, $total, $total, $pages, $pages, $fileList, $zipFileName);
}
/**
* 진행률 전송
*/
function member_export_send_progress($status, $message = "", $downloadType = 1, $total = 1, $current = 1, $totalChunks = 1, $currentChunk = 1, $files = [], $zipFile = '')
function member_export_send_progress($status, $message = "", $downloadType = 1, $total = 1, $current = 1, $totalChunks = 1, $currentChunk = 1, $files = array(), $zipFile = '')
{
// 연결 상태 확인
if (connection_aborted()) return;
$data = [
$data = array(
'status' => $status,
'message' => $message,
'downloadType' => $downloadType,
@@ -130,9 +130,10 @@ function member_export_send_progress($status, $message = "", $downloadType = 1,
'files' => $files,
'zipFile' => $zipFile,
'filePath' => G5_DATA_URL . "/" . MEMBER_BASE_DIR . "/" . MEMBER_BASE_DATE,
];
);
echo "data: " . json_encode($data, JSON_UNESCAPED_UNICODE) . "\n\n";
$json_options = defined('JSON_UNESCAPED_UNICODE') ? JSON_UNESCAPED_UNICODE : 0;
echo "data: " . json_encode($data, $json_options) . "\n\n";
// 더 안정적인 플러시
if (ob_get_level()) ob_end_flush();
@@ -145,18 +146,18 @@ function member_export_send_progress($status, $message = "", $downloadType = 1,
function member_export_get_config()
{
$type = 1;
$configs = [
1 => [
'title' => ["회원관리파일(일반)"],
'headers' => ['아이디', '이름', '닉네임', '휴대폰번호', '전화번호', '이메일', '주소', '회원권한', '포인트', '가입일', '차단',
$configs = array(
1 => array(
'title' => array("회원관리파일(일반)"),
'headers' => array('아이디', '이름', '닉네임', '휴대폰번호', '전화번호', '이메일', '주소', '회원권한', '포인트', '가입일', '차단',
'광고성 이메일 수신동의', '광고성 이메일 동의일자', '광고성 SMS/카카오톡 수신동의', '광고성 SMS/카카오톡 동의일자',
'마케팅목적의개인정보수집및이용동의', '마케팅목적의개인정보수집및이용동의일자', '개인정보제3자제공동의', '개인정보제3자제공동의일자'],
'fields' => ['mb_id', 'mb_name', 'mb_nick', 'mb_hp', 'mb_tel', 'mb_email', 'mb_addr1', 'mb_level', 'mb_point', 'mb_datetime', 'mb_intercept_date',
'마케팅목적의개인정보수집및이용동의', '마케팅목적의개인정보수집및이용동의일자', '개인정보제3자제공동의', '개인정보제3자제공동의일자'),
'fields' => array('mb_id', 'mb_name', 'mb_nick', 'mb_hp', 'mb_tel', 'mb_email', 'mb_addr1', 'mb_level', 'mb_point', 'mb_datetime', 'mb_intercept_date',
'mb_mailling','mb_mailling_date', 'mb_sms','mb_sms_date', 'mb_marketing_agree',
'mb_marketing_date', 'mb_thirdparty_agree', 'mb_thirdparty_date'],
'widths' => [20, 20, 20, 20, 20, 30, 30, 10, 15, 25, 10, 20, 25, 20, 25, 20, 25, 20, 25],
],
];
'mb_marketing_date', 'mb_thirdparty_agree', 'mb_thirdparty_date'),
'widths' => array(20, 20, 20, 20, 20, 30, 30, 10, 15, 25, 10, 20, 25, 20, 25, 20, 25, 20, 25),
),
);
return isset($configs[$type]) ? $configs[$type] : $configs[1];
}
@@ -195,7 +196,7 @@ function member_export_get_data($params)
$fields = array_unique($fields);
// SQL 변환 맵 (가공이 필요한 필드만 정의)
$sqlTransformMap = [
$sqlTransformMap = array(
'mb_datetime' => "IF(mb_datetime = '0000-00-00 00:00:00', '', mb_datetime) AS mb_datetime",
'mb_intercept_date' => "IF(mb_intercept_date != '', '차단됨', '정상') AS mb_intercept_date",
'mb_sms' => "IF(mb_sms = '1', '동의', '미동의') AS mb_sms",
@@ -206,10 +207,10 @@ function member_export_get_data($params)
'mb_marketing_date' => "IF(mb_marketing_agree != '1' OR mb_marketing_date = '0000-00-00 00:00:00', '', mb_marketing_date) AS mb_marketing_date",
'mb_thirdparty_agree' => "IF(mb_thirdparty_agree = '1', '동의', '미동의') AS mb_thirdparty_agree",
'mb_thirdparty_date' => "IF(mb_thirdparty_agree != '1' OR mb_thirdparty_date = '0000-00-00 00:00:00', '', mb_thirdparty_date) AS mb_thirdparty_date",
];
);
// SQL 필드 생성
$sqlFields = [];
$sqlFields = array();
foreach ($fields as $field) {
$sqlFields[] = isset($sqlTransformMap[$field]) ? $sqlTransformMap[$field] : $field;
}
@@ -228,12 +229,16 @@ function member_export_get_data($params)
throw new Exception("데이터 조회에 실패하였습니다");
}
$excelData = [$config['title'], $config['headers']];
$excelData = array($config['title'], $config['headers']);
while ($row = sql_fetch_array($result)) {
$rowData = [];
$rowData = array();
foreach ($fields as $field) {
$rowData[] = isset($row[$field]) ? $row[$field] : '';
if (isset($row[$field])) {
$rowData[] = function_exists('csv_safe_cell') ? csv_safe_cell($row[$field]) : $row[$field];
} else {
$rowData[] = '';
}
}
$excelData[] = $rowData;
}
@@ -257,10 +262,10 @@ function member_export_create_excel($data, $fileName, $index = 0)
$currentCache = PHPExcel_Settings::getCacheStorageMethod();
// 캐싱 모드 설정 (엑셀 생성 전용)
$cacheMethods = [
$cacheMethods = array(
PHPExcel_CachedObjectStorageFactory::cache_to_discISAM,
PHPExcel_CachedObjectStorageFactory::cache_in_memory_serialized
];
);
foreach ($cacheMethods as $method) {
if (PHPExcel_Settings::setCacheStorageMethod($method)) {
@@ -274,12 +279,12 @@ function member_export_create_excel($data, $fileName, $index = 0)
// 헤더 스타일 적용
$last_char = member_export_column_char(count($config['headers']) - 1);
$sheet->getStyle("A2:{$last_char}2")->applyFromArray([
'fill' => [
$sheet->getStyle("A2:{$last_char}2")->applyFromArray(array(
'fill' => array(
'type' => PHPExcel_Style_Fill::FILL_SOLID,
'startcolor' => ['rgb' => 'D9E1F2'], // 연파랑 배경
],
]);
'startcolor' => array('rgb' => 'D9E1F2'), // 연파랑 배경
),
));
// 셀 정렬 및 줄바꿈 설정
$sheet->getStyle("A:{$last_char}")->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER)->setWrapText(true);
@@ -309,14 +314,15 @@ function member_export_create_excel($data, $fileName, $index = 0)
}
catch (Exception $e)
{
throw new Exception("엑셀 파일 생성에 실패하였습니다: " . $e->getMessage());
}
finally
{
// 캐싱 모드 원래 상태로 복원
if ($currentCache) {
PHPExcel_Settings::setCacheStorageMethod($currentCache);
}
throw new Exception("엑셀 파일 생성에 실패하였습니다: " . $e->getMessage());
}
// 캐싱 모드 원래 상태로 복원
if ($currentCache) {
PHPExcel_Settings::setCacheStorageMethod($currentCache);
}
return $filename;
@@ -329,7 +335,7 @@ function member_export_create_zip($files, $zipFileName)
{
if (!class_exists('ZipArchive')) {
error_log('[Member Export Error] ZipArchive 클래스를 사용할 수 없습니다.');
return ['error' => '파일을 압축하는 중 문제가 발생했습니다. 개별 파일로 제공됩니다.<br>: ZipArchive 클래스를 사용할 수 없습니다.'];
return array('error' => '파일을 압축하는 중 문제가 발생했습니다. 개별 파일로 제공됩니다.<br>: ZipArchive 클래스를 사용할 수 없습니다.');
}
member_export_ensure_directory(MEMBER_EXPORT_DIR);
@@ -337,7 +343,7 @@ function member_export_create_zip($files, $zipFileName)
$zip = new ZipArchive();
if ($zip->open($destinationZipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== TRUE) {
return ['error' => "파일을 압축하는 중 문제가 발생했습니다. 개별 파일로 제공됩니다."];
return array('error' => "파일을 압축하는 중 문제가 발생했습니다. 개별 파일로 제공됩니다.");
}
foreach ($files as $file) {
@@ -349,11 +355,11 @@ function member_export_create_zip($files, $zipFileName)
$result = $zip->close();
return [
return array(
'result' => $result,
'zipFile' => $zipFileName . ".zip",
'zipPath' => $destinationZipPath,
];
);
}
/**
@@ -378,7 +384,7 @@ function member_export_ensure_directory($dir)
* - 알집 생성 완료 시 엑셀 파일 제거
* - 작업 전 오늘 날짜 폴더 및 log 폴더를 제외한 나머지 파일 모두 제거
*/
function member_export_delete($fileList = [])
function member_export_delete($fileList = array())
{
$cnt = 0;
@@ -397,7 +403,7 @@ function member_export_delete($fileList = [])
function deleteFolder($dir) {
foreach (glob($dir . '/{.,}*', GLOB_BRACE) as $item) {
if (in_array(basename($item), ['.', '..'])) continue;
if (in_array(basename($item), array('.', '..'))) continue;
is_dir($item) ? deleteFolder($item) : unlink($item);
}
rmdir($dir);
@@ -424,7 +430,7 @@ function member_export_delete($fileList = [])
/**
* 로그 작성
*/
function member_export_write_log($params, $result = [])
function member_export_write_log($params, $result = array())
{
global $member;
@@ -438,10 +444,13 @@ function member_export_write_log($params, $result = [])
@chmod(MEMBER_LOG_DIR, G5_DIR_PERMISSION);
}
$logFiles = glob(MEMBER_LOG_DIR . "/export_log_*.log") ?: [];
$logFiles = glob(MEMBER_LOG_DIR . "/export_log_*.log");
if (!$logFiles) {
$logFiles = array();
}
// 최신 파일 기준 정렬 (최신 → 오래된)
usort($logFiles, fn($a, $b) => filemtime($b) - filemtime($a));
usort($logFiles, 'member_export_compare_log_mtime');
$latestLogFile = isset($logFiles[0]) ? $logFiles[0] : null;
@@ -464,7 +473,7 @@ function member_export_write_log($params, $result = [])
$status = $success ? '성공' : '실패';
// 조건 정리
$condition = [];
$condition = array();
// 검색 조건
if ($params['use_stx'] == 1 && !empty($params['stx'])) {
@@ -506,11 +515,11 @@ function member_export_write_log($params, $result = [])
$condition[] = "수신동의일: {$params['agree_date_start']}~{$params['agree_date_end']}";
}
if (in_array($params['ad_range_type'], ["month_confirm", "custom_period"])){
$channels = array_filter([
if (in_array($params['ad_range_type'], array("month_confirm", "custom_period"))){
$channels = array_filter(array(
!empty($params['ad_mailling']) && (int)$params['ad_mailling'] === 1 ? '이메일' : null,
!empty($params['ad_sms']) && (int)$params['ad_sms'] === 1 ? 'SMS/카카오톡' : null,
]);
));
if ($channels) {
$condition[] = '수신채널: ' . implode(', ', $channels);
@@ -531,7 +540,7 @@ function member_export_write_log($params, $result = [])
// 성공일 경우 추가 정보
if ($success) {
$total = isset($result['total']) ? $result['total'] : 0;
$fileCount = isset($result['zip']) ? 1 : count(isset($result['files']) ? $result['files'] : []);
$fileCount = isset($result['zip']) ? 1 : count(isset($result['files']) ? $result['files'] : array());
$line1 .= " | 총 {$total}건 | 파일: {$fileCount}개";
}
@@ -548,4 +557,9 @@ function member_export_write_log($params, $result = [])
if (@file_put_contents($latestLogFile, $logEntry, FILE_APPEND | LOCK_EX) === false) {
error_log("[Member Export Error] 로그 파일 기록 실패: {$latestLogFile}");
}
}
}
function member_export_compare_log_mtime($a, $b)
{
return filemtime($b) - filemtime($a);
}
+3 -1
View File
@@ -27,7 +27,7 @@ if ($_POST['act_button'] == "선택수정") {
$post_mb_sms = isset($_POST['mb_sms'][$k]) ? (int) $_POST['mb_sms'][$k] : 0;
$post_mb_open = isset($_POST['mb_open'][$k]) ? (int) $_POST['mb_open'][$k] : 0;
$agree_items = [];
$agree_items = array();
// 광고성 이메일 수신동의 일자 추가
$post_mb_mailling_default = isset($_POST['mb_mailling_default'][$k]) ? (int) $_POST['mb_mailling_default'][$k] : 0;
$sql_mailling_date = "";
@@ -57,6 +57,8 @@ if ($_POST['act_button'] == "선택수정") {
$msg .= $mb['mb_id'] . ' : 회원자료가 존재하지 않습니다.\\n';
} elseif ($is_admin != 'super' && $mb['mb_level'] >= $member['mb_level']) {
$msg .= $mb['mb_id'] . ' : 자신보다 권한이 높거나 같은 회원은 수정할 수 없습니다.\\n';
} elseif ($is_admin != 'super' && $post_mb_level >= (int) $member['mb_level']) {
$msg .= $mb['mb_id'] . ' : 자신보다 권한이 높거나 같은 등급은 부여할 수 없습니다.\\n';
} elseif ($member['mb_id'] == $mb['mb_id']) {
$msg .= $mb['mb_id'] . ' : 로그인 중인 관리자는 수정 할 수 없습니다.\\n';
} else {
+2
View File
@@ -6,6 +6,8 @@ auth_check_menu($auth, $sub_menu, 'r');
// 체크된 자료 삭제
if (isset($_POST['chk']) && is_array($_POST['chk'])) {
check_admin_token();
for ($i = 0; $i < count($_POST['chk']); $i++) {
$pp_id = (int) $_POST['chk'][$i];
+6
View File
@@ -21,6 +21,12 @@ foreach ($check_keys as $key) {
$qa_include_head = isset($qa_include_head) ? preg_replace(array("#[\\\]+$#", "#(<\?php|<\?)#i"), "", substr($qa_include_head, 0, 255)) : '';
$qa_include_tail = isset($qa_include_tail) ? preg_replace(array("#[\\\]+$#", "#(<\?php|<\?)#i"), "", substr($qa_include_tail, 0, 255)) : '';
// 최고 관리자가 아니면 include 경로 변경 불가 (board_form_update.php 와 동일 정책)
if ($is_admin !== 'super') {
$qa_include_head = isset($qaconfig['qa_include_head']) ? $qaconfig['qa_include_head'] : '';
$qa_include_tail = isset($qaconfig['qa_include_tail']) ? $qaconfig['qa_include_tail'] : '';
}
// 관리자가 자동등록방지를 사용해야 할 경우
if ($board && ($qaconfig['qa_include_head'] !== $qa_include_head || $qaconfig['qa_include_tail'] !== $qa_include_tail) && function_exists('get_admin_captcha_by') && get_admin_captcha_by()) {
include_once G5_CAPTCHA_PATH . '/captcha.lib.php';
+61 -24
View File
@@ -9,40 +9,76 @@ if (!$config['cf_email_use'])
include_once(G5_LIB_PATH.'/mailer.lib.php');
$token = get_token();
$g5['title'] = '메일 테스트';
include_once('./admin.head.php');
if (isset($_POST['email'])) {
check_admin_token();
$_POST['email'] = strip_tags($_POST['email']);
$email = explode(',', $_POST['email']);
$real_email = array();
$sent_email = array(); // 발송 요청 성공
$failed_email = array(); // 발송 실패 (메일 서버에서 거부/오류)
for ($i=0; $i<count($email); $i++){
if (!preg_match("/([0-9a-zA-Z_-]+)@([0-9a-zA-Z_-]+)\.([0-9a-zA-Z_-]+)/", $email[$i])) continue;
$real_email[] = $email[$i];
mailer($config['cf_admin_email_name'], $config['cf_admin_email'], trim($email[$i]), '[메일검사] 제목', '<span style="font-size:9pt;">[메일검사] 내용<p>이 내용이 제대로 보인다면 보내는 메일 서버에는 이상이 없는것입니다.<p>'.G5_TIME_YMDHIS.'<p>이 메일 주소로는 회신되지 않습니다.</span>', 1);
$to = trim($email[$i]);
$send_result = mailer($config['cf_admin_email_name'], $config['cf_admin_email'], $to, '[메일검사] 제목', '<span style="font-size:9pt;">[메일검사] 내용<p>이 내용이 제대로 보인다면 보내는 메일 서버에는 이상이 없는것입니다.<p>'.G5_TIME_YMDHIS.'<p>이 메일 주소로는 회신되지 않습니다.</span>', 1);
if ($send_result) {
$sent_email[] = $to;
} else {
$failed_email[] = $to;
}
}
if( $real_email ){
if( $sent_email || $failed_email ){
echo '<section>';
echo '<h2>결과메세지</h2>';
echo '<div class="local_desc01 local_desc"><p>';
echo '다음 '.count($real_email).'개의 메일 주소로 테스트 메일 발송이 완료되었습니다.';
echo '</p></div>';
echo '<ul>';
for ($i=0;$i<count($real_email);$i++) {
echo '<li>'.$real_email[$i].'</li>';
echo '<h2>결과 메시지</h2>';
if( $sent_email ){
echo '<div class="local_desc01 local_desc"><p>';
echo '다음 '.count($sent_email).'개의 메일 주소로 테스트 메일 <strong>발송 요청이 성공</strong>했습니다. <strong>수신함 도착 여부는 별도 확인이 필요합니다.</strong>';
echo '</p></div>';
echo '<ul>';
for ($i=0;$i<count($sent_email);$i++) {
echo '<li>'.get_text($sent_email[$i]).'</li>';
}
echo '</ul>';
echo '<div class="local_desc02 local_desc"><p>';
echo '<strong>발송 요청 성공은 사이트가 메일 서버에 메일을 넘겼다는 의미이며, 받은편지함 도착을 보장하지는 않습니다.</strong><br>';
echo '메일이 보이지 않는다면 아래 항목을 순서대로 확인해 주십시오.';
echo '</p></div>';
echo '<ol>';
echo '<li>받은편지함뿐 아니라 <strong>스팸함, 정크메일함, 프로모션함</strong>을 확인합니다.</li>';
echo '<li>네이버, 지메일, 회사메일 등 <strong>서로 다른 메일 주소</strong>로 다시 테스트합니다.</li>';
echo '<li>관리자 메일 주소가 사이트 도메인과 같은지 확인합니다. 도메인이 다르면 스팸으로 분류될 가능성이 높습니다.</li>';
echo '<li>도메인 메일을 사용한다면 <strong>SPF, DKIM, DMARC</strong> 설정을 확인합니다.</li>';
echo '<li>계속 도착하지 않으면 서버 개발자에게 메일 발송 로그를 확인해주세요.</li>';
echo '</ol>';
}
echo '</ul>';
echo '<div class="local_desc02 local_desc"><p>';
echo '해당 주소로 테스트 메일이 도착했는지 확인해 주십시오.<br>';
echo '만약, 테스트 메일이 오지 않는다면 더 다양한 계정의 메일 주소로 메일을 보내 보십시오.<br>';
echo '그래도 메일이 하나도 도착하지 않는다면 메일 서버(sendmail server)의 오류일 가능성이 높으니, 웹 서버관리자에게 문의하여 주십시오.<br>';
echo '도메인을 소유하고 있을시 SPF, DKIM 설정이 필요할수 있습니다.<br>';
echo '</p></div>';
if( $failed_email ){
echo '<div class="local_desc01 local_desc" style="color:#d9534f"><p>';
echo '다음 '.count($failed_email).'개의 메일 주소는 <strong>발송에 실패</strong>했습니다.';
echo '</p></div>';
echo '<ul>';
for ($i=0;$i<count($failed_email);$i++) {
echo '<li>'.get_text($failed_email[$i]).'</li>';
}
echo '</ul>';
echo '<div class="local_desc02 local_desc"><p>';
echo '발송 실패는 받는 사람의 문제가 아니라 <strong>보내는 서버(메일 발송) 설정 문제</strong>일 가능성이 높습니다.<br>';
echo 'SMTP 정보(주소/포트/인증)가 올바른지, 서버에서 메일 발송(sendmail/mail 함수)이 허용되어 있는지 확인하시고, 웹 서버 관리자(호스팅 업체)에게 문의해 주십시오.<br>';
echo '자세한 오류 내용은 서버의 PHP error_log 에 기록됩니다.<br>';
echo '</p></div>';
}
echo '</section>';
}
}
@@ -52,15 +88,16 @@ if (isset($_POST['email'])) {
<h2>테스트 메일 발송</h2>
<div class="local_desc02 local_desc">
<p>
메일서버가 정상적으로 동작 중인지 확인할 수 있습니다.<br>
사이트에서 메일 서버로 메일을 전달할 수 있는지 확인합니다. 이 테스트는 받은편지함 도착을 보장하지 않습니다.<br>
아래 입력칸에 테스트 메일을 발송하실 메일 주소를 입력하시면, [메일검사] 라는 제목으로 테스트 메일을 발송합니다.<br>
보내는 메일주소 : <?php echo get_sanitize_input($config['cf_admin_email']); ?><br>
<?php if (function_exists('domain_mail_host') && $config['cf_admin_email'] && stripos($config['cf_admin_email'], domain_mail_host()) === false) { ?>
<?php echo '외부메일설정이나 기타 설정을 하지 않았다면, 도메인과 다른 헤더로 여겨 스팸이나 차단될 가능성이 있습니다.<br>기본환경설정에서 관리자 메일 주소를 name'.domain_mail_host().' 과 같은 도메인 형식으로 설정할것을 권장합니다.'; ?>
<?php echo '외부메일설정이나 기타 설정을 하지 않았다면, 도메인과 다른 헤더로 여겨 스팸이나 차단될 가능성이 있습니다.<br>외부메일설정이나 기타 설정을 하지 않았다면, 기본환경설정에서 관리자 메일 주소를 name'.domain_mail_host().' 과 같은 도메인 형식으로 설정할것을 권장합니다.'; ?>
<?php } ?>
</p>
</div>
<form name="fsendmailtest" method="post">
<input type="hidden" name="token" value="<?php echo $token; ?>">
<fieldset id="fsendmailtest">
<legend>테스트메일 발송</legend>
<label for="email">받는 메일주소<strong class="sound_only"> 필수</strong></label>
@@ -70,11 +107,11 @@ if (isset($_POST['email'])) {
</form>
<div class="local_desc02 local_desc">
<p>
만약 [메일검사] 라는 내용으로 테스트 메일이 도착하지 않는다면 보내는 메일서버 혹은 받는 메일서버 중 문제가 발생했을 가능성이 있습니다.<br>
따라서 보다 정확한 테스트를 원하신다면 여러 곳으로 테스트 메일을 발송하시기 바랍니다.<br>
테스트 결과가 발송 요청 성공으로 표시되어도 수신 메일 서버의 스팸 정책에 따라 도착하지 않을 수 있습니다.<br>
정확한 확인을 위해 여러 메일 서비스로 테스트하고, 도착하지 않으면 스팸함과 도메인 인증(SPF, DKIM, DMARC)을 확인해 주십시오.<br>
</p>
</div>
</section>
<?php
include_once('./admin.tail.php');
include_once('./admin.tail.php');
+2 -2
View File
@@ -123,7 +123,7 @@ if ($w == "" || $w == "u")
$sql = " select mb_id from {$g5['member_table']} where mb_id = '$ca_mb_id' ";
$row = sql_fetch($sql);
if (!$row['mb_id'])
alert("\'$ca_mb_id\' 은(는) 존재하는 회원아이디가 아닙니다.");
alert("'$ca_mb_id' 은(는) 존재하는 회원아이디가 아닙니다.");
}
}
@@ -256,4 +256,4 @@ if ($w == "" || $w == "u")
goto_url("./categoryform.php?w=u&amp;ca_id=$ca_id&amp;$qstr");
} else {
goto_url("./categorylist.php?$qstr");
}
}
+3 -3
View File
@@ -19,7 +19,7 @@ for ($i=0; $i<$post_ca_id_count; $i++)
$sql = " select mb_id from {$g5['member_table']} where mb_id = '".sql_real_escape_string($str_ca_mb_id)."' ";
$row = sql_fetch($sql);
if (!$row['mb_id'])
alert("\'{$str_ca_mb_id}\' 은(는) 존재하는 회원아이디가 아닙니다.", "./categorylist.php?$qstr");
alert("'{$str_ca_mb_id}' 은(는) 존재하는 회원아이디가 아닙니다.", "./categorylist.php?$qstr");
}
$check_files = array();
@@ -51,7 +51,7 @@ for ($i=0; $i<$post_ca_id_count; $i++)
alert('스킨파일명에 포함될수 없는 문자가 들어있습니다.');
}
if( ! is_include_path_check($file) ){
if( ! is_include_path_check($file, 1) ){
alert('오류 : 데이터폴더가 포함된 path 또는 잘못된 path 를 포함할수 없습니다.');
}
@@ -94,4 +94,4 @@ for ($i=0; $i<$post_ca_id_count; $i++)
}
goto_url("./categorylist.php?$qstr");
goto_url("./categorylist.php?$qstr");
+11 -5
View File
@@ -221,7 +221,7 @@ $od_zip2 = substr($od_zip, 3);
$od_addr1 = addslashes(clean_xss_tags($data['od_addr1']));
$od_addr2 = addslashes(clean_xss_tags($data['od_addr2']));
$od_addr3 = addslashes(clean_xss_tags($data['od_addr3']));
$od_addr_jibeon = preg_match("/^(N|R)$/", $data['od_addr_jibeon']) ? $data['od_addr_jibeon'] : '';
$od_addr_jibeon = preg_match("/^(N|R|J)$/", $data['od_addr_jibeon']) ? $data['od_addr_jibeon'] : '';
$od_b_name = addslashes(clean_xss_tags($data['od_b_name']));
$od_b_tel = addslashes(clean_xss_tags($data['od_b_tel']));
$od_b_hp = addslashes(clean_xss_tags($data['od_b_hp']));
@@ -231,7 +231,7 @@ $od_b_zip2 = substr($od_b_zip, 3);
$od_b_addr1 = addslashes(clean_xss_tags($data['od_b_addr1']));
$od_b_addr2 = addslashes(clean_xss_tags($data['od_b_addr2']));
$od_b_addr3 = addslashes(clean_xss_tags($data['od_b_addr3']));
$od_b_addr_jibeon = preg_match("/^(N|R)$/", $data['od_b_addr_jibeon']) ? $data['od_b_addr_jibeon'] : '';
$od_b_addr_jibeon = preg_match("/^(N|R|J)$/", $data['od_b_addr_jibeon']) ? $data['od_b_addr_jibeon'] : '';
$od_memo = addslashes(clean_xss_tags($data['od_memo'], 0, 1, 0, 0));
$od_deposit_name = addslashes(clean_xss_tags($data['od_deposit_name']));
$od_tax_flag = $default['de_tax_flag_use'];
@@ -384,10 +384,16 @@ sql_query($sql);
$sql = " delete from {$g5['g5_shop_order_data_table']} where od_id = '$od_id' and dt_pg = '$od_pg' ";
sql_query($sql, true);
$orderform_url = './orderform.php?od_id='.$od_id;
$inorderlist_url = './inorderlist.php?'.str_replace('&amp;', '&', $qstr);
$js_replace = array('\\' => '\\\\', '"' => '\\"', "'" => '\\u0027', '/' => '\\/', "\r" => '\\r', "\n" => '\\n', "\t" => '\\t', '<' => '\\u003C', '>' => '\\u003E', '&' => '\\u0026', "\xE2\x80\xA8" => '\\u2028', "\xE2\x80\xA9" => '\\u2029');
$js_orderform_url = function_exists('get_js_safe_string') ? get_js_safe_string($orderform_url) : '"'.strtr((string)$orderform_url, $js_replace).'"';
$js_inorderlist_url = function_exists('get_js_safe_string') ? get_js_safe_string($inorderlist_url) : '"'.strtr((string)$inorderlist_url, $js_replace).'"';
echo '<meta http-equiv="content-type" content="text/html; charset=utf-8">'.PHP_EOL;
echo '<script>'.PHP_EOL;
echo 'if(confirm("복구하신 주문 상세페이지로 이동하시겠습니까?"))'.PHP_EOL;
echo 'document.location.href = "./orderform.php?od_id='.$od_id.'";'.PHP_EOL;
echo 'document.location.href = '.$js_orderform_url.';'.PHP_EOL;
echo 'else'.PHP_EOL;
echo 'document.location.href = "./inorderlist.php?'.str_replace('&amp;', '&', $qstr).'";'.PHP_EOL;
echo '</script>'.PHP_EOL;
echo 'document.location.href = '.$js_inorderlist_url.';'.PHP_EOL;
echo '</script>'.PHP_EOL;
+6
View File
@@ -104,6 +104,12 @@ $colspan = 10;
case 'lg':
$pg = 'LGU+';
break;
case 'toss':
$pg = '토스페이먼츠';
break;
case 'nicepay':
$pg = 'NICEPAY';
break;
default:
$pg = 'KCP';
break;
+2 -2
View File
@@ -105,7 +105,7 @@ else if ($w == "u")
and b.ca_mb_id = '{$member['mb_id']}' ";
$row = sql_fetch($sql);
if (!$row['it_id'])
alert("\'{$member['mb_id']}\' 님께서 수정 할 권한이 없는 상품입니다.");
alert("'{$member['mb_id']}' 님께서 수정 할 권한이 없는 상품입니다.");
}
$it = get_shop_item($it_id);
@@ -1901,4 +1901,4 @@ categorychange(document.fitemform);
</script>
<?php
include_once (G5_ADMIN_PATH.'/admin.tail.php');
include_once (G5_ADMIN_PATH.'/admin.tail.php');
+27 -1
View File
@@ -365,6 +365,32 @@ $it_explan = isset($_POST['it_explan']) ? $_POST['it_explan'] : '';
if ($it_name == "")
alert("상품명을 입력해 주십시오.");
// 스킨 경로 검증
$it_skin = isset($_POST['it_skin']) ? strip_tags(clean_xss_attributes($_POST['it_skin'])) : '';
$it_mobile_skin = isset($_POST['it_mobile_skin']) ? strip_tags(clean_xss_attributes($_POST['it_mobile_skin'])) : '';
$check_files = array();
if( !empty($it_skin) ) $check_files[] = $it_skin;
if( !empty($it_mobile_skin) ) $check_files[] = $it_mobile_skin;
foreach( $check_files as $file ){
if( empty($file) ) continue;
if( preg_match('#\.+(\/|\\\)#', $file) ){
alert('스킨파일명에 포함될수 없는 문자가 들어있습니다.');
}
if( ! is_include_path_check($file, 1) ){
alert('오류 : 데이터폴더가 포함된 path 또는 잘못된 path 를 포함할수 없습니다.');
}
$file_ext = pathinfo($file, PATHINFO_EXTENSION);
if( ! $file_ext || ! in_array($file_ext, array('php', 'htm', 'html')) || ! preg_match('/^.*\.(php|htm|html)$/i', $file) ) {
alert('스킨 파일 경로의 확장자는 php, htm, html 만 허용합니다.');
}
}
$sql_common = " ca_id = '$ca_id',
ca_id2 = '$ca_id2',
ca_id3 = '$ca_id3',
@@ -487,7 +513,7 @@ else if ($w == "d")
and b.ca_mb_id = '{$member['mb_id']}' ";
$row = sql_fetch($sql);
if (!$row['it_id'])
alert("\'{$member['mb_id']}\' 님께서 삭제 할 권한이 없는 상품입니다.");
alert("'{$member['mb_id']}' 님께서 삭제 할 권한이 없는 상품입니다.");
}
itemdelete($it_id);
+11 -11
View File
@@ -30,17 +30,17 @@ if(! function_exists('column_char')) {
$rows = array();
for($i=1; $row=sql_fetch_array($result); $i++) {
$rows[] =
array(' '.$row['od_id'],
$row['od_name'],
' '.$row['od_tel'],
' '.$row['od_hp'],
$row['od_b_name'],
' '.$row['od_b_tel'],
' '.$row['od_b_hp'],
print_address($row['od_b_addr1'], $row['od_b_addr2'], $row['od_b_addr3'], $row['od_b_addr_jibeon']),
$row['od_delivery_company'],
$row['od_invoice']);
$rows[] =
array(' '.$row['od_id'],
function_exists('csv_safe_cell') ? csv_safe_cell($row['od_name']) : $row['od_name'],
' '.$row['od_tel'],
' '.$row['od_hp'],
function_exists('csv_safe_cell') ? csv_safe_cell($row['od_b_name']) : $row['od_b_name'],
' '.$row['od_b_tel'],
' '.$row['od_b_hp'],
function_exists('csv_safe_cell') ? csv_safe_cell(print_address($row['od_b_addr1'], $row['od_b_addr2'], $row['od_b_addr3'], $row['od_b_addr_jibeon'])) : print_address($row['od_b_addr1'], $row['od_b_addr2'], $row['od_b_addr3'], $row['od_b_addr_jibeon']),
function_exists('csv_safe_cell') ? csv_safe_cell($row['od_delivery_company']) : $row['od_delivery_company'],
function_exists('csv_safe_cell') ? csv_safe_cell($row['od_invoice']) : $row['od_invoice']);
}
$data = array_merge(array($headers), $rows);
+2
View File
@@ -6,6 +6,8 @@ include_once(G5_LIB_PATH.'/mailer.lib.php');
auth_check_menu($auth, $sub_menu, "w");
check_admin_token();
define("_ORDERMAIL_", true);
$sms_count = 0;
+2 -2
View File
@@ -382,8 +382,8 @@ add_javascript(G5_POSTCODE_JS, 0); //다음 주소 js
<input type="hidden" name="sel_field" value="<?php echo $sel_field; ?>">
<input type="hidden" name="search" value="<?php echo $search; ?>">
<input type="hidden" name="page" value="<?php echo $page; ?>">
<input type="hidden" name="od_name" value="<?php echo $od['od_name']; ?>">
<input type="hidden" name="od_hp" value="<?php echo $od['od_hp']; ?>">
<input type="hidden" name="od_name" value="<?php echo get_text($od['od_name']); ?>">
<input type="hidden" name="od_hp" value="<?php echo get_text($od['od_hp']); ?>">
<input type="hidden" name="od_tno" value="<?php echo $od['od_tno']; ?>">
<input type="hidden" name="od_escrow" value="<?php echo $od['od_escrow']; ?>">
<input type="hidden" name="od_pg" value="<?php echo $od['od_pg']; ?>">
+2
View File
@@ -4,6 +4,8 @@ include_once('./_common.php');
auth_check_menu($auth, $sub_menu, "w");
check_admin_token();
$tax_mny = isset($_POST['mod_tax_mny']) ? preg_replace('/[^0-9]/', '', $_POST['mod_tax_mny']) : 0;
$free_mny = isset($_POST['mod_free_mny']) ? preg_replace('/[^0-9]/', '', $_POST['mod_free_mny']) : 0;
+14 -14
View File
@@ -118,21 +118,21 @@ if ($csv == 'csv')
}
echo '"\''.$row['od_b_zip1'].$row['od_b_zip2'].'"\''.',';
echo '"'.$pull_address.'"'.',';
echo '"'.$row['od_b_name'].'"'.',';
echo '"'.(function_exists('csv_safe_cell') ? csv_safe_cell($pull_address) : $pull_address).'"'.',';
echo '"'.(function_exists('csv_safe_cell') ? csv_safe_cell($row['od_b_name']) : $row['od_b_name']).'"'.',';
//echo '"'.multibyte_digit((string)$row[od_b_tel]).'"'.',';
//echo '"'.multibyte_digit((string)$row[od_b_hp]).'"'.',';
echo '"'.conv_telno($row['od_b_tel']) . '"'.',';
echo '"'.conv_telno($row['od_b_hp']) . '"'.',';
echo '"'.preg_replace("/\"/", "&#034;", $row['it_name']) . '"'.',';
echo '"'.(function_exists('csv_safe_cell') ? csv_safe_cell(preg_replace("/\"/", "&#034;", $row['it_name'])) : preg_replace("/\"/", "&#034;", $row['it_name'])) . '"'.',';
echo '"'.$row['ct_qty'].'"'.',';
echo '"'.$row['ct_option'].'"'.',';
echo '"'.(function_exists('csv_safe_cell') ? csv_safe_cell($row['ct_option']) : $row['ct_option']).'"'.',';
echo '"'.$ct_send_cost.'"'.',';
echo '"\''.$row['it_id'].'\'"'.',';
echo '"\''.$row['od_id'].'\'"'.',';
echo '"'.$row['od_invoice'].'"'.',';
echo '"'.(function_exists('csv_safe_cell') ? csv_safe_cell($row['od_invoice']) : $row['od_invoice']).'"'.',';
//echo '"'.preg_replace("/\"/", "&#034;", preg_replace("/\n/", "", $row[od_memo])).'"';
echo '"'.preg_replace("/\"/", "&#034;", $row['od_memo']).'"';
echo '"'.(function_exists('csv_safe_cell') ? csv_safe_cell(preg_replace("/\"/", "&#034;", $row['od_memo'])) : preg_replace("/\"/", "&#034;", $row['od_memo'])).'"';
echo "\n";
}
if ($i == 0)
@@ -217,18 +217,18 @@ if ($csv == 'xls')
}
$rows[] = array(' '.$row['od_b_zip1'].$row['od_b_zip2'],
$pull_address,
$row['od_b_name'],
' '.conv_telno($row['od_b_tel']),
' '.conv_telno($row['od_b_hp']),
preg_replace("/\"/", "&#034;", $row['it_name']),
' '.$row['ct_qty'],
$row['ct_option'],
function_exists('csv_safe_cell') ? csv_safe_cell($pull_address) : $pull_address,
function_exists('csv_safe_cell') ? csv_safe_cell($row['od_b_name']) : $row['od_b_name'],
' '.conv_telno($row['od_b_tel']),
' '.conv_telno($row['od_b_hp']),
function_exists('csv_safe_cell') ? csv_safe_cell(preg_replace("/\"/", "&#034;", $row['it_name'])) : preg_replace("/\"/", "&#034;", $row['it_name']),
' '.$row['ct_qty'],
function_exists('csv_safe_cell') ? csv_safe_cell($row['ct_option']) : $row['ct_option'],
$ct_send_cost,
' '.$row['it_id'],
' '.$row['od_id'],
' '.$row['od_invoice'],
preg_replace("/\"/", "&#034;", $row['od_memo']));
function_exists('csv_safe_cell') ? csv_safe_cell(preg_replace("/\"/", "&#034;", $row['od_memo'])) : preg_replace("/\"/", "&#034;", $row['od_memo']));
}
$data = array_merge(array($headers), $rows);
+1 -1
View File
@@ -87,7 +87,7 @@ $result = sql_query($sql);
?>
<tr>
<td class="td_alignc"><a href="./orderform.php?od_id=<?php echo $row['od_id']; ?>"><?php echo $row['od_id']; ?></a></td>
<td class="td_name"><?php echo $href; ?><?php echo $row['od_name']; ?></a></td>
<td class="td_name"><?php echo $href; ?><?php echo get_text($row['od_name']); ?></a></td>
<td class="td_numsum"><?php echo number_format($row['orderprice']); ?></td>
<td class="td_numincome"><?php echo number_format($row['couponprice']); ?></td>
<td class="td_numincome"><?php echo number_format($receipt_bank); ?></td>
+1 -1
View File
@@ -65,7 +65,7 @@ function book_all_checked(chk)
function book_del(fo_no)
{
if (confirm("한번 삭제한 자료는 복구할 방법이 없습니다.\n\n그래도 삭제하시겠습니까?"))
location.href = "./form_update.php?w=d&fo_no=" + fo_no + "&page=<?php echo $page?>&fg_no=<?php echo $fg_no?>&st=<?php echo get_text($st); ?>&sv=<?php echo get_text($sv); ?>";
location.href = "./form_update.php?w=d&fo_no=" + fo_no + "&page=<?php echo $page?>&fg_no=<?php echo $fg_no?>&st=<?php echo get_text($st); ?>&sv=<?php echo get_text($sv); ?>&token=<?php echo $token; ?>";
}
function multi_update(sel)
+2
View File
@@ -4,6 +4,8 @@ include_once("./_common.php");
auth_check_menu($auth, $sub_menu, "w");
check_admin_token();
$fo_name = isset($_REQUEST['fo_name']) ? strip_tags(clean_xss_attributes($_REQUEST['fo_name'])) : '';
$fo_content = isset($_REQUEST['fo_content']) ? strip_tags(clean_xss_attributes($_REQUEST['fo_content'])) : '';
$fo_receipt = isset($_REQUEST['fo_receipt']) ? clean_xss_tags($_REQUEST['fo_receipt'], 1, 1) : '';
+3
View File
@@ -4,6 +4,8 @@ include_once("./_common.php");
auth_check_menu($auth, $sub_menu, "w");
$token = get_token();
$g5['title'] = "이모티콘 ";
$fo_no = isset($_REQUEST['fo_no']) ? (int) $_REQUEST['fo_no'] : 0;
@@ -34,6 +36,7 @@ include_once(G5_ADMIN_PATH.'/admin.head.php');
<input type="hidden" name="page" value="<?php echo $page?>">
<input type="hidden" name="fo_no" value="<?php echo $write['fo_no']; ?>">
<input type="hidden" name="get_fg_no" value="<?php echo $fg_no?>">
<input type="hidden" name="token" value="<?php echo $token; ?>">
<div class="tbl_frm01 tbl_wrap">
<table>
+7 -6
View File
@@ -161,11 +161,12 @@ function all_send()
if( $write['wr_memo'] ){
$tmp_wr_memo = @unserialize($write['wr_memo']);
if( count($tmp_wr_memo) && is_array($tmp_wr_memo) ){
if(function_exists('array_fill_keys')){
$tmp_wr_hp = array_replace($tmp_wr_memo['hp'],array_fill_keys(array_keys($tmp_wr_memo['hp'], null),''));
} else {
$tmp_wr_hp = $tmp_wr_memo['hp'];
}
$tmp_wr_hp = $tmp_wr_memo['hp'];
if (is_array($tmp_wr_hp)) {
foreach (array_keys($tmp_wr_hp, null) as $empty_key) {
$tmp_wr_hp[$empty_key] = '';
}
}
$arr_wr_memo = @array_count_values( $tmp_wr_hp );
?>
<h2>중복번호 <?php echo $tmp_wr_memo['total'];?>건</h2>
@@ -265,4 +266,4 @@ function all_send()
<?php echo sms5_sub_paging(G5_IS_MOBILE ? $config['cf_mobile_pages'] : $config['cf_write_pages'], $spage, $total_spage, $_SERVER['SCRIPT_NAME']."?wr_no=$wr_no&amp;wr_renum=$wr_renum&amp;page=$page&amp;st=$st&amp;sv=$sv&amp;sst=$sst&amp;ssv=$ssv", "", "spage"); ?>
<?php
include_once(G5_ADMIN_PATH.'/admin.tail.php');
include_once(G5_ADMIN_PATH.'/admin.tail.php');
+30 -12
View File
@@ -37,21 +37,39 @@ include_once(G5_ADMIN_PATH.'/admin.head.php');
$( "#mb_update_form" ).submit(function( e ) {
e.preventDefault();
$("#res_msg").html('업데이트 중입니다. 잠시만 기다려 주십시오...');
var params = { mtype : 'json' };
var action = $(this).attr("action");
$.ajax({
url: $(this).attr("action"),
cache:false,
timeout : 30000,
dataType:"json",
data:params,
success: function(data) {
if(data.error){
alert( data.error );
url: '<?php echo G5_ADMIN_URL; ?>/ajax.token.php',
type: 'POST',
dataType: 'json',
data: { admin_csrf_token_key: '<?php echo admin_csrf_token_key(1); ?>' },
success: function(tokenData) {
if(tokenData.error){
alert(tokenData.error);
$("#res_msg").html("");
} else {
$("#datetime").html( data.datetime );
$("#res_msg").html( data.res_msg );
return;
}
$.ajax({
url: action,
type: 'POST',
cache:false,
timeout : 30000,
dataType:"json",
data: { mtype : 'json', token : tokenData.token },
success: function(data) {
if(data.error){
alert( data.error );
$("#res_msg").html("");
} else {
$("#datetime").html( data.datetime );
$("#res_msg").html( data.res_msg );
}
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
});
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
+2
View File
@@ -26,6 +26,8 @@ if( $mtype == "json" ){
auth_check_menu($auth, $sub_menu, "w");
}
check_admin_token();
$count = 0;
$hp_yes = 0;
$hp_no = 0;
+1 -1
View File
@@ -46,7 +46,7 @@ for($i=1; $res=sql_fetch_array($qry); $i++)
if ($no_hp && $res['bk_hp'] != '' && !$hp) continue;
$rows[] = array($res['bk_name'], ' '.$hp);
$rows[] = array(function_exists('csv_safe_cell') ? csv_safe_cell($res['bk_name']) : $res['bk_name'], ' '.$hp);
}
$data = array_merge(array($headers), $rows);
+121 -116
View File
@@ -1,116 +1,121 @@
<?php
global $lo_location;
global $lo_url;
include_once('./_common.php');
if($error) {
$g5['title'] = "오류안내 페이지";
} else {
$g5['title'] = "결과안내 페이지";
}
include_once(G5_PATH.'/head.sub.php');
// 필수 입력입니다.
// 양쪽 공백 없애기
// 필수 (선택 혹은 입력)입니다.
// 전화번호 형식이 올바르지 않습니다. 하이픈(-)을 포함하여 입력하세요.
// 이메일주소 형식이 아닙니다.
// 한글이 아닙니다. (자음, 모음만 있는 한글은 처리하지 않습니다.)
// 한글이 아닙니다.
// 한글, 영문, 숫자가 아닙니다.
// 한글, 영문이 아닙니다.
// 숫자가 아닙니다.
// 영문이 아닙니다.
// 영문 또는 숫자가 아닙니다.
// 영문, 숫자, _ 가 아닙니다.
// 최소 글자 이상 입력하세요.
// 이미지 파일이 아닙니다..gif .jpg .png 파일만 가능합니다.
// 파일만 가능합니다.
// 공백이 없어야 합니다.
$msg = isset($msg) ? strip_tags($msg) : '';
$msg2 = str_replace("\\n", "<br>", $msg);
$url = isset($url) ? clean_xss_tags($url, 1) : '';
if (!$url) $url = isset($_SERVER['HTTP_REFERER']) ? clean_xss_tags($_SERVER['HTTP_REFERER'], 1) : '';
$url = preg_replace("/[\<\>\'\"\\\'\\\"\(\)]/", "", $url);
$url = preg_replace('/\r\n|\r|\n|[^\x20-\x7e]/','', $url);
// url 체크
check_url_host($url, $msg);
if($error) {
$header2 = "다음 항목에 오류가 있습니다.";
} else {
$header2 = "다음 내용을 확인해 주세요.";
}
?>
<script>
alert("<?php echo $msg; ?>");
<?php if ($url) { ?>
document.location.replace("<?php echo str_replace('&amp;', '&', $url); ?>");
<?php } else { ?>
history.back();
<?php } ?>
</script>
<noscript>
<div id="validation_check">
<h1><?php echo $header2 ?></h1>
<p class="cbg">
<?php echo $msg2 ?>
</p>
<?php if($post) { ?>
<form method="post" action="<?php echo $url ?>">
<?php
foreach($_POST as $key => $value) {
$key = clean_xss_tags($key);
$value = clean_xss_tags($value);
if(strlen($value) < 1)
continue;
if(preg_match("/pass|pwd|capt|url/", $key))
continue;
?>
<input type="hidden" name="<?php echo htmlspecialchars($key); ?>" value="<?php echo htmlspecialchars($value); ?>">
<?php
}
?>
<input type="submit" value="돌아가기">
</form>
<?php } else { ?>
<div class="btn_confirm">
<a href="<?php echo $url ?>">돌아가기</a>
</div>
<?php } ?>
<?php /*
<article id="validation_check">
<header>
<hgroup>
<!-- <h1>회원가입 정보 입력 확인</h1> --> <!-- 수행 중이던 작업 내용 -->
<h1><?php echo $header ?></h1> <!-- 수행 중이던 작업 내용 -->
<h2><?php echo $header2 ?></h2>
</hgroup>
</header>
<p>
<!-- <strong>항목</strong> 오류내역 -->
<!--
<strong>이름</strong> 필수 입력입니다. 한글만 입력할 수 있습니다.<br>
<strong>이메일</strong> 올바르게 입력하지 않았습니다.<br>
-->
<?php echo $msg2 ?>
</p>
<a href="<?php echo $url ?>">돌아가기</a>
</article>
*/ ?>
</div>
</noscript>
<?php
include_once(G5_PATH.'/tail.sub.php');
<?php
global $lo_location;
global $lo_url;
include_once('./_common.php');
if($error) {
$g5['title'] = "오류안내 페이지";
} else {
$g5['title'] = "결과안내 페이지";
}
include_once(G5_PATH.'/head.sub.php');
// 필수 입력입니다.
// 양쪽 공백 없애기
// 필수 (선택 혹은 입력)입니다.
// 전화번호 형식이 올바르지 않습니다. 하이픈(-)을 포함하여 입력하세요.
// 이메일주소 형식이 아닙니다.
// 한글이 아닙니다. (자음, 모음만 있는 한글은 처리하지 않습니다.)
// 한글이 아닙니다.
// 한글, 영문, 숫자가 아닙니다.
// 한글, 영문이 아닙니다.
// 숫자가 아닙니다.
// 영문이 아닙니다.
// 영문 또는 숫자가 아닙니다.
// 영문, 숫자, _ 가 아닙니다.
// 최소 글자 이상 입력하세요.
// 이미지 파일이 아닙니다..gif .jpg .png 파일만 가능합니다.
// 파일만 가능합니다.
// 공백이 없어야 합니다.
$msg = isset($msg) ? strip_tags($msg) : '';
$msg2 = str_replace(array("\\r\\n", "\\n", "\\r"), "<br>", $msg);
$alert_msg = str_replace(array("\\r\\n", "\\n", "\\r"), "\n", $msg);
$url = isset($url) ? clean_xss_tags($url, 1) : '';
if (!$url) $url = isset($_SERVER['HTTP_REFERER']) ? clean_xss_tags($_SERVER['HTTP_REFERER'], 1) : '';
$url = preg_replace("/[\<\>\'\"\\\'\\\"\(\)]/", "", $url);
$url = preg_replace('/\r\n|\r|\n|[^\x20-\x7e]/','', $url);
// url 체크
check_url_host($url, $msg);
$alert_url = str_replace('&amp;', '&', $url);
$js_replace = array('\\' => '\\\\', '"' => '\\"', "'" => '\\u0027', '/' => '\\/', "\r" => '\\r', "\n" => '\\n', "\t" => '\\t', '<' => '\\u003C', '>' => '\\u003E', '&' => '\\u0026', "\xE2\x80\xA8" => '\\u2028', "\xE2\x80\xA9" => '\\u2029');
$js_alert_msg = function_exists('get_js_safe_string') ? get_js_safe_string($alert_msg) : '"'.strtr((string)$alert_msg, $js_replace).'"';
$js_alert_url = function_exists('get_js_safe_string') ? get_js_safe_string($alert_url) : '"'.strtr((string)$alert_url, $js_replace).'"';
if($error) {
$header2 = "다음 항목에 오류가 있습니다.";
} else {
$header2 = "다음 내용을 확인해 주세요.";
}
?>
<script>
alert(<?php echo $js_alert_msg; ?>);
<?php if ($url) { ?>
document.location.replace(<?php echo $js_alert_url; ?>);
<?php } else { ?>
history.back();
<?php } ?>
</script>
<noscript>
<div id="validation_check">
<h1><?php echo $header2 ?></h1>
<p class="cbg">
<?php echo $msg2 ?>
</p>
<?php if($post) { ?>
<form method="post" action="<?php echo $url ?>">
<?php
foreach($_POST as $key => $value) {
$key = clean_xss_tags($key);
$value = clean_xss_tags($value);
if(strlen($value) < 1)
continue;
if(preg_match("/pass|pwd|capt|url/", $key))
continue;
?>
<input type="hidden" name="<?php echo htmlspecialchars($key); ?>" value="<?php echo htmlspecialchars($value); ?>">
<?php
}
?>
<input type="submit" value="돌아가기">
</form>
<?php } else { ?>
<div class="btn_confirm">
<a href="<?php echo $url ?>">돌아가기</a>
</div>
<?php } ?>
<?php /*
<article id="validation_check">
<header>
<hgroup>
<!-- <h1>회원가입 정보 입력 확인</h1> --> <!-- 수행 중이던 작업 내용 -->
<h1><?php echo $header ?></h1> <!-- 수행 중이던 작업 내용 -->
<h2><?php echo $header2 ?></h2>
</hgroup>
</header>
<p>
<!-- <strong>항목</strong> 오류내역 -->
<!--
<strong>이름</strong> 필수 입력입니다. 한글만 입력할 수 있습니다.<br>
<strong>이메일</strong> 올바르게 입력하지 않았습니다.<br>
-->
<?php echo $msg2 ?>
</p>
<a href="<?php echo $url ?>">돌아가기</a>
</article>
*/ ?>
</div>
</noscript>
<?php
include_once(G5_PATH.'/tail.sub.php');
+6 -3
View File
@@ -4,7 +4,10 @@ include_once(G5_PATH.'/head.sub.php');
$msg = isset($msg) ? strip_tags($msg) : '';
$msg2 = str_replace("\\n", "<br>", $msg);
$msg2 = str_replace(array("\\r\\n", "\\n", "\\r"), "<br>", $msg);
$alert_msg = str_replace(array("\\r\\n", "\\n", "\\r"), "\n", $msg);
$js_replace = array('\\' => '\\\\', '"' => '\\"', "'" => '\\u0027', '/' => '\\/', "\r" => '\\r', "\n" => '\\n', "\t" => '\\t', '<' => '\\u003C', '>' => '\\u003E', '&' => '\\u0026', "\xE2\x80\xA8" => '\\u2028', "\xE2\x80\xA9" => '\\u2029');
$js_alert_msg = function_exists('get_js_safe_string') ? get_js_safe_string($alert_msg) : '"'.strtr((string)$alert_msg, $js_replace).'"';
if($error) {
$header2 = "다음 항목에 오류가 있습니다.";
@@ -16,7 +19,7 @@ if($error) {
?>
<script>
alert("<?php echo $msg; ?>");
alert(<?php echo $js_alert_msg; ?>);
try {
window.close();
} catch(error) {
@@ -69,4 +72,4 @@ setTimeout(function() {
</noscript>
<?php
include_once(G5_PATH.'/tail.sub.php');
include_once(G5_PATH.'/tail.sub.php');
+2 -2
View File
@@ -7,7 +7,7 @@ $count = (isset($_POST['chk_wr_id']) && is_array($_POST['chk_wr_id'])) ? count($
$post_btn_submit = isset($_POST['btn_submit']) ? clean_xss_tags($_POST['btn_submit'], 1, 1) : '';
if(!$count) {
alert(addcslashes($post_btn_submit, '"\\/').' 하실 항목을 하나 이상 선택하세요.');
alert($post_btn_submit.' 하실 항목을 하나 이상 선택하세요.');
}
if($post_btn_submit === '선택삭제') {
@@ -20,4 +20,4 @@ if($post_btn_submit === '선택삭제') {
include './move.php';
} else {
alert('올바른 방법으로 이용해 주세요.');
}
}
+10 -4
View File
@@ -14,6 +14,12 @@ $url3 = preg_replace($pattern2, "", $url3);
$msg = isset($msg) ? $msg : '';
$header = isset($header) ? $msg : '';
$confirm_msg = str_replace(array('<br>', '<br/>', '<br />'), "\n", $msg);
$confirm_msg = strip_tags($confirm_msg);
$js_replace = array('\\' => '\\\\', '"' => '\\"', "'" => '\\u0027', '/' => '\\/', "\r" => '\\r', "\n" => '\\n', "\t" => '\\t', '<' => '\\u003C', '>' => '\\u003E', '&' => '\\u0026', "\xE2\x80\xA8" => '\\u2028', "\xE2\x80\xA9" => '\\u2029');
$js_confirm_msg = function_exists('get_js_safe_string') ? get_js_safe_string($confirm_msg) : '"'.strtr((string)$confirm_msg, $js_replace).'"';
$js_url1 = function_exists('get_js_safe_string') ? get_js_safe_string($url1) : '"'.strtr((string)$url1, $js_replace).'"';
$js_url2 = function_exists('get_js_safe_string') ? get_js_safe_string($url2) : '"'.strtr((string)$url2, $js_replace).'"';
// url 체크
check_url_host($url1);
@@ -22,11 +28,11 @@ check_url_host($url3);
?>
<script>
var conf = "<?php echo strip_tags($msg); ?>";
var conf = <?php echo $js_confirm_msg; ?>;
if (confirm(conf)) {
document.location.replace("<?php echo $url1; ?>");
document.location.replace(<?php echo $js_url1; ?>);
} else {
document.location.replace("<?php echo $url2; ?>");
document.location.replace(<?php echo $js_url2; ?>);
}
</script>
@@ -49,4 +55,4 @@ if (confirm(conf)) {
</noscript>
<?php
include_once(G5_PATH.'/tail.sub.php');
include_once(G5_PATH.'/tail.sub.php');
+2 -2
View File
@@ -3,7 +3,7 @@ include_once('./_common.php');
include_once(G5_CAPTCHA_PATH.'/captcha.lib.php');
if (!$config['cf_email_use'])
alert_close('환경설정에서 \"메일발송 사용\"에 체크하셔야 메일을 발송할 수 있습니다.\\n\\n관리자에게 문의하시기 바랍니다.');
alert_close('환경설정에서 "메일발송 사용"에 체크하셔야 메일을 발송할 수 있습니다.\\n\\n관리자에게 문의하시기 바랍니다.');
if (!$is_member && $config['cf_formmail_is_member'])
alert_close('회원만 이용하실 수 있습니다.');
@@ -52,4 +52,4 @@ $type_checked[$type] = 'checked';
include_once($member_skin_path.'/formmail.skin.php');
include_once(G5_PATH.'/tail.sub.php');
include_once(G5_PATH.'/tail.sub.php');
+10 -1
View File
@@ -170,7 +170,13 @@ $td_width = (int)(100 / $bo_gallery_cols);
// 인덱스 필드가 아니면 정렬에 사용하지 않음
//if (!$sst || ($sst && !(strstr($sst, 'wr_id') || strstr($sst, "wr_datetime")))) {
if (!$sst) {
if ($board['bo_sort_field']) {
$bo_allowed_sort_field = array();
if (function_exists('get_board_sort_fields')) {
foreach (get_board_sort_fields($board) as $bo_sort_v) {
$bo_allowed_sort_field[] = $bo_sort_v[0];
}
}
if ($board['bo_sort_field'] && in_array($board['bo_sort_field'], $bo_allowed_sort_field, true)) {
$sst = $board['bo_sort_field'];
} else {
$sst = "wr_num, wr_reply";
@@ -191,6 +197,9 @@ if (!$sst) {
if(!$sst)
$sst = "wr_num, wr_reply";
// 정렬 방향 화이트리스트
$sod = preg_match("/^(asc|desc)$/i", $sod) ? $sod : '';
if ($sst) {
$sql_order = " order by {$sst} {$sod} ";
}
+6 -1
View File
@@ -87,4 +87,9 @@ run_event('cert_refresh_update_after', $mb_id);
//===============================================================
(empty($url))? goto_url(G5_URL) : goto_url($url);
if ($url) {
check_url_host($url, '', G5_URL, true);
goto_url($url);
} else {
goto_url(G5_URL);
}
+15
View File
@@ -41,6 +41,21 @@ while ($row = sql_fetch_array($result))
// 존재하지 않다면
if( !$move_board['bo_table'] ) continue;
// 대상 게시판에 대한 권한 재검증 (KVE-2026-0795)
// 원본 게시판 기준의 $is_admin 만으로는 타 게시판 이동/복사가 허용되지 않도록 함.
if ($is_admin !== 'super') {
$is_target_admin = false;
if ($is_admin === 'board' && isset($move_board['bo_admin']) && $move_board['bo_admin'] !== '' && $move_board['bo_admin'] === $member['mb_id']) {
$is_target_admin = true;
} else if ($is_admin === 'group' && isset($move_board['gr_id']) && $move_board['gr_id'] !== '') {
$move_group = sql_fetch(" select gr_admin from {$g5['group_table']} where gr_id = '".sql_real_escape_string($move_board['gr_id'])."' ");
if (!empty($move_group['gr_admin']) && $move_group['gr_admin'] === $member['mb_id']) {
$is_target_admin = true;
}
}
if (!$is_target_admin) continue;
}
$move_write_table = $g5['write_prefix'] . $move_bo_table;
$src_dir = G5_DATA_PATH.'/file/'.$bo_table; // 원본 디렉토리
+2 -2
View File
@@ -38,10 +38,10 @@ if ($is_member) {
sql_query($sql);
if (get_sql_affected_rows() <= 0) {
alert(addcslashes($po['po_subject'], '"\\/').'에 이미 참여하셨습니다.', $result_url);
alert($po['po_subject'].'에 이미 참여하셨습니다.', $result_url);
}
insert_point($member['mb_id'], $po['po_point'], $po['po_id'] . '. ' . cut_str($po['po_subject'],20) . ' 투표 참여 ', '@poll', $po['po_id'], '투표');
//goto_url($g5['bbs_url'].'/poll_result.php?po_id='.$po_id.'&amp;skin_dir='.$skin_dir);
goto_url($result_url);
goto_url($result_url);
+4 -4
View File
@@ -174,11 +174,11 @@ for ($i=1; $i<=$upload_count; $i++) {
// 서버에 설정된 값보다 큰파일을 업로드 한다면
if ($filename) {
if ($_FILES['bf_file']['error'][$i] == 1) {
$file_upload_msg .= '\"'.$filename.'\" 파일의 용량이 서버에 설정('.$upload_max_filesize.')된 값보다 크므로 업로드 할 수 없습니다.\\n';
$file_upload_msg .= '"'.$filename.'" 파일의 용량이 서버에 설정('.$upload_max_filesize.')된 값보다 크므로 업로드 할 수 없습니다.\\n';
continue;
}
else if ($_FILES['bf_file']['error'][$i] != 0) {
$file_upload_msg .= '\"'.$filename.'\" 파일이 정상적으로 업로드 되지 않았습니다.\\n';
$file_upload_msg .= '"'.$filename.'" 파일이 정상적으로 업로드 되지 않았습니다.\\n';
continue;
}
}
@@ -186,7 +186,7 @@ for ($i=1; $i<=$upload_count; $i++) {
if (is_uploaded_file($tmp_file)) {
// 관리자가 아니면서 설정한 업로드 사이즈보다 크다면 건너뜀
if (!$is_admin && $filesize > $qaconfig['qa_upload_size']) {
$file_upload_msg .= '\"'.$filename.'\" 파일의 용량('.number_format($filesize).' 바이트)이 게시판에 설정('.number_format($qaconfig['qa_upload_size']).' 바이트)된 값보다 크므로 업로드 하지 않습니다.\\n';
$file_upload_msg .= '"'.$filename.'" 파일의 용량('.number_format($filesize).' 바이트)이 게시판에 설정('.number_format($qaconfig['qa_upload_size']).' 바이트)된 값보다 크므로 업로드 하지 않습니다.\\n';
continue;
}
@@ -482,4 +482,4 @@ else
if ($file_upload_msg)
alert($file_upload_msg, $result_url);
else
goto_url($result_url);
goto_url($result_url);
+10 -1
View File
@@ -150,6 +150,15 @@ $hp_readonly = (($config['cf_cert_use'] && $config['cf_cert_req']) && ($config['
$agree = isset($_REQUEST['agree']) ? preg_replace('#[^0-9]#', '', $_REQUEST['agree']) : '';
$agree2 = isset($_REQUEST['agree2']) ? preg_replace('#[^0-9]#', '', $_REQUEST['agree2']) : '';
$member['mb_marketing_agree'] = isset($member['mb_marketing_agree']) ? $member['mb_marketing_agree'] : 0;
$member['mb_marketing_date'] = isset($member['mb_marketing_date']) ? $member['mb_marketing_date'] : '0000-00-00 00:00:00';
$member['mb_thirdparty_agree'] = isset($member['mb_thirdparty_agree']) ? $member['mb_thirdparty_agree'] : 0;
$member['mb_thirdparty_date'] = isset($member['mb_thirdparty_date']) ? $member['mb_thirdparty_date'] : '0000-00-00 00:00:00';
$member['mb_mailling'] = isset($member['mb_mailling']) ? $member['mb_mailling'] : 0;
$member['mb_mailling_date'] = isset($member['mb_mailling_date']) ? $member['mb_mailling_date'] : '0000-00-00 00:00:00';
$member['mb_sms'] = isset($member['mb_sms']) ? $member['mb_sms'] : 0;
$member['mb_sms_date'] = isset($member['mb_sms_date']) ? $member['mb_sms_date'] : '0000-00-00 00:00:00';
// add_javascript('js 구문', 출력순서); 숫자가 작을 수록 먼저 출력됨
if ($config['cf_use_addr'])
add_javascript(G5_POSTCODE_JS, 0); //다음 주소 js
@@ -158,4 +167,4 @@ include_once($member_skin_path.'/register_form.skin.php');
run_event('register_form_after', $w, $agree, $agree2);
include_once('./_tail.php');
include_once('./_tail.php');
+9 -6
View File
@@ -72,7 +72,7 @@ $mb_zip2 = preg_replace('/[^0-9]/', '', $mb_zip2);
$mb_addr1 = addslashes(clean_xss_tags(stripslashes($mb_addr1), 1, 1));
$mb_addr2 = addslashes(clean_xss_tags(stripslashes($mb_addr2), 1, 1));
$mb_addr3 = addslashes(clean_xss_tags(stripslashes($mb_addr3), 1, 1));
$mb_addr_jibeon = preg_match("/^(N|R)$/", $mb_addr_jibeon) ? $mb_addr_jibeon : '';
$mb_addr_jibeon = preg_match("/^(N|R|J)$/", $mb_addr_jibeon) ? $mb_addr_jibeon : '';
$mb_marketing_agree = isset($_POST['mb_marketing_agree']) ? trim($_POST['mb_marketing_agree']) : "0";
$mb_thirdparty_agree = isset($_POST['mb_thirdparty_agree']) ? trim($_POST['mb_thirdparty_agree']) : "0";
@@ -275,7 +275,7 @@ if ($w == '') {
if (!$config['cf_use_email_certify'])
$sql .= " , mb_email_certify = '".G5_TIME_YMDHIS."' ";
$agree_items = [];
$agree_items = array();
// 마케팅 목적의 개인정보 수집 및 이용
if ($mb_marketing_agree == 1) {
$sql .= " , mb_marketing_date = '".G5_TIME_YMDHIS."' ";
@@ -396,7 +396,7 @@ if ($w == '') {
if ($old_email != $mb_email && $config['cf_use_email_certify'])
$sql_email_certify = " , mb_email_certify = '' ";
$agree_items = [];
$agree_items = array();
// 마케팅 목적의 개인정보 수집 및 이용
$sql_marketing_date = "";
@@ -678,8 +678,11 @@ if(isset($_SESSION['ss_cert_hash'])) unset($_SESSION['ss_cert_hash']);
if(isset($_SESSION['ss_cert_birth'])) unset($_SESSION['ss_cert_birth']);
if(isset($_SESSION['ss_cert_adult'])) unset($_SESSION['ss_cert_adult']);
if ($msg)
echo '<script>alert(\''.$msg.'\');</script>';
if ($msg) {
$js_replace = array('\\' => '\\\\', '"' => '\\"', "'" => '\\u0027', '/' => '\\/', "\r" => '\\r', "\n" => '\\n', "\t" => '\\t', '<' => '\\u003C', '>' => '\\u003E', '&' => '\\u0026', "\xE2\x80\xA8" => '\\u2028', "\xE2\x80\xA9" => '\\u2029');
$js_msg = function_exists('get_js_safe_string') ? get_js_safe_string($msg) : '"'.strtr((string)$msg, $js_replace).'"';
echo '<script>alert('.$js_msg.');</script>';
}
run_event('register_form_update_after', $mb_id, $w);
@@ -713,4 +716,4 @@ if ($w == '') {
</body>
</html>';
}
}
}
+21 -9
View File
@@ -3,6 +3,8 @@ include_once('./_common.php');
// 특수문자 변환
function specialchars_replace($str, $len=0) {
$str = (string)$str;
if ($len) {
$str = substr($str, 0, $len);
}
@@ -18,19 +20,29 @@ function specialchars_replace($str, $len=0) {
return $str;
}
if (!isset($bo_table) || !$bo_table) {
echo '존재하지 않는 게시판입니다.';
exit;
}
$sql = " select gr_id, bo_subject, bo_page_rows, bo_read_level, bo_use_rss_view from {$g5['board_table']} where bo_table = '$bo_table' ";
$row = sql_fetch($sql);
$subj2 = specialchars_replace($row['bo_subject'], 255);
$lines = $row['bo_page_rows'];
$rss_board = sql_fetch($sql);
if (!isset($rss_board['gr_id']) || !$rss_board['gr_id']) {
echo '존재하지 않는 게시판입니다.';
exit;
}
$subj2 = specialchars_replace($rss_board['bo_subject'], 255);
$lines = (int)$rss_board['bo_page_rows'];
// 비회원 읽기가 가능한 게시판만 RSS 지원
if ($row['bo_read_level'] >= 2) {
if ((int)$rss_board['bo_read_level'] >= 2) {
echo '비회원 읽기가 가능한 게시판만 RSS 지원합니다.';
exit;
}
// RSS 사용 체크
if (!$row['bo_use_rss_view']) {
if (!$rss_board['bo_use_rss_view']) {
echo 'RSS 보기가 금지되어 있습니다.';
exit;
}
@@ -39,9 +51,9 @@ header('Content-type: text/xml');
header('Cache-Control: no-cache, must-revalidate');
header('Pragma: no-cache');
$sql = " select gr_subject from {$g5['group_table']} where gr_id = '{$row['gr_id']}' ";
$row = sql_fetch($sql);
$subj1 = specialchars_replace($row['gr_subject'], 255);
$sql = " select gr_subject from {$g5['group_table']} where gr_id = '{$rss_board['gr_id']}' ";
$rss_group = sql_fetch($sql);
$subj1 = isset($rss_group['gr_subject']) ? specialchars_replace($rss_group['gr_subject'], 255) : '';
echo '<?xml version="1.0" encoding="utf-8" ?>'."\n";
?>
@@ -88,4 +100,4 @@ $date = substr($date,0,10) . "T" . substr($date,11,8) . "+09:00";
}
echo '</channel>'."\n";
echo '</rss>'."\n";
echo '</rss>'."\n";
+5 -2
View File
@@ -6,7 +6,10 @@ include_once(G5_PATH.'/head.sub.php');
if (!$is_member)
{
$href = './login.php?'.$qstr.'&amp;url='.urlencode(get_pretty_url($bo_table, $wr_id));
echo '<script> alert(\'회원만 접근 가능합니다.\'); top.location.href = \''.str_replace('&amp;', '&', $href).'\'; </script>';
$href = str_replace('&amp;', '&', $href);
$js_replace = array('\\' => '\\\\', '"' => '\\"', "'" => '\\u0027', '/' => '\\/', "\r" => '\\r', "\n" => '\\n', "\t" => '\\t', '<' => '\\u003C', '>' => '\\u003E', '&' => '\\u0026', "\xE2\x80\xA8" => '\\u2028', "\xE2\x80\xA9" => '\\u2029');
$js_href = function_exists('get_js_safe_string') ? get_js_safe_string($href) : '"'.strtr((string)$href, $js_replace).'"';
echo '<script> alert(\'회원만 접근 가능합니다.\'); top.location.href = '.$js_href.'; </script>';
exit;
}
@@ -115,4 +118,4 @@ delete_cache_latest($bo_table);
<noscript>
<p>이 글을 스크랩 하였습니다.</p>
<a href="./scrap.php">스크랩 확인하기</a>
</noscript>
</noscript>
+2 -2
View File
@@ -8,7 +8,7 @@ if(!(version_compare(phpversion(), '5.3.0', '>=') && defined('G5_BROWSCAP_USE')
if(defined('G5_VISIT_BROWSCAP_USE') && G5_VISIT_BROWSCAP_USE && is_file(G5_DATA_PATH.'/cache/browscap_cache.php')) {
include_once(G5_PLUGIN_PATH.'/browscap/Browscap.php');
$browscap = new phpbrowscap\Browscap(G5_DATA_PATH.'/cache');
$browscap = new Browscap(G5_DATA_PATH.'/cache');
$browscap->doAutoUpdate = false;
$browscap->cacheFilename = 'browscap_cache.php';
@@ -17,4 +17,4 @@ if(defined('G5_VISIT_BROWSCAP_USE') && G5_VISIT_BROWSCAP_USE && is_file(G5_DATA_
$vi_browser = $info->Comment;
$vi_os = $info->Platform;
$vi_device = $info->Device_Type;
}
}
+9 -4
View File
@@ -484,6 +484,11 @@ $file_upload_msg = '';
$upload = array();
if(isset($_FILES['bf_file']['name']) && is_array($_FILES['bf_file']['name'])) {
if (function_exists('g5_check_data_htaccess')) {
g5_check_data_htaccess();
}
$bf_file_cnt = count($_FILES['bf_file']['name']);
for ($i=0; $i<$bf_file_cnt; $i++) {
$upload[$i]['file'] = '';
@@ -523,11 +528,11 @@ if(isset($_FILES['bf_file']['name']) && is_array($_FILES['bf_file']['name'])) {
// 서버에 설정된 값보다 큰파일을 업로드 한다면
if ($filename) {
if ($_FILES['bf_file']['error'][$i] == 1) {
$file_upload_msg .= '\"'.$filename.'\" 파일의 용량이 서버에 설정('.$upload_max_filesize.')된 값보다 크므로 업로드 할 수 없습니다.\\n';
$file_upload_msg .= '"'.$filename.'" 파일의 용량이 서버에 설정('.$upload_max_filesize.')된 값보다 크므로 업로드 할 수 없습니다.\\n';
continue;
}
else if ($_FILES['bf_file']['error'][$i] != 0) {
$file_upload_msg .= '\"'.$filename.'\" 파일이 정상적으로 업로드 되지 않았습니다.\\n';
$file_upload_msg .= '"'.$filename.'" 파일이 정상적으로 업로드 되지 않았습니다.\\n';
continue;
}
}
@@ -535,7 +540,7 @@ if(isset($_FILES['bf_file']['name']) && is_array($_FILES['bf_file']['name'])) {
if (is_uploaded_file($tmp_file)) {
// 관리자가 아니면서 설정한 업로드 사이즈보다 크다면 건너뜀
if (!$is_admin && $filesize > $board['bo_upload_size']) {
$file_upload_msg .= '\"'.$filename.'\" 파일의 용량('.number_format($filesize).' 바이트)이 게시판에 설정('.number_format($board['bo_upload_size']).' 바이트)된 값보다 크므로 업로드 하지 않습니다.\\n';
$file_upload_msg .= '"'.$filename.'" 파일의 용량('.number_format($filesize).' 바이트)이 게시판에 설정('.number_format($board['bo_upload_size']).' 바이트)된 값보다 크므로 업로드 하지 않습니다.\\n';
continue;
}
@@ -776,4 +781,4 @@ run_event('write_update_after', $board, $wr_id, $w, $qstr, $redirect_url);
if ($file_upload_msg)
alert($file_upload_msg, $redirect_url);
else
goto_url($redirect_url);
goto_url($redirect_url);
+1 -1
View File
@@ -295,7 +295,7 @@ if( ! class_exists('XenoPostToForm') ){
public static function makeInputArray($posts) {
$res = array();
foreach($posts as $k => $v) {
$res[] = self::makeInputArray_($k, $v);
$res[] = self::makeInputArray_(htmlspecialchars($k), $v);
}
return implode('', $res);
}
+3
View File
@@ -64,6 +64,7 @@ define('G5_MOBILE_DIR', 'mobile');
define('G5_OKNAME_DIR', 'okname');
define('G5_KCPCERT_DIR', 'kcpcert');
define('G5_KCPCERT_V2_DIR', 'kcpcert_v2');
define('G5_INICERT_DIR', 'inicert');
define('G5_LGXPAY_DIR', 'lgxpay');
@@ -103,6 +104,7 @@ define('G5_PLUGIN_URL', G5_URL.'/'.G5_PLUGIN_DIR);
define('G5_EDITOR_URL', G5_PLUGIN_URL.'/'.G5_EDITOR_DIR);
define('G5_OKNAME_URL', G5_PLUGIN_URL.'/'.G5_OKNAME_DIR);
define('G5_KCPCERT_URL', G5_PLUGIN_URL.'/'.G5_KCPCERT_DIR);
define('G5_KCPCERT_V2_URL', G5_PLUGIN_URL.'/'.G5_KCPCERT_V2_DIR);
define('G5_INICERT_URL', G5_PLUGIN_URL.'/'.G5_INICERT_DIR);
define('G5_LGXPAY_URL', G5_PLUGIN_URL.'/'.G5_LGXPAY_DIR);
define('G5_SNS_URL', G5_PLUGIN_URL.'/'.G5_SNS_DIR);
@@ -123,6 +125,7 @@ define('G5_EDITOR_PATH', G5_PLUGIN_PATH.'/'.G5_EDITOR_DIR);
define('G5_OKNAME_PATH', G5_PLUGIN_PATH.'/'.G5_OKNAME_DIR);
define('G5_KCPCERT_PATH', G5_PLUGIN_PATH.'/'.G5_KCPCERT_DIR);
define('G5_KCPCERT_V2_PATH', G5_PLUGIN_PATH.'/'.G5_KCPCERT_V2_DIR);
define('G5_INICERT_PATH', G5_PLUGIN_PATH.'/'.G5_INICERT_DIR);
define('G5_LGXPAY_PATH', G5_PLUGIN_PATH.'/'.G5_LGXPAY_DIR);
-5
View File
@@ -1,5 +0,0 @@
<FilesMatch "\.(htaccess|htpasswd|[Pp][Hh][Pp]|[Pp][Hh][Tt]|[Ss]?[Pp]?[Hh][Tt][Mm][Ll]?|[Ii][Nn][Cc]|[Cc][Gg][Ii]|[Pp][Ll]|[Pp][Hh][Aa][Rr]|[Ss][Vv][Gg][Zz]?)">
Order allow,deny
Deny from all
</FilesMatch>
RedirectMatch 403 /session/.*
+1 -1
View File
@@ -5,4 +5,4 @@ if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가
// 예) https://도메인/css/default.css?ver=220620
// 예) https://도메인/js/common.js?ver=220620
define('G5_CSS_VER', '2303229');
define('G5_JS_VER', '2304171');
define('G5_JS_VER', '2605291');
+19 -14
View File
@@ -7,6 +7,8 @@ include_once('../lib/common.lib.php'); // 공통 라이브러리
include_once('../lib/hook.lib.php'); // hook 함수 파일
include_once('../lib/get_data.lib.php'); // 데이터 가져오는 함수 모음
@header('Content-Type: application/json; charset=utf-8');
$data_path = '../'.G5_DATA_DIR;
// 파일이 존재한다면 설치할 수 없다.
@@ -30,29 +32,32 @@ $ajax_token = md5($tmp_str.$_SERVER['REMOTE_ADDR'].dirname(dirname(__FILE__).'/'
$bool_ajax_token = (isset($_POST['ajax_token']) && ($ajax_token == $_POST['ajax_token'])) ? true : false;
if (!($mysql_host && $mysql_user && $mysql_pass && $mysql_db && $table_prefix && $bool_ajax_token)) {
if (!($mysql_host && $mysql_user && $mysql_db && $table_prefix && $bool_ajax_token)) {
die(install_json_msg('잘못된 요청입니다.'));
}
try {
$dblink = sql_connect($mysql_host, $mysql_user, $mysql_pass, $mysql_db);
} catch (Exception $e) {
$connect = install_db_connect($mysql_host, $mysql_user, $mysql_pass, $mysql_db);
$dblink = $connect['link'];
if (!$dblink || $connect['message']) {
if ($connect['error']) {
install_error_log($connect['message'].' | '.$connect['error']);
}
die(install_json_msg($connect['message'] ? $connect['message'] : 'MySQL 정보를 확인해 주십시오.'));
}
if (!isset($dblink)) {
die(install_json_msg('MySQL Host, User, Password 를 확인해 주십시오.'));
$db_check = install_check_db_capability($dblink, $table_prefix);
if (!$db_check[0]) {
die(install_json_msg($db_check[1]));
}
try {
$select_db = sql_select_db($mysql_db, $dblink);
} catch (Exception $e) {
$table_check_error = '';
$table_exists = install_table_exists($dblink, $table_prefix.'config', $table_check_error);
if ($table_check_error) {
die(install_json_msg('테이블 존재 여부를 확인하지 못했습니다. DB 계정 권한을 확인해 주십시오.'));
}
if (!isset($select_db)) {
die(install_json_msg('MySQL DB 를 확인해 주십시오.'));
}
if (sql_query("SHOW TABLES LIKE `{$table_prefix}config`", G5_DISPLAY_SQL_ERROR, $dblink)) {
if ($table_exists) {
die(install_json_msg('주의! 이미 테이블이 존재하므로, 기존 DB 자료가 망실됩니다. 계속 진행하겠습니까?', 'exists'));
}
+2
View File
@@ -12,6 +12,7 @@ include_once ('./install.inc.php');
if ($exists_data_dir && $write_data_dir) {
// 필수 모듈 체크
require_once('./library.check.php');
if (empty($install_library_required_missing)) {
?>
<form action="./install_config.php" method="post" onsubmit="return frm_submit(this);">
@@ -48,6 +49,7 @@ function frm_submit(f)
}
</script>
<?php
}
} // if
?>
+395 -1
View File
@@ -56,4 +56,398 @@ if( ! function_exists('install_json_msg') ){
return json_encode(array('error'=>$error_msg, 'success'=>$success_msg, 'exists'=>$exists_msg));
}
}
}
if( ! function_exists('install_error_log') ){
function install_error_log($message) {
$err_file = isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] : '';
@error_log('[g5 install] '.$message.' | file: '.$err_file);
}
}
if( ! function_exists('install_html_escape') ){
function install_html_escape($str) {
return htmlspecialchars((string) $str, ENT_QUOTES, 'UTF-8');
}
}
if( ! function_exists('install_db_error') ){
function install_db_error($link=null) {
if (function_exists('mysqli_connect') && G5_MYSQLI_USE) {
if ($link) {
return mysqli_errno($link).' : '.mysqli_error($link);
}
return mysqli_connect_errno().' : '.mysqli_connect_error();
}
if (function_exists('mysql_error')) {
return $link ? mysql_errno($link).' : '.mysql_error($link) : mysql_errno().' : '.mysql_error();
}
return '';
}
}
if( ! function_exists('install_db_query') ){
function install_db_query($sql, $link) {
if (function_exists('mysqli_query') && G5_MYSQLI_USE) {
return @mysqli_query($link, $sql);
}
return @mysql_query($sql, $link);
}
}
if( ! function_exists('install_db_fetch_row') ){
function install_db_fetch_row($result) {
if (!$result) {
return false;
}
if (function_exists('mysqli_fetch_row') && G5_MYSQLI_USE) {
return mysqli_fetch_row($result);
}
return mysql_fetch_row($result);
}
}
if( ! function_exists('install_db_num_rows') ){
function install_db_num_rows($result) {
if (!$result) {
return 0;
}
if (function_exists('mysqli_num_rows') && G5_MYSQLI_USE) {
return mysqli_num_rows($result);
}
return mysql_num_rows($result);
}
}
if( ! function_exists('install_db_connect') ){
function install_db_connect($host, $user, $pass, $db) {
$result = array('link'=>false, 'error'=>'', 'message'=>'');
if (function_exists('mysqli_connect') && G5_MYSQLI_USE) {
if (function_exists('mysqli_report')) {
mysqli_report(MYSQLI_REPORT_OFF);
}
$link = @mysqli_connect($host, $user, $pass);
if (!$link) {
$result['error'] = install_db_error();
$result['message'] = 'MySQL Host, User, Password 정보를 확인해 주십시오.';
return $result;
}
if (!@mysqli_select_db($link, $db)) {
$result['link'] = $link;
$result['error'] = install_db_error($link);
$result['message'] = 'MySQL DB 정보를 확인해 주십시오.';
return $result;
}
$result['link'] = $link;
return $result;
}
if (!function_exists('mysql_connect')) {
$result['message'] = 'MySQL 확장(mysqli/mysql)이 설치되어 있지 않습니다.';
return $result;
}
$link = @mysql_connect($host, $user, $pass);
if (!$link) {
$result['error'] = install_db_error();
$result['message'] = 'MySQL Host, User, Password 정보를 확인해 주십시오.';
return $result;
}
if (!@mysql_select_db($db, $link)) {
$result['link'] = $link;
$result['error'] = install_db_error($link);
$result['message'] = 'MySQL DB 정보를 확인해 주십시오.';
return $result;
}
$result['link'] = $link;
return $result;
}
}
if( ! function_exists('install_sql_like_escape') ){
function install_sql_like_escape($str) {
return str_replace(array('\\', '%', '_'), array('\\\\', '\%', '\_'), $str);
}
}
if( ! function_exists('install_sql_escape') ){
function install_sql_escape($str, $link) {
if (function_exists('mysqli_real_escape_string') && G5_MYSQLI_USE) {
return mysqli_real_escape_string($link, $str);
}
return mysql_real_escape_string($str, $link);
}
}
if( ! function_exists('install_table_exists') ){
function install_table_exists($link, $table, &$error='') {
$error = '';
$table_like = install_sql_escape(install_sql_like_escape($table), $link);
$result = install_db_query("SHOW TABLES LIKE '{$table_like}'", $link);
if (!$result) {
$error = install_db_error($link);
install_error_log('table exists check failed: '.$error.' | table: '.$table);
return false;
}
return install_db_num_rows($result) > 0;
}
}
if( ! function_exists('install_get_existing_tables') ){
function install_get_existing_tables($link, $prefixes) {
$tables = array();
foreach ($prefixes as $prefix) {
if (!$prefix) {
continue;
}
$table_like = install_sql_escape(install_sql_like_escape($prefix).'%', $link);
$result = install_db_query("SHOW TABLES LIKE '{$table_like}'", $link);
while ($row = install_db_fetch_row($result)) {
if (isset($row[0])) {
$tables[$row[0]] = $row[0];
}
}
}
ksort($tables);
return array_values($tables);
}
}
if( ! function_exists('install_fail_page') ){
function install_fail_page($message, $link=null, $prefixes=array()) {
global $install_progress_started;
install_error_log($message);
if (!empty($install_progress_started)) {
$install_progress_started = false;
?>
</ol>
</div>
<?php
}
?>
<div class="ins_inner">
<h2>설치를 계속할 수 없습니다.</h2>
<p><?php echo nl2br(install_html_escape($message)); ?></p>
<?php
if ($link && $prefixes) {
$tables = install_get_existing_tables($link, $prefixes);
if ($tables) {
?>
<p>설치가 중간에 멈춘 경우 아래 테이블이 일부 생성되었을 수 있습니다. 다시 설치하려면 DB에서 해당 테이블을 정리하거나, 재설치 옵션을 선택한 뒤 진행해 주십시오.</p>
<ul>
<?php
for ($i=0; $i<count($tables); $i++) {
?>
<li><?php echo install_html_escape($tables[$i]); ?></li>
<?php
}
?>
</ul>
<?php
}
}
?>
<div class="inner_btn"><a href="./install_config.php">뒤로가기</a></div>
</div>
<?php
include_once('./install.inc2.php');
exit;
}
}
if( ! function_exists('install_query_or_fail') ){
function install_query_or_fail($sql, $link, $message, $prefixes=array()) {
$result = install_db_query($sql, $link);
if (!$result) {
install_error_log($message.' | '.install_db_error($link).' | SQL: '.$sql);
install_fail_page($message."\n서버 오류 로그를 확인해 주십시오.", $link, $prefixes);
}
return $result;
}
}
if( ! function_exists('install_check_db_capability') ){
function install_check_db_capability($link, $table_prefix) {
$suffix = substr(md5(uniqid('', true)), 0, 12);
$table = $table_prefix.'install_check_'.$suffix;
$charset = preg_replace('/[^0-9a-z_]/i', '', G5_DB_CHARSET);
$engine = '';
if (!$charset) {
$charset = 'utf8';
}
if (in_array(strtolower(G5_DB_ENGINE), array('innodb', 'myisam'))) {
$engine = ' ENGINE='.G5_DB_ENGINE;
}
$checks = array(
"CREATE TABLE `{$table}` (`id` int(11) NOT NULL){$engine} DEFAULT CHARSET={$charset}",
"INSERT INTO `{$table}` (`id`) VALUES (1)",
"ALTER TABLE `{$table}` ADD `memo` varchar(20) NOT NULL DEFAULT ''",
"DROP TABLE `{$table}`"
);
for ($i=0; $i<count($checks); $i++) {
if (!install_db_query($checks[$i], $link)) {
$error = install_db_error($link);
install_db_query("DROP TABLE IF EXISTS `{$table}`", $link);
install_error_log('DB capability check failed: '.$error.' | SQL: '.$checks[$i]);
return array(false, 'DB 계정에 테이블 생성/입력/수정/삭제 권한이 있는지, DB 문자셋('.G5_DB_CHARSET.')을 사용할 수 있는지 확인해 주십시오.');
}
}
return array(true, '');
}
}
if( ! function_exists('install_split_sql') ){
function install_split_sql($sql) {
$queries = array();
$query = '';
$quote = '';
$len = strlen($sql);
for ($i=0; $i<$len; $i++) {
$char = $sql[$i];
$next = ($i + 1 < $len) ? $sql[$i + 1] : '';
if ($quote) {
$query .= $char;
if ($quote !== '`' && $char === '\\' && $next !== '') {
$query .= $next;
$i++;
continue;
}
if ($char === $quote) {
$quote = '';
}
continue;
}
if ($char === "'" || $char === '"' || $char === '`') {
$quote = $char;
$query .= $char;
continue;
}
if ($char === '-' && $next === '-' && ($i === 0 || preg_match('/\s/', $sql[$i - 1]))) {
while ($i < $len && $sql[$i] !== "\n") {
$i++;
}
continue;
}
if ($char === '#') {
while ($i < $len && $sql[$i] !== "\n") {
$i++;
}
continue;
}
if ($char === '/' && $next === '*') {
$i += 2;
while ($i < $len - 1 && !($sql[$i] === '*' && $sql[$i + 1] === '/')) {
$i++;
}
$i++;
continue;
}
if ($char === ';') {
$trimmed = trim($query);
if ($trimmed !== '') {
$queries[] = $trimmed;
}
$query = '';
continue;
}
$query .= $char;
}
$trimmed = trim($query);
if ($trimmed !== '') {
$queries[] = $trimmed;
}
return $queries;
}
}
if( ! function_exists('install_load_sql_file') ){
function install_load_sql_file($file, $from_prefix, $to_prefix) {
if (!is_readable($file)) {
return false;
}
$sql = file_get_contents($file);
if ($sql === false) {
return false;
}
$sql = preg_replace('/`'.preg_quote($from_prefix, '/').'([^`]+`)/', '`'.$to_prefix.'$1', $sql);
return install_split_sql($sql);
}
}
if( ! function_exists('install_ensure_dir') ){
function install_ensure_dir($dir) {
if (!is_dir($dir) && !@mkdir($dir, G5_DIR_PERMISSION)) {
return false;
}
@chmod($dir, G5_DIR_PERMISSION);
return is_dir($dir) && is_writable($dir);
}
}
if( ! function_exists('install_file_write') ){
function install_file_write($handle, $content) {
global $install_file_write_error;
if ($install_file_write_error) {
return false;
}
$result = @fwrite($handle, $content);
if ($result === false || $result < strlen($content)) {
$install_file_write_error = true;
return false;
}
return true;
}
}
+71 -2
View File
@@ -135,8 +135,56 @@ $ajax_token = md5($tmp_str.$_SERVER['REMOTE_ADDR'].dirname(dirname(__FILE__).'/'
<script src="../js/jquery-1.8.3.min.js"></script>
<script>
function get_install_check_error_message(xhr)
{
var status = (xhr && xhr.status) ? ' (HTTP ' + xhr.status + ')' : '';
var default_msg = 'DB 연결 점검 중 오류가 발생했습니다.' + status + '\n'
+ 'MySQL Host/User/Password/DB 정보가 올바른지, DB 서버가 동작 중인지 확인해 주십시오.\n'
+ '문제가 계속되면 PHP 오류 로그를 확인하시기 바랍니다.';
var response_text = xhr ? (xhr.responseText || '') : '';
if (response_text && window.jQuery) {
try {
var data = jQuery.parseJSON(response_text);
if (data && data.error) {
return data.error;
}
} catch (e) {
}
}
response_text = response_text.replace(/<[^>]*>/g, ' ').replace(/\s+/g, ' ');
response_text = window.jQuery ? jQuery.trim(response_text) : response_text;
return response_text || default_msg;
}
function set_install_submit_state(f, submitting)
{
var submit_btn = f.querySelector ? f.querySelector('input[type="submit"]') : null;
if (submitting) {
f.setAttribute('data-install-submitting', '1');
if (submit_btn) {
submit_btn.setAttribute('data-original-value', submit_btn.value);
submit_btn.disabled = true;
submit_btn.value = '점검 중...';
}
} else {
f.removeAttribute('data-install-submitting');
if (submit_btn) {
submit_btn.disabled = false;
submit_btn.value = submit_btn.getAttribute('data-original-value') || '다음';
}
}
}
function frm_install_submit(f)
{
if (f.getAttribute('data-install-submitting') == '1') {
return false;
}
if (f.mysql_host.value == '')
{
alert('MySQL Host 를 입력하십시오.'); f.mysql_host.focus(); return false;
@@ -194,25 +242,46 @@ function frm_install_submit(f)
f.admin_id.focus();
return false;
}
if (f.g5_install.checked) {
var reinstall_msg = '재설치를 선택했습니다.\n\n'
+ 'DB: ' + f.mysql_db.value + '\n'
+ 'TABLE명 접두사: ' + f.table_prefix.value + '\n'
+ '쇼핑몰 TABLE명 접두사: ' + f.g5_shop_prefix.value + '\n\n'
+ '기존 테이블과 자료가 삭제되거나 덮어써질 수 있습니다. 계속 진행하시겠습니까?';
if (!confirm(reinstall_msg)) {
return false;
}
}
set_install_submit_state(f, true);
if (window.jQuery) {
var jqxhr = jQuery.post( "ajax.install.check.php", $(f).serialize(), function(data) {
if( data.error ){
set_install_submit_state(f, false);
alert(data.error);
} else if( data.exists ) {
if( confirm(data.exists) ){
if( f.g5_install.checked || confirm(data.exists) ){
f.submit();
} else {
set_install_submit_state(f, false);
}
} else if( data.success ) {
f.submit();
} else {
set_install_submit_state(f, false);
alert(get_install_check_error_message());
}
}, "json");
jqxhr.fail(function(xhr) {
alert( xhr.responseText );
set_install_submit_state(f, false);
alert(get_install_check_error_message(xhr));
});
return false;
+185 -149
View File
@@ -37,99 +37,101 @@ $admin_name = isset($_POST['admin_name']) ? $_POST['admin_name'] : '';
$admin_email = isset($_POST['admin_email']) ? $_POST['admin_email'] : '';
if (preg_match("/[^0-9a-z_]+/i", $table_prefix) ) {
die('<div class="ins_inner"><p>TABLE명 접두사는 영문자, 숫자, _ 만 입력하세요.</p><div class="inner_btn"><a href="./install_config.php">뒤로가기</a></div></div>');
install_fail_page('TABLE명 접두사는 영문자, 숫자, _ 만 입력하세요.');
}
if (preg_match("/[^0-9a-z_]+/i", $admin_id)) {
die('<div class="ins_inner"><p>관리자 아이디는 영문자, 숫자, _ 만 입력하세요.</p><div class="inner_btn"><a href="./install_config.php">뒤로가기</a></div></div>');
install_fail_page('관리자 아이디는 영문자, 숫자, _ 만 입력하세요.');
}
// 관리자 이메일 형식 검증
$admin_email = trim($admin_email);
if (!$admin_email || !filter_var($admin_email, FILTER_VALIDATE_EMAIL)) {
install_fail_page('올바른 관리자 E-mail 주소를 입력하세요.');
}
$g5_install = isset($_POST['g5_install']) ? (int) $_POST['g5_install'] : 0;
$g5_shop_prefix = isset($_POST['g5_shop_prefix']) ? safe_install_string_check($_POST['g5_shop_prefix']) : 'yc5_';
$g5_shop_install = isset($_POST['g5_shop_install']) ? (int) $_POST['g5_shop_install'] : 0;
$dblink = sql_connect($mysql_host, $mysql_user, $mysql_pass, $mysql_db);
if (!$dblink) {
?>
if (preg_match("/[^0-9a-z_]+/i", $g5_shop_prefix)) {
install_fail_page('쇼핑몰 TABLE명 접두사는 영문자, 숫자, _ 만 입력하세요.');
}
<div class="ins_inner">
<p>MySQL Host, User, Password 를 확인해 주십시오.</p>
<div class="inner_btn"><a href="./install_config.php">뒤로가기</a></div>
</div>
$install_table_prefixes = array($table_prefix);
if ($g5_shop_install) {
$install_table_prefixes[] = $g5_shop_prefix;
}
<?php
include_once('./install.inc2.php');
exit;
$connect = install_db_connect($mysql_host, $mysql_user, $mysql_pass, $mysql_db);
$dblink = $connect['link'];
if (!$dblink || $connect['message']) {
if ($connect['error']) {
install_error_log($connect['message'].' | '.$connect['error']);
}
install_fail_page($connect['message'] ? $connect['message'] : 'MySQL 정보를 확인해 주십시오.', $dblink, $install_table_prefixes);
}
$g5['connect_db'] = $dblink;
$select_db = sql_select_db($mysql_db, $dblink);
if (!$select_db) {
?>
<div class="ins_inner">
<p>MySQL DB 를 확인해 주십시오.</p>
<div class="inner_btn"><a href="./install_config.php">뒤로가기</a></div>
</div>
<?php
include_once('./install.inc2.php');
exit;
$db_check = install_check_db_capability($dblink, $table_prefix);
if (!$db_check[0]) {
install_fail_page($db_check[1], $dblink, $install_table_prefixes);
}
$mysql_set_mode = 'false';
sql_set_charset(G5_DB_CHARSET, $dblink);
$result = sql_query(" SELECT @@sql_mode as mode ", true, $dblink);
// 관리자 입력값 SQL escape — sql_set_charset 이후 적용
$admin_name = sql_real_escape_string(trim($admin_name), $dblink);
$admin_email = sql_real_escape_string($admin_email, $dblink);
$result = install_query_or_fail(" SELECT @@sql_mode as mode ", $dblink, 'DB SQL 모드를 확인하지 못했습니다.', $install_table_prefixes);
$row = sql_fetch_array($result);
if($row['mode']) {
sql_query("SET SESSION sql_mode = ''", true, $dblink);
install_query_or_fail("SET SESSION sql_mode = ''", $dblink, 'DB SQL 모드를 변경하지 못했습니다.', $install_table_prefixes);
$mysql_set_mode = 'true';
}
unset($result);
unset($row);
?>
<?php $install_progress_started = true; ?>
<div class="ins_inner">
<h2><?php echo G5_VERSION ?> 설치가 시작되었습니다.</h2>
<ol>
<?php
$sql = "SHOW TABLES LIKE '{$table_prefix}config'";
$is_install = sql_query($sql, false, $dblink)->num_rows > 0;
$table_check_error = '';
$is_install = install_table_exists($dblink, $table_prefix.'config', $table_check_error);
if ($table_check_error) {
install_fail_page('기존 테이블 존재 여부를 확인하지 못했습니다. DB 계정 권한을 확인해 주십시오.', $dblink, $install_table_prefixes);
}
// 그누보드5 재설치에 체크하였거나 그누보드5가 설치되어 있지 않다면
if ($g5_install || $is_install === false) {
// 테이블 생성 ------------------------------------
$file = implode('', file('./gnuboard5.sql'));
eval("\$file = \"$file\";");
$queries = install_load_sql_file('./gnuboard5.sql', 'g5_', $table_prefix);
if ($queries === false) {
install_fail_page('gnuboard5.sql 파일을 읽을 수 없습니다.', $dblink, $install_table_prefixes);
}
$file = preg_replace('/^--.*$/m', '', $file);
$file = preg_replace('/`g5_([^`]+`)/', '`'.$table_prefix.'$1', $file);
$f = explode(';', $file);
for ($i=0; $i<count($f); $i++) {
if (trim($f[$i]) == '') {
continue;
}
$sql = get_db_create_replace($f[$i]);
sql_query($sql, true, $dblink);
for ($i=0; $i<count($queries); $i++) {
$sql = get_db_create_replace($queries[$i]);
install_query_or_fail($sql, $dblink, '그누보드 기본 테이블 생성 중 오류가 발생했습니다.', $install_table_prefixes);
}
}
// 쇼핑몰 테이블 생성 -----------------------------
if($g5_shop_install) {
$file = implode('', file('./gnuboard5shop.sql'));
$queries = install_load_sql_file('./gnuboard5shop.sql', 'g5_shop_', $g5_shop_prefix);
if ($queries === false) {
install_fail_page('gnuboard5shop.sql 파일을 읽을 수 없습니다.', $dblink, $install_table_prefixes);
}
$file = preg_replace('/^--.*$/m', '', $file);
$file = preg_replace('/`g5_shop_([^`]+`)/', '`'.$g5_shop_prefix.'$1', $file);
$f = explode(';', $file);
for ($i=0; $i<count($f); $i++) {
if (trim($f[$i]) == '') {
continue;
}
$sql = get_db_create_replace($f[$i]);
sql_query($sql, true, $dblink);
for ($i=0; $i<count($queries); $i++) {
$sql = get_db_create_replace($queries[$i]);
install_query_or_fail($sql, $dblink, '쇼핑몰 테이블 생성 중 오류가 발생했습니다.', $install_table_prefixes);
}
}
// 테이블 생성 ------------------------------------
@@ -219,14 +221,14 @@ if ($g5_install || $is_install === false) {
cf_stipulation = '해당 홈페이지에 맞는 회원가입약관을 입력합니다.',
cf_privacy = '해당 홈페이지에 맞는 개인정보처리방침을 입력합니다.'
";
sql_query($sql, true, $dblink);
install_query_or_fail($sql, $dblink, '기본 환경설정을 저장하지 못했습니다.', $install_table_prefixes);
// 1:1문의 설정
$sql = " insert into `{$table_prefix}qa_config`
( qa_title, qa_category, qa_skin, qa_mobile_skin, qa_use_email, qa_req_email, qa_use_hp, qa_req_hp, qa_use_editor, qa_subject_len, qa_mobile_subject_len, qa_page_rows, qa_mobile_page_rows, qa_image_width, qa_upload_size, qa_insert_content )
values
( '1:1문의', '회원|포인트', 'basic', 'basic', '1', '0', '1', '0', '1', '60', '30', '15', '15', '600', '1048576', '' ) ";
sql_query($sql, true, $dblink);
install_query_or_fail($sql, $dblink, '1:1문의 설정을 저장하지 못했습니다.', $install_table_prefixes);
// 관리자 회원가입
$sql = " insert into `{$table_prefix}member`
@@ -243,15 +245,15 @@ if ($g5_install || $is_install === false) {
mb_datetime = '".G5_TIME_YMDHIS."',
mb_ip = '{$_SERVER['REMOTE_ADDR']}'
";
sql_query($sql, true, $dblink);
install_query_or_fail($sql, $dblink, '관리자 회원 정보를 저장하지 못했습니다.', $install_table_prefixes);
// 내용관리 생성
sql_query(" insert into `{$table_prefix}content` set co_id = 'company', co_html = '1', co_subject = '회사소개', co_content= '<p align=center><b>회사소개에 대한 내용을 입력하십시오.</b></p>', co_skin = 'basic', co_mobile_skin = 'basic' ", true, $dblink);
sql_query(" insert into `{$table_prefix}content` set co_id = 'privacy', co_html = '1', co_subject = '개인정보 처리방침', co_content= '<p align=center><b>개인정보 처리방침에 대한 내용을 입력하십시오.</b></p>', co_skin = 'basic', co_mobile_skin = 'basic' ", true, $dblink);
sql_query(" insert into `{$table_prefix}content` set co_id = 'provision', co_html = '1', co_subject = '서비스 이용약관', co_content= '<p align=center><b>서비스 이용약관에 대한 내용을 입력하십시오.</b></p>', co_skin = 'basic', co_mobile_skin = 'basic' ", true, $dblink);
install_query_or_fail(" insert into `{$table_prefix}content` set co_id = 'company', co_html = '1', co_subject = '회사소개', co_content= '<p align=center><b>회사소개에 대한 내용을 입력하십시오.</b></p>', co_skin = 'basic', co_mobile_skin = 'basic' ", $dblink, '회사소개 기본 내용을 저장하지 못했습니다.', $install_table_prefixes);
install_query_or_fail(" insert into `{$table_prefix}content` set co_id = 'privacy', co_html = '1', co_subject = '개인정보 처리방침', co_content= '<p align=center><b>개인정보 처리방침에 대한 내용을 입력하십시오.</b></p>', co_skin = 'basic', co_mobile_skin = 'basic' ", $dblink, '개인정보 처리방침 기본 내용을 저장하지 못했습니다.', $install_table_prefixes);
install_query_or_fail(" insert into `{$table_prefix}content` set co_id = 'provision', co_html = '1', co_subject = '서비스 이용약관', co_content= '<p align=center><b>서비스 이용약관에 대한 내용을 입력하십시오.</b></p>', co_skin = 'basic', co_mobile_skin = 'basic' ", $dblink, '서비스 이용약관 기본 내용을 저장하지 못했습니다.', $install_table_prefixes);
// FAQ Master
sql_query(" insert into `{$table_prefix}faq_master` set fm_id = '1', fm_subject = '자주하시는 질문' ", true, $dblink);
install_query_or_fail(" insert into `{$table_prefix}faq_master` set fm_id = '1', fm_subject = '자주하시는 질문' ", $dblink, 'FAQ 기본 정보를 저장하지 못했습니다.', $install_table_prefixes);
// 그누보드, 영카트 통합으로 인하여 게시판그룹을 커뮤니티(community)로 생성 (NaviGator님,210624)
// $tmp_gr_id = defined('G5_YOUNGCART_VER') ? 'shop' : 'community';
@@ -260,7 +262,7 @@ if ($g5_install || $is_install === false) {
$tmp_gr_subject = '커뮤니티';
// 게시판 그룹 생성
sql_query(" insert into `{$table_prefix}group` set gr_id = '$tmp_gr_id', gr_subject = '$tmp_gr_subject' ", true, $dblink);
install_query_or_fail(" insert into `{$table_prefix}group` set gr_id = '$tmp_gr_id', gr_subject = '$tmp_gr_subject' ", $dblink, '게시판 그룹을 생성하지 못했습니다.', $install_table_prefixes);
// 게시판 생성
$tmp_bo_subject = array ("공지사항", "질문답변", "자유게시판", "갤러리");
@@ -345,10 +347,14 @@ if ($g5_install || $is_install === false) {
bo_use_search = '0',
bo_order = '0'
";
sql_query($sql, true, $dblink);
install_query_or_fail($sql, $dblink, '게시판 기본 설정을 저장하지 못했습니다.', $install_table_prefixes);
// 게시판 테이블 생성
$file = file("../".G5_ADMIN_DIR."/sql_write.sql");
$file = @file("../".G5_ADMIN_DIR."/sql_write.sql");
if ($file === false) {
install_fail_page(G5_ADMIN_DIR."/sql_write.sql 파일을 읽을 수 없습니다.", $dblink, $install_table_prefixes);
}
$file = get_db_create_replace($file);
$sql = implode("\n", $file);
@@ -358,7 +364,7 @@ if ($g5_install || $is_install === false) {
$source = array("/__TABLE_NAME__/", "/;/");
$target = array($create_table, "");
$sql = preg_replace($source, $target, $sql);
sql_query($sql, false, $dblink);
install_query_or_fail($sql, $dblink, '게시판 글쓰기 테이블을 생성하지 못했습니다.', $install_table_prefixes);
}
}
@@ -516,7 +522,7 @@ if($g5_shop_install) {
de_sms_cont4 = '{이름}님 입금 감사합니다.\n{입금액}원\n주문번호:\n{주문번호}\n{회사명}',
de_sms_cont5 = '{이름}님 배송합니다.\n택배:{택배회사}\n운송장번호:\n{운송장번호}\n{회사명}'
";
sql_query($sql, true, $dblink);
install_query_or_fail($sql, $dblink, '쇼핑몰 기본 설정을 저장하지 못했습니다.', $install_table_prefixes);
}
?>
@@ -540,15 +546,17 @@ $dir_arr = array (
);
for ($i=0; $i<count($dir_arr); $i++) {
@mkdir($dir_arr[$i], G5_DIR_PERMISSION);
@chmod($dir_arr[$i], G5_DIR_PERMISSION);
if (!install_ensure_dir($dir_arr[$i])) {
install_fail_page($dir_arr[$i]." 디렉토리를 생성하거나 쓸 수 없습니다.\ndata 디렉토리 권한을 확인해 주십시오.", $dblink, $install_table_prefixes);
}
}
// 게시판 디렉토리 생성 (작은별님,211206)
for ($i=0; $i<count($tmp_bo_table); $i++) {
$board_dir = $data_path.'/file/'.$tmp_bo_table[$i];
@mkdir($board_dir, G5_DIR_PERMISSION);
@chmod($board_dir, G5_DIR_PERMISSION);
if (!install_ensure_dir($board_dir)) {
install_fail_page($board_dir." 디렉토리를 생성하거나 쓸 수 없습니다.\ndata 디렉토리 권한을 확인해 주십시오.", $dblink, $install_table_prefixes);
}
}
if($g5_shop_install) {
@@ -560,8 +568,9 @@ if($g5_shop_install) {
);
for ($i=0; $i<count($dir_arr); $i++) {
@mkdir($dir_arr[$i], G5_DIR_PERMISSION);
@chmod($dir_arr[$i], G5_DIR_PERMISSION);
if (!install_ensure_dir($dir_arr[$i])) {
install_fail_page($dir_arr[$i]." 디렉토리를 생성하거나 쓸 수 없습니다.\ndata 디렉토리 권한을 확인해 주십시오.", $dblink, $install_table_prefixes);
}
}
}
?>
@@ -573,84 +582,92 @@ if($g5_shop_install) {
// DB 설정 파일 생성
$file = '../'.G5_DATA_DIR.'/'.G5_DBCONFIG_FILE;
$f = @fopen($file, 'a');
$install_file_write_error = false;
$f = @fopen($file, 'w');
fwrite($f, "<?php\n");
fwrite($f, "if (!defined('_GNUBOARD_')) exit;\n");
fwrite($f, "define('G5_MYSQL_HOST', '".addcslashes($mysql_host, "\\'")."');\n");
fwrite($f, "define('G5_MYSQL_USER', '".addcslashes($mysql_user, "\\'")."');\n");
fwrite($f, "define('G5_MYSQL_PASSWORD', '".addcslashes($mysql_pass, "\\'")."');\n");
fwrite($f, "define('G5_MYSQL_DB', '".addcslashes($mysql_db, "\\'")."');\n");
fwrite($f, "define('G5_MYSQL_SET_MODE', {$mysql_set_mode});\n\n");
fwrite($f, "define('G5_TABLE_PREFIX', '{$table_prefix}');\n\n");
fwrite($f, "define('G5_TOKEN_ENCRYPTION_KEY', '".get_random_token_string(16)."'); // 토큰 암호화에 사용할 키\n\n");
fwrite($f, "\$g5['write_prefix'] = G5_TABLE_PREFIX.'write_'; // 게시판 테이블명 접두사\n\n");
fwrite($f, "\$g5['auth_table'] = G5_TABLE_PREFIX.'auth'; // 관리권한 설정 테이블\n");
fwrite($f, "\$g5['config_table'] = G5_TABLE_PREFIX.'config'; // 기본환경 설정 테이블\n");
fwrite($f, "\$g5['group_table'] = G5_TABLE_PREFIX.'group'; // 게시판 그룹 테이블\n");
fwrite($f, "\$g5['group_member_table'] = G5_TABLE_PREFIX.'group_member'; // 게시판 그룹+회원 테이블\n");
fwrite($f, "\$g5['board_table'] = G5_TABLE_PREFIX.'board'; // 게시판 설정 테이블\n");
fwrite($f, "\$g5['board_file_table'] = G5_TABLE_PREFIX.'board_file'; // 게시판 첨부파일 테이블\n");
fwrite($f, "\$g5['board_good_table'] = G5_TABLE_PREFIX.'board_good'; // 게시물 추천,비추천 테이블\n");
fwrite($f, "\$g5['board_new_table'] = G5_TABLE_PREFIX.'board_new'; // 게시판 새글 테이블\n");
fwrite($f, "\$g5['login_table'] = G5_TABLE_PREFIX.'login'; // 로그인 테이블 (접속자수)\n");
fwrite($f, "\$g5['mail_table'] = G5_TABLE_PREFIX.'mail'; // 회원메일 테이블\n");
fwrite($f, "\$g5['member_table'] = G5_TABLE_PREFIX.'member'; // 회원 테이블\n");
fwrite($f, "\$g5['member_auto_login_table'] = G5_TABLE_PREFIX.'member_auto_login'; // 자동 로그인 토큰 테이블\n");
fwrite($f, "\$g5['memo_table'] = G5_TABLE_PREFIX.'memo'; // 메모 테이블\n");
fwrite($f, "\$g5['poll_table'] = G5_TABLE_PREFIX.'poll'; // 투표 테이블\n");
fwrite($f, "\$g5['poll_etc_table'] = G5_TABLE_PREFIX.'poll_etc'; // 투표 기타의견 테이블\n");
fwrite($f, "\$g5['point_table'] = G5_TABLE_PREFIX.'point'; // 포인트 테이블\n");
fwrite($f, "\$g5['popular_table'] = G5_TABLE_PREFIX.'popular'; // 인기검색어 테이블\n");
fwrite($f, "\$g5['scrap_table'] = G5_TABLE_PREFIX.'scrap'; // 게시글 스크랩 테이블\n");
fwrite($f, "\$g5['visit_table'] = G5_TABLE_PREFIX.'visit'; // 방문자 테이블\n");
fwrite($f, "\$g5['visit_sum_table'] = G5_TABLE_PREFIX.'visit_sum'; // 방문자 합계 테이블\n");
fwrite($f, "\$g5['uniqid_table'] = G5_TABLE_PREFIX.'uniqid'; // 유니크한 값을 만드는 테이블\n");
fwrite($f, "\$g5['autosave_table'] = G5_TABLE_PREFIX.'autosave'; // 게시글 작성시 일정시간마다 글을 임시 저장하는 테이블\n");
fwrite($f, "\$g5['cert_history_table'] = G5_TABLE_PREFIX.'cert_history'; // 인증내역 테이블\n");
fwrite($f, "\$g5['qa_config_table'] = G5_TABLE_PREFIX.'qa_config'; // 1:1문의 설정테이블\n");
fwrite($f, "\$g5['qa_content_table'] = G5_TABLE_PREFIX.'qa_content'; // 1:1문의 테이블\n");
fwrite($f, "\$g5['content_table'] = G5_TABLE_PREFIX.'content'; // 내용(컨텐츠)정보 테이블\n");
fwrite($f, "\$g5['faq_table'] = G5_TABLE_PREFIX.'faq'; // 자주하시는 질문 테이블\n");
fwrite($f, "\$g5['faq_master_table'] = G5_TABLE_PREFIX.'faq_master'; // 자주하시는 질문 마스터 테이블\n");
fwrite($f, "\$g5['new_win_table'] = G5_TABLE_PREFIX.'new_win'; // 새창 테이블\n");
fwrite($f, "\$g5['menu_table'] = G5_TABLE_PREFIX.'menu'; // 메뉴관리 테이블\n");
fwrite($f, "\$g5['social_profile_table'] = G5_TABLE_PREFIX.'member_social_profiles'; // 소셜 로그인 테이블\n");
fwrite($f, "\$g5['member_cert_history_table'] = G5_TABLE_PREFIX.'member_cert_history'; // 본인인증 변경내역 테이블\n");
if($g5_shop_install) {
fwrite($f, "\n");
fwrite($f, "define('G5_USE_SHOP', true);\n\n");
fwrite($f, "define('G5_SHOP_TABLE_PREFIX', '{$g5_shop_prefix}');\n\n");
fwrite($f, "\$g5['g5_shop_default_table'] = G5_SHOP_TABLE_PREFIX.'default'; // 쇼핑몰설정 테이블\n");
fwrite($f, "\$g5['g5_shop_banner_table'] = G5_SHOP_TABLE_PREFIX.'banner'; // 배너 테이블\n");
fwrite($f, "\$g5['g5_shop_cart_table'] = G5_SHOP_TABLE_PREFIX.'cart'; // 장바구니 테이블\n");
fwrite($f, "\$g5['g5_shop_category_table'] = G5_SHOP_TABLE_PREFIX.'category'; // 상품분류 테이블\n");
fwrite($f, "\$g5['g5_shop_event_table'] = G5_SHOP_TABLE_PREFIX.'event'; // 이벤트 테이블\n");
fwrite($f, "\$g5['g5_shop_event_item_table'] = G5_SHOP_TABLE_PREFIX.'event_item'; // 상품, 이벤트 연결 테이블\n");
fwrite($f, "\$g5['g5_shop_item_table'] = G5_SHOP_TABLE_PREFIX.'item'; // 상품 테이블\n");
fwrite($f, "\$g5['g5_shop_item_option_table'] = G5_SHOP_TABLE_PREFIX.'item_option'; // 상품옵션 테이블\n");
fwrite($f, "\$g5['g5_shop_item_use_table'] = G5_SHOP_TABLE_PREFIX.'item_use'; // 상품 사용후기 테이블\n");
fwrite($f, "\$g5['g5_shop_item_qa_table'] = G5_SHOP_TABLE_PREFIX.'item_qa'; // 상품 질문답변 테이블\n");
fwrite($f, "\$g5['g5_shop_item_relation_table'] = G5_SHOP_TABLE_PREFIX.'item_relation'; // 관련 상품 테이블\n");
fwrite($f, "\$g5['g5_shop_order_table'] = G5_SHOP_TABLE_PREFIX.'order'; // 주문서 테이블\n");
fwrite($f, "\$g5['g5_shop_order_delete_table'] = G5_SHOP_TABLE_PREFIX.'order_delete'; // 주문서 삭제 테이블\n");
fwrite($f, "\$g5['g5_shop_wish_table'] = G5_SHOP_TABLE_PREFIX.'wish'; // 보관함(위시리스트) 테이블\n");
fwrite($f, "\$g5['g5_shop_coupon_table'] = G5_SHOP_TABLE_PREFIX.'coupon'; // 쿠폰정보 테이블\n");
fwrite($f, "\$g5['g5_shop_coupon_zone_table'] = G5_SHOP_TABLE_PREFIX.'coupon_zone'; // 쿠폰존 테이블\n");
fwrite($f, "\$g5['g5_shop_coupon_log_table'] = G5_SHOP_TABLE_PREFIX.'coupon_log'; // 쿠폰사용정보 테이블\n");
fwrite($f, "\$g5['g5_shop_sendcost_table'] = G5_SHOP_TABLE_PREFIX.'sendcost'; // 추가배송비 테이블\n");
fwrite($f, "\$g5['g5_shop_personalpay_table'] = G5_SHOP_TABLE_PREFIX.'personalpay'; // 개인결제 정보 테이블\n");
fwrite($f, "\$g5['g5_shop_order_address_table'] = G5_SHOP_TABLE_PREFIX.'order_address'; // 배송지이력 정보 테이블\n");
fwrite($f, "\$g5['g5_shop_item_stocksms_table'] = G5_SHOP_TABLE_PREFIX.'item_stocksms'; // 재입고SMS 알림 정보 테이블\n");
fwrite($f, "\$g5['g5_shop_post_log_table'] = G5_SHOP_TABLE_PREFIX.'order_post_log'; // 주문요청 로그 테이블\n");
fwrite($f, "\$g5['g5_shop_order_data_table'] = G5_SHOP_TABLE_PREFIX.'order_data'; // 모바일 결제정보 임시저장 테이블\n");
fwrite($f, "\$g5['g5_shop_inicis_log_table'] = G5_SHOP_TABLE_PREFIX.'inicis_log'; // 이니시스 모바일 계좌이체 로그 테이블\n");
if (!$f) {
install_fail_page($file." 파일을 생성할 수 없습니다.\ndata 디렉토리 쓰기 권한을 확인해 주십시오.", $dblink, $install_table_prefixes);
}
fwrite($f, "?>");
install_file_write($f, "<?php\n");
install_file_write($f, "if (!defined('_GNUBOARD_')) exit;\n");
install_file_write($f, "define('G5_MYSQL_HOST', '".addcslashes($mysql_host, "\\'")."');\n");
install_file_write($f, "define('G5_MYSQL_USER', '".addcslashes($mysql_user, "\\'")."');\n");
install_file_write($f, "define('G5_MYSQL_PASSWORD', '".addcslashes($mysql_pass, "\\'")."');\n");
install_file_write($f, "define('G5_MYSQL_DB', '".addcslashes($mysql_db, "\\'")."');\n");
install_file_write($f, "define('G5_MYSQL_SET_MODE', {$mysql_set_mode});\n\n");
install_file_write($f, "define('G5_TABLE_PREFIX', '{$table_prefix}');\n\n");
install_file_write($f, "define('G5_TOKEN_ENCRYPTION_KEY', '".get_random_token_string(16)."'); // 토큰 암호화에 사용할 키\n\n");
install_file_write($f, "\$g5['write_prefix'] = G5_TABLE_PREFIX.'write_'; // 게시판 테이블명 접두사\n\n");
install_file_write($f, "\$g5['auth_table'] = G5_TABLE_PREFIX.'auth'; // 관리권한 설정 테이블\n");
install_file_write($f, "\$g5['config_table'] = G5_TABLE_PREFIX.'config'; // 기본환경 설정 테이블\n");
install_file_write($f, "\$g5['group_table'] = G5_TABLE_PREFIX.'group'; // 게시판 그룹 테이블\n");
install_file_write($f, "\$g5['group_member_table'] = G5_TABLE_PREFIX.'group_member'; // 게시판 그룹+회원 테이블\n");
install_file_write($f, "\$g5['board_table'] = G5_TABLE_PREFIX.'board'; // 게시판 설정 테이블\n");
install_file_write($f, "\$g5['board_file_table'] = G5_TABLE_PREFIX.'board_file'; // 게시판 첨부파일 테이블\n");
install_file_write($f, "\$g5['board_good_table'] = G5_TABLE_PREFIX.'board_good'; // 게시물 추천,비추천 테이블\n");
install_file_write($f, "\$g5['board_new_table'] = G5_TABLE_PREFIX.'board_new'; // 게시판 새글 테이블\n");
install_file_write($f, "\$g5['login_table'] = G5_TABLE_PREFIX.'login'; // 로그인 테이블 (접속자수)\n");
install_file_write($f, "\$g5['mail_table'] = G5_TABLE_PREFIX.'mail'; // 회원메일 테이블\n");
install_file_write($f, "\$g5['member_table'] = G5_TABLE_PREFIX.'member'; // 회원 테이블\n");
install_file_write($f, "\$g5['member_auto_login_table'] = G5_TABLE_PREFIX.'member_auto_login'; // 자동 로그인 토큰 테이블\n");
install_file_write($f, "\$g5['memo_table'] = G5_TABLE_PREFIX.'memo'; // 메모 테이블\n");
install_file_write($f, "\$g5['poll_table'] = G5_TABLE_PREFIX.'poll'; // 투표 테이블\n");
install_file_write($f, "\$g5['poll_etc_table'] = G5_TABLE_PREFIX.'poll_etc'; // 투표 기타의견 테이블\n");
install_file_write($f, "\$g5['point_table'] = G5_TABLE_PREFIX.'point'; // 포인트 테이블\n");
install_file_write($f, "\$g5['popular_table'] = G5_TABLE_PREFIX.'popular'; // 인기검색어 테이블\n");
install_file_write($f, "\$g5['scrap_table'] = G5_TABLE_PREFIX.'scrap'; // 게시글 스크랩 테이블\n");
install_file_write($f, "\$g5['visit_table'] = G5_TABLE_PREFIX.'visit'; // 방문자 테이블\n");
install_file_write($f, "\$g5['visit_sum_table'] = G5_TABLE_PREFIX.'visit_sum'; // 방문자 합계 테이블\n");
install_file_write($f, "\$g5['uniqid_table'] = G5_TABLE_PREFIX.'uniqid'; // 유니크한 값을 만드는 테이블\n");
install_file_write($f, "\$g5['autosave_table'] = G5_TABLE_PREFIX.'autosave'; // 게시글 작성시 일정시간마다 글을 임시 저장하는 테이블\n");
install_file_write($f, "\$g5['cert_history_table'] = G5_TABLE_PREFIX.'cert_history'; // 인증내역 테이블\n");
install_file_write($f, "\$g5['qa_config_table'] = G5_TABLE_PREFIX.'qa_config'; // 1:1문의 설정테이블\n");
install_file_write($f, "\$g5['qa_content_table'] = G5_TABLE_PREFIX.'qa_content'; // 1:1문의 테이블\n");
install_file_write($f, "\$g5['content_table'] = G5_TABLE_PREFIX.'content'; // 내용(컨텐츠)정보 테이블\n");
install_file_write($f, "\$g5['faq_table'] = G5_TABLE_PREFIX.'faq'; // 자주하시는 질문 테이블\n");
install_file_write($f, "\$g5['faq_master_table'] = G5_TABLE_PREFIX.'faq_master'; // 자주하시는 질문 마스터 테이블\n");
install_file_write($f, "\$g5['new_win_table'] = G5_TABLE_PREFIX.'new_win'; // 새창 테이블\n");
install_file_write($f, "\$g5['menu_table'] = G5_TABLE_PREFIX.'menu'; // 메뉴관리 테이블\n");
install_file_write($f, "\$g5['social_profile_table'] = G5_TABLE_PREFIX.'member_social_profiles'; // 소셜 로그인 테이블\n");
install_file_write($f, "\$g5['member_cert_history_table'] = G5_TABLE_PREFIX.'member_cert_history'; // 본인인증 변경내역 테이블\n");
fclose($f);
if($g5_shop_install) {
install_file_write($f, "\n");
install_file_write($f, "define('G5_USE_SHOP', true);\n\n");
install_file_write($f, "define('G5_SHOP_TABLE_PREFIX', '{$g5_shop_prefix}');\n\n");
install_file_write($f, "\$g5['g5_shop_default_table'] = G5_SHOP_TABLE_PREFIX.'default'; // 쇼핑몰설정 테이블\n");
install_file_write($f, "\$g5['g5_shop_banner_table'] = G5_SHOP_TABLE_PREFIX.'banner'; // 배너 테이블\n");
install_file_write($f, "\$g5['g5_shop_cart_table'] = G5_SHOP_TABLE_PREFIX.'cart'; // 장바구니 테이블\n");
install_file_write($f, "\$g5['g5_shop_category_table'] = G5_SHOP_TABLE_PREFIX.'category'; // 상품분류 테이블\n");
install_file_write($f, "\$g5['g5_shop_event_table'] = G5_SHOP_TABLE_PREFIX.'event'; // 이벤트 테이블\n");
install_file_write($f, "\$g5['g5_shop_event_item_table'] = G5_SHOP_TABLE_PREFIX.'event_item'; // 상품, 이벤트 연결 테이블\n");
install_file_write($f, "\$g5['g5_shop_item_table'] = G5_SHOP_TABLE_PREFIX.'item'; // 상품 테이블\n");
install_file_write($f, "\$g5['g5_shop_item_option_table'] = G5_SHOP_TABLE_PREFIX.'item_option'; // 상품옵션 테이블\n");
install_file_write($f, "\$g5['g5_shop_item_use_table'] = G5_SHOP_TABLE_PREFIX.'item_use'; // 상품 사용후기 테이블\n");
install_file_write($f, "\$g5['g5_shop_item_qa_table'] = G5_SHOP_TABLE_PREFIX.'item_qa'; // 상품 질문답변 테이블\n");
install_file_write($f, "\$g5['g5_shop_item_relation_table'] = G5_SHOP_TABLE_PREFIX.'item_relation'; // 관련 상품 테이블\n");
install_file_write($f, "\$g5['g5_shop_order_table'] = G5_SHOP_TABLE_PREFIX.'order'; // 주문서 테이블\n");
install_file_write($f, "\$g5['g5_shop_order_delete_table'] = G5_SHOP_TABLE_PREFIX.'order_delete'; // 주문서 삭제 테이블\n");
install_file_write($f, "\$g5['g5_shop_wish_table'] = G5_SHOP_TABLE_PREFIX.'wish'; // 보관함(위시리스트) 테이블\n");
install_file_write($f, "\$g5['g5_shop_coupon_table'] = G5_SHOP_TABLE_PREFIX.'coupon'; // 쿠폰정보 테이블\n");
install_file_write($f, "\$g5['g5_shop_coupon_zone_table'] = G5_SHOP_TABLE_PREFIX.'coupon_zone'; // 쿠폰존 테이블\n");
install_file_write($f, "\$g5['g5_shop_coupon_log_table'] = G5_SHOP_TABLE_PREFIX.'coupon_log'; // 쿠폰사용정보 테이블\n");
install_file_write($f, "\$g5['g5_shop_sendcost_table'] = G5_SHOP_TABLE_PREFIX.'sendcost'; // 추가배송비 테이블\n");
install_file_write($f, "\$g5['g5_shop_personalpay_table'] = G5_SHOP_TABLE_PREFIX.'personalpay'; // 개인결제 정보 테이블\n");
install_file_write($f, "\$g5['g5_shop_order_address_table'] = G5_SHOP_TABLE_PREFIX.'order_address'; // 배송지이력 정보 테이블\n");
install_file_write($f, "\$g5['g5_shop_item_stocksms_table'] = G5_SHOP_TABLE_PREFIX.'item_stocksms'; // 재입고SMS 알림 정보 테이블\n");
install_file_write($f, "\$g5['g5_shop_post_log_table'] = G5_SHOP_TABLE_PREFIX.'order_post_log'; // 주문요청 로그 테이블\n");
install_file_write($f, "\$g5['g5_shop_order_data_table'] = G5_SHOP_TABLE_PREFIX.'order_data'; // 모바일 결제정보 임시저장 테이블\n");
install_file_write($f, "\$g5['g5_shop_inicis_log_table'] = G5_SHOP_TABLE_PREFIX.'inicis_log'; // 이니시스 모바일 계좌이체 로그 테이블\n");
}
install_file_write($f, "?>");
$install_file_closed = @fclose($f);
if ($install_file_write_error || !$install_file_closed) {
install_fail_page($file." 파일에 DB 설정을 저장하지 못했습니다.\ndata 디렉토리 용량과 쓰기 권한을 확인해 주십시오.", $dblink, $install_table_prefixes);
}
@chmod($file, G5_FILE_PERMISSION);
?>
@@ -658,7 +675,14 @@ fclose($f);
<?php
// data 디렉토리 및 하위 디렉토리에서는 .htaccess .htpasswd .php .phtml .html .htm .inc .cgi .pl .phar 파일을 실행할수 없게함.
$f = fopen($data_path.'/.htaccess', 'w');
$htaccess_file = $data_path.'/.htaccess';
$install_file_write_error = false;
$f = @fopen($htaccess_file, 'w');
if (!$f) {
install_fail_page($htaccess_file." 파일을 생성할 수 없습니다.\ndata 디렉토리 쓰기 권한을 확인해 주십시오.", $dblink, $install_table_prefixes);
}
$str = <<<EOD
<FilesMatch "\.(htaccess|htpasswd|[Pp][Hh][Pp]|[Pp][Hh][Tt]|[Ss]?[Pp]?[Hh][Tt][Mm][Ll]?|[Ii][Nn][Cc]|[Cc][Gg][Ii]|[Pp][Ll]|[Pp][Hh][Aa][Rr]|[Ss][Vv][Gg][Zz]?)">
Order allow,deny
@@ -666,14 +690,26 @@ Deny from all
</FilesMatch>
RedirectMatch 403 /session/.*
EOD;
fwrite($f, $str);
fclose($f);
install_file_write($f, $str);
$install_file_closed = @fclose($f);
if ($install_file_write_error || !$install_file_closed) {
install_fail_page($htaccess_file." 파일을 저장하지 못했습니다.\ndata 디렉토리 용량과 쓰기 권한을 확인해 주십시오.", $dblink, $install_table_prefixes);
}
if($g5_shop_install) {
@copy('./logo_img', $data_path.'/common/logo_img');
@copy('./logo_img', $data_path.'/common/logo_img2');
@copy('./mobile_logo_img', $data_path.'/common/mobile_logo_img');
@copy('./mobile_logo_img', $data_path.'/common/mobile_logo_img2');
$copy_files = array(
array('./logo_img', $data_path.'/common/logo_img'),
array('./logo_img', $data_path.'/common/logo_img2'),
array('./mobile_logo_img', $data_path.'/common/mobile_logo_img'),
array('./mobile_logo_img', $data_path.'/common/mobile_logo_img2')
);
for ($i=0; $i<count($copy_files); $i++) {
if (!@copy($copy_files[$i][0], $copy_files[$i][1])) {
install_fail_page($copy_files[$i][1]." 파일을 복사하지 못했습니다.\ndata 디렉토리 권한을 확인해 주십시오.", $dblink, $install_table_prefixes);
}
}
}
//-------------------------------------------------------------------------------------------------
?>
+71 -5
View File
@@ -1,8 +1,74 @@
<?php
if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가
if(!extension_loaded('gd') || !function_exists('gd_info')) {
echo '<script>'.PHP_EOL;
echo 'alert("'.G5_VERSION.'의 정상적인 사용을 위해서는 GD 라이브러리가 필요합니다.\nGD 라이브러리가 없을 경우 자동등록방지 문자와 썸네일 기능이 작동하지 않습니다.");'.PHP_EOL;
echo '</script>'.PHP_EOL;
}
$install_library_required_missing = false;
$install_library_checks = array(
array(
'name' => 'MySQL 확장',
'required' => true,
'ok' => (function_exists('mysqli_connect') && G5_MYSQLI_USE) || function_exists('mysql_connect'),
'message' => 'MySQL DB 연결에 필요합니다.'
),
array(
'name' => 'JSON',
'required' => true,
'ok' => function_exists('json_encode') && function_exists('json_decode'),
'message' => '설치 전 DB 점검 응답 처리에 필요합니다.'
),
array(
'name' => 'iconv 또는 mbstring',
'required' => true,
'ok' => function_exists('iconv') || function_exists('mb_convert_encoding'),
'message' => '문자열 인코딩 처리에 필요합니다.'
),
array(
'name' => 'GD',
'required' => false,
'ok' => extension_loaded('gd') && function_exists('gd_info'),
'message' => '자동등록방지 문자와 썸네일 기능에 필요합니다.'
),
array(
'name' => 'OpenSSL',
'required' => false,
'ok' => extension_loaded('openssl'),
'message' => '암호화, 외부 연동, 보안 통신 기능 사용 시 권장됩니다.'
),
array(
'name' => 'cURL',
'required' => false,
'ok' => function_exists('curl_init'),
'message' => '외부 API, 결제, 소셜 연동 사용 시 권장됩니다.'
),
array(
'name' => 'Fileinfo',
'required' => false,
'ok' => function_exists('finfo_open'),
'message' => '업로드 파일의 MIME 타입 확인에 권장됩니다.'
)
);
foreach ($install_library_checks as $check) {
if ($check['required'] && !$check['ok']) {
$install_library_required_missing = true;
break;
}
}
?>
<div class="ins_inner">
<h2>서버 환경 점검</h2>
<ul>
<?php for ($i=0; $i<count($install_library_checks); $i++) { ?>
<li>
<strong><?php echo $install_library_checks[$i]['ok'] ? '확인' : ($install_library_checks[$i]['required'] ? '필수 누락' : '권장 누락'); ?></strong>
- <?php echo $install_library_checks[$i]['name']; ?>
(<?php echo $install_library_checks[$i]['required'] ? '필수' : '권장'; ?>)
: <?php echo $install_library_checks[$i]['message']; ?>
</li>
<?php } ?>
</ul>
<?php if ($install_library_required_missing) { ?>
<p>필수 서버 환경이 준비되지 않아 설치를 진행할 수 없습니다. 누락된 PHP 확장을 설치한 뒤 새로고침해 주십시오.</p>
<?php } else { ?>
<p>필수 서버 환경을 확인했습니다. 권장 항목은 설치 후 일부 기능 사용에 영향을 줄 수 있습니다.</p>
<?php } ?>
</div>
+13
View File
@@ -64,6 +64,19 @@ function certify_win_open(type, url, event) {
var AUTH_POP = window.open(url,'auth_popup', winopts + position);
}
}
else if(type == 'kcp_v2-hp')
{
var width = 410;
var height = 500;
var leftpos = screen.width / 2 - ( width / 2 );
var toppos = screen.height / 2 - ( height / 2 );
var winopts = "width=" + width + ", height=" + height + ", toolbar=no,status=no,statusbar=no,menubar=no,scrollbars=no,resizable=no";
var position = ",left=" + leftpos + ", top=" + toppos;
var AUTH_POP = window.open(url, 'auth_popup', winopts + position);
if (AUTH_POP) AUTH_POP.focus();
}
else if(type == 'lg-hp')
{
+109 -9
View File
@@ -112,11 +112,14 @@ function goto_url($url)
if (!headers_sent())
header('Location: '.$url);
else {
$js_replace = array('\\' => '\\\\', '"' => '\\"', "'" => '\\u0027', '/' => '\\/', "\r" => '\\r', "\n" => '\\n', "\t" => '\\t', '<' => '\\u003C', '>' => '\\u003E', '&' => '\\u0026', "\xE2\x80\xA8" => '\\u2028', "\xE2\x80\xA9" => '\\u2029');
$js_url = function_exists('get_js_safe_string') ? get_js_safe_string($url) : '"'.strtr((string)$url, $js_replace).'"';
$html_url = htmlspecialchars($url, ENT_QUOTES);
echo '<script>';
echo 'location.replace("'.$url.'");';
echo 'location.replace('.$js_url.');';
echo '</script>';
echo '<noscript>';
echo '<meta http-equiv="refresh" content="0;url='.$url.'" />';
echo '<meta http-equiv="refresh" content="0;url='.$html_url.'" />';
echo '</noscript>';
}
exit;
@@ -179,6 +182,59 @@ function get_cookie($cookie_name)
}
// JavaScript 문자열 컨텍스트에 삽입할 값을 안전하게 이스케이프하여 따옴표를 포함한 JS 리터럴로 반환
// PHP 5.3+ 에서는 json_encode 의 JSON_HEX_* 플래그를 사용하고, 5.2 환경에서는 직접 치환으로 폴백
if (!function_exists('get_js_safe_string')) {
function get_js_safe_string($s)
{
$s = (string)$s;
if (defined('JSON_HEX_TAG')) {
$flags = JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT;
if (defined('JSON_UNESCAPED_UNICODE')) {
$flags |= JSON_UNESCAPED_UNICODE;
}
$encoded = @json_encode($s, $flags);
if ($encoded !== false && $encoded !== null) {
return $encoded;
}
}
return '"' . strtr($s, array(
'\\' => '\\\\',
'"' => '\\"',
"'" => '\\u0027',
'/' => '\\/',
"\r" => '\\r',
"\n" => '\\n',
"\t" => '\\t',
'<' => '\\u003C',
'>' => '\\u003E',
'&' => '\\u0026',
"\xE2\x80\xA8" => '\\u2028',
"\xE2\x80\xA9" => '\\u2029',
)) . '"';
}
}
// CSV/Excel 셀에 출력할 값을 안전하게 변환 (수식 인젝션 방지)
// 값이 = + - @ TAB CR 로 시작하면 작은따옴표를 prefix 해 수식 해석을 차단
if (!function_exists('csv_safe_cell')) {
function csv_safe_cell($v)
{
if ($v === null || $v === '') {
return $v;
}
$s = (string)$v;
$first = substr($s, 0, 1);
if ($first === '=' || $first === '+' || $first === '-' || $first === '@'
|| $first === "\t" || $first === "\r") {
return "'" . $s;
}
return $s;
}
}
// 경고메세지를 경고창으로
function alert($msg='', $url='', $error=true, $post=false)
{
@@ -3196,8 +3252,7 @@ class html_process {
if (isset(self::$instances[self::$id])) {
return self::$instances[self::$id];
}
$calledClass = get_called_class();
return self::$instances[self::$id] = new $calledClass;
return self::$instances[self::$id] = new self;
}
public static function merge_stylesheet($stylesheet, $order)
@@ -3249,7 +3304,7 @@ class html_process {
$member['mb_id'] = '';
}
if ($tmp_row['cnt']) {
if (!empty($tmp_row['cnt'])) {
$tmp_sql = " update {$g5['login_table']} set mb_id = '{$member['mb_id']}', lo_datetime = '".G5_TIME_YMDHIS."', lo_location = '{$g5['lo_location']}', lo_url = '{$g5['lo_url']}' where lo_ip = '{$_SERVER['REMOTE_ADDR']}' ";
sql_query($tmp_sql, FALSE);
} else {
@@ -3688,7 +3743,9 @@ function module_exec_check($exe, $type)
}
if($error) {
$error = '<script>alert("'.$error.'");</script>';
$js_replace = array('\\' => '\\\\', '"' => '\\"', "'" => '\\u0027', '/' => '\\/', "\r" => '\\r', "\n" => '\\n', "\t" => '\\t', '<' => '\\u003C', '>' => '\\u003E', '&' => '\\u0026', "\xE2\x80\xA8" => '\\u2028', "\xE2\x80\xA9" => '\\u2029');
$js_error = function_exists('get_js_safe_string') ? get_js_safe_string($error) : '"'.strtr((string)$error, $js_replace).'"';
$error = '<script>alert('.$js_error.');</script>';
}
return $error;
@@ -4113,13 +4170,16 @@ function check_url_host($url, $msg='', $return_url=G5_URL, $is_redirect=false)
if ((isset($p['scheme']) && $p['scheme']) || (isset($p['host']) && $p['host']) || $is_host_check) {
//if ($p['host'].(isset($p['port']) ? ':'.$p['port'] : '') != $_SERVER['HTTP_HOST']) {
if (run_replace('check_same_url_host', (($p['host'] != $host) || $is_host_check), $p, $host, $is_host_check, $return_url, $is_redirect)) {
$js_replace = array('\\' => '\\\\', '"' => '\\"', "'" => '\\u0027', '/' => '\\/', "\r" => '\\r', "\n" => '\\n', "\t" => '\\t', '<' => '\\u003C', '>' => '\\u003E', '&' => '\\u0026', "\xE2\x80\xA8" => '\\u2028', "\xE2\x80\xA9" => '\\u2029');
$js_return_url = function_exists('get_js_safe_string') ? get_js_safe_string($return_url) : '"'.strtr((string)$return_url, $js_replace).'"';
$html_return_url = htmlspecialchars($return_url, ENT_QUOTES);
echo '<script>'.PHP_EOL;
echo 'alert("url에 타 도메인을 지정할 수 없습니다.");'.PHP_EOL;
echo 'document.location.href = "'.$return_url.'";'.PHP_EOL;
echo 'document.location.href = '.$js_return_url.';'.PHP_EOL;
echo '</script>'.PHP_EOL;
echo '<noscript>'.PHP_EOL;
echo '<p>'.$msg.'</p>'.PHP_EOL;
echo '<p><a href="'.$return_url.'">돌아가기</a></p>'.PHP_EOL;
echo '<p><a href="'.$html_return_url.'">돌아가기</a></p>'.PHP_EOL;
echo '</noscript>'.PHP_EOL;
exit;
}
@@ -4577,6 +4637,46 @@ function get_call_func_cache($func, $args=array()){
return $result;
}
function g5_check_data_htaccess($data_path='')
{
if ($data_path === '') {
if (!defined('G5_DATA_PATH')) {
return false;
}
$data_path = G5_DATA_PATH;
}
$htaccess_file = $data_path.'/.htaccess';
if (@is_file($htaccess_file) && @filesize($htaccess_file) > 0) {
return true;
}
if (!@is_dir($data_path) || !@is_writable($data_path)) {
return false;
}
$content = <<<EOD
<FilesMatch "\.(htaccess|htpasswd|[Pp][Hh][Pp]|[Pp][Hh][Tt]|[Ss]?[Pp]?[Hh][Tt][Mm][Ll]?|[Ii][Nn][Cc]|[Cc][Gg][Ii]|[Pp][Ll]|[Pp][Hh][Aa][Rr]|[Ss][Vv][Gg][Zz]?)">
Order allow,deny
Deny from all
</FilesMatch>
RedirectMatch 403 /session/.*
EOD;
$result = @file_put_contents($htaccess_file, $content);
if ($result === false) {
return false;
}
if (defined('G5_FILE_PERMISSION')) {
@chmod($htaccess_file, G5_FILE_PERMISSION);
}
return true;
}
// include 하는 경로에 data file 경로나 안전하지 않은 경로가 있는지 체크합니다.
function is_include_path_check($path='', $is_input='')
{
@@ -4602,7 +4702,7 @@ function is_include_path_check($path='', $is_input='')
return false;
}
$dirname_doc_root = !empty($_SERVER['DOCUMENT_ROOT']) ? dirname($_SERVER['DOCUMENT_ROOT']) : dirname(dirname(dirname(__DIR__)));
$dirname_doc_root = !empty($_SERVER['DOCUMENT_ROOT']) ? dirname($_SERVER['DOCUMENT_ROOT']) : dirname(dirname(dirname(dirname(__FILE__))));
// 웹서버 폴더만 허용
if ($dirname_doc_root && file_exists($path) && strpos(realpath($path), realpath($dirname_doc_root)) !== 0) {
+1 -1
View File
@@ -60,7 +60,7 @@ class LMS {
$this->Result = array(); // 발송결과값이 배열로 들어간다.
}
function Add($strDest, $strCallBack, $strCaller, $strSubject, $strURL, $strData, $strDate="", $nCount) {
function Add($strDest, $strCallBack, $strCaller, $strSubject, $strURL, $strData, $strDate="", $nCount=0) {
global $config;
// 문자 타입별 Port 설정.
+7 -3
View File
@@ -1405,11 +1405,15 @@ function alert_opener($msg='', $url='')
global $g5;
if (!$msg) $msg = '올바른 방법으로 이용해 주십시오.';
$msg = strip_tags($msg);
$js_replace = array('\\' => '\\\\', '"' => '\\"', "'" => '\\u0027', '/' => '\\/', "\r" => '\\r', "\n" => '\\n', "\t" => '\\t', '<' => '\\u003C', '>' => '\\u003E', '&' => '\\u0026', "\xE2\x80\xA8" => '\\u2028', "\xE2\x80\xA9" => '\\u2029');
$js_msg = function_exists('get_js_safe_string') ? get_js_safe_string($msg) : '"'.strtr((string)$msg, $js_replace).'"';
$js_url = function_exists('get_js_safe_string') ? get_js_safe_string($url) : '"'.strtr((string)$url, $js_replace).'"';
echo "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">";
echo "<script>";
echo "alert(\"$msg\");";
echo "opener.location.href=\"$url\";";
echo "alert(".$js_msg.");";
echo "opener.location.href=".$js_url.";";
echo "self.close();";
echo "</script>";
exit;
@@ -2976,4 +2980,4 @@ function is_coupon_downloaded($mb_id, $cz_id)
//==============================================================================
// 쇼핑몰 라이브러리 모음 끝
//==============================================================================;
//==============================================================================;
+2 -1
View File
@@ -1,7 +1,8 @@
<?php
include_once('../../common.php');
if (isset($_REQUEST['sort'])) {
// SQL 주석 토큰 차단 추가 — 데스크톱 shop/_common.php 와 동일 패턴
if (isset($_REQUEST['sort']) && !preg_match("/(--|#|\/\*|\*\/)/", $_REQUEST['sort'])) {
$sort = trim($_REQUEST['sort']);
$sort = preg_replace("/[\<\>\'\"\\\'\\\"\%\=\(\)\s]/", "", $sort);
} else {
+3
View File
@@ -36,6 +36,9 @@ if (!$sst) {
$sst = "a.iq_id";
$sod = "desc";
}
// 정렬 컬럼/방향 화이트리스트
$sst = in_array($sst, array('a.iq_id', 'a.iq_datetime', 'a.it_id', 'b.it_name'), true) ? $sst : 'a.iq_id';
$sod = preg_match("/^(asc|desc)$/i", $sod) ? $sod : 'desc';
$sql_order = " order by $sst $sod ";
$sql = " select count(*) as cnt
+3
View File
@@ -36,6 +36,9 @@ if (!$sst) {
$sst = "a.is_id";
$sod = "desc";
}
// 정렬 컬럼/방향 화이트리스트
$sst = in_array($sst, array('a.is_id', 'a.is_datetime', 'a.is_score', 'a.it_id', 'b.it_name'), true) ? $sst : 'a.is_id';
$sod = preg_match("/^(asc|desc)$/i", $sod) ? $sod : 'desc';
$sql_order = " order by $sst $sod ";
$sql = " select count(*) as cnt
+3 -2
View File
@@ -169,7 +169,8 @@
$c_PayPlus->m_res_msg = "연동 오류|tran_cd값이 설정되지 않았습니다.";
}
if ($res_cd != '0000')
// 가상계좌 발급 정상 응답은 V000 으로 옴 (KCP 정책 변경)
if ($res_cd != '0000' && $res_cd != 'V000')
{
$res_msg = iconv("euc-kr", "utf-8", $res_msg);
@@ -202,7 +203,7 @@
/* = -------------------------------------------------------------------------- = */
if ( $req_tx == "pay" )
{
if( $res_cd == "0000" )
if( $res_cd == "0000" || $res_cd == "V000" )
{
$tno = $c_PayPlus->mf_get_res_data( "tno" ); // KCP 거래 고유 번호
$amount = $c_PayPlus->mf_get_res_data( "amount" ); // KCP 실제 거래 금액
+3
View File
@@ -1,6 +1,9 @@
<?php
include_once('./_common.php');
// 상품 정렬 컬럼 화이트리스트 — 데스크톱 shop/listtype.php 와 동일 패턴
$sort = (isset($_REQUEST['sort']) && in_array($_REQUEST['sort'], array('it_name', 'it_sum_qty', 'it_price', 'it_use_avg', 'it_use_cnt', 'it_update_time'))) ? $_REQUEST['sort'] : '';
$type = isset($_REQUEST['type']) ? (int) preg_replace("/[^0-9]/", "", $_REQUEST['type']) : 1;
if ($type === 1) $g5['title'] = '히트상품';
else if ($type === 2) $g5['title'] = '추천상품';
+44 -4
View File
@@ -608,14 +608,14 @@ $od_zip2 = substr($od_zip, 3);
$od_addr1 = addslashes(clean_xss_tags(stripslashes($od_addr1)));
$od_addr2 = addslashes(clean_xss_tags(stripslashes($od_addr2)));
$od_addr3 = addslashes(clean_xss_tags(stripslashes($od_addr3)));
$od_addr_jibeon = preg_match("/^(N|R)$/", $od_addr_jibeon) ? $od_addr_jibeon : '';
$od_addr_jibeon = preg_match("/^(N|R|J)$/", $od_addr_jibeon) ? $od_addr_jibeon : '';
$od_b_name = addslashes(clean_xss_tags(stripslashes($od_b_name)));
$od_b_tel = addslashes(clean_xss_tags(stripslashes($od_b_tel)));
$od_b_hp = addslashes(clean_xss_tags(stripslashes($od_b_hp)));
$od_b_addr1 = addslashes(clean_xss_tags(stripslashes($od_b_addr1)));
$od_b_addr2 = addslashes(clean_xss_tags(stripslashes($od_b_addr2)));
$od_b_addr3 = addslashes(clean_xss_tags(stripslashes($od_b_addr3)));
$od_b_addr_jibeon = preg_match("/^(N|R)$/", $od_b_addr_jibeon) ? $od_b_addr_jibeon : '';
$od_b_addr_jibeon = preg_match("/^(N|R|J)$/", $od_b_addr_jibeon) ? $od_b_addr_jibeon : '';
$od_memo = addslashes(clean_xss_tags(stripslashes($od_memo), 0, 1, 0, 0));
$od_deposit_name = addslashes(clean_xss_tags(stripslashes($od_deposit_name)));
$od_tax_flag = $default['de_tax_flag_use'];
@@ -750,8 +750,48 @@ if(!$result) {
}
// 회원이면서 포인트를 사용했다면 포인트 테이블에 사용을 추가
if ($is_member && $od_receipt_point)
insert_point($member['mb_id'], (-1) * $od_receipt_point, "주문번호 $od_id 결제");
// 동시 주문 race condition 방지 — 회원 단위 GET_LOCK + 잔액 재조회
if ($is_member && $od_receipt_point) {
$point_lock_key = 'g5pt_order_'.md5($member['mb_id']);
$lock_row = sql_fetch(" select get_lock('$point_lock_key', 5) as lk ");
$lock_acquired = !empty($lock_row['lk']);
$point_shortage = false;
if ($lock_acquired) {
$current_point = (int) get_point_sum($member['mb_id']);
if ($current_point >= $od_receipt_point) {
insert_point($member['mb_id'], (-1) * $od_receipt_point, "주문번호 $od_id 결제");
} else {
$point_shortage = true;
}
sql_query(" do release_lock('$point_lock_key') ");
} else {
// lock timeout — 안전을 위해 결제 취소 처리
$point_shortage = true;
}
if ($point_shortage) {
// race condition 으로 잔액 부족 — PG 환불 + 장바구니 복구 + 주문 삭제
if ($tno) {
$cancel_msg = '포인트 잔액 부족으로 결제 취소 (동시 주문 race)';
include G5_SHOP_PATH.'/cancel_pg.inc.php';
}
// 장바구니 복구
sql_query(" update {$g5['g5_shop_cart_table']} set od_id = '$tmp_cart_id', ct_status = '쇼핑' where od_id = '$od_id' ", false);
// 주문 삭제
sql_query(" delete from {$g5['g5_shop_order_table']} where od_id = '$od_id' ");
if (function_exists('add_order_post_log')) {
add_order_post_log("동시 주문 race 로 인한 포인트 잔액 부족. 주문 $od_id 취소.");
}
die('<p>회원님의 포인트 잔액이 부족하여 주문이 완료되지 않았습니다.</p><p>'.strtoupper($od_pg).'를 이용한 전자결제(신용카드, 계좌이체, 가상계좌 등)은 자동 취소되었습니다.</p>');
}
}
$od_memo = nl2br(htmlspecialchars2(stripslashes($od_memo))) . "&nbsp;";
+1 -1
View File
@@ -666,7 +666,7 @@ if($od['od_pg'] == 'lg') {
</tr>
<tr>
<th scope="col"><label for="req_name">입금자명</label></th>
<td><input type="text" name="req_name" value="<?php echo $od['od_deposit_name']; ?>"></td>
<td><input type="text" name="req_name" value="<?php echo get_text($od['od_deposit_name']); ?>"></td>
</tr>
<tr>
<th scope="col"><label for="noti_url">입금통보 URL</label></th>
+1 -1
View File
@@ -6,7 +6,7 @@ if (!defined("_GNUBOARD_")) exit; // 개별 페이지 접근 불가
<input type="hidden" name="method" value="">
<input type="hidden" name="orderId" value="<?php echo isset($od_id) ? $od_id : ''; ?>">
<input type="hidden" name="orderName" value="<?php echo isset($goods) ? $goods : ''; ?>">
<input type="hidden" name="customerName" value="<?php echo isset($od_name) ? $od_name : ''; ?>">
<input type="hidden" name="customerName" value="<?php echo isset($od_name) ? get_text($od_name) : ''; ?>">
<input type="hidden" name="customerEmail" value="<?php echo isset($od_email) ? $od_email : ''; ?>">
<input type="hidden" name="customerMobilePhone" value="<?php echo isset($od_hp) ? $od_hp : ''; ?>">
<input type="hidden" name="cardUseEscrow" value="false">
+1 -1
View File
@@ -5,7 +5,7 @@ if (!defined("_GNUBOARD_")) exit; // 개별 페이지 접근 불가
<input type="hidden" name="method" value="">
<input type="hidden" name="orderId" value="<?php echo isset($od_id) ? $od_id : ''; ?>">
<input type="hidden" name="orderName" value="<?php echo isset($goods) ? $goods : ''; ?>">
<input type="hidden" name="customerName" value="<?php echo isset($od_name) ? $od_name : ''; ?>">
<input type="hidden" name="customerName" value="<?php echo isset($od_name) ? get_text($od_name) : ''; ?>">
<input type="hidden" name="customerEmail" value="<?php echo isset($od_email) ? $od_email : ''; ?>">
<input type="hidden" name="customerMobilePhone" value="<?php echo isset($od_hp) ? $od_hp : ''; ?>">
<input type="hidden" name="cardUseEscrow" value="false">
+2 -2
View File
@@ -40,7 +40,7 @@ $sql = "
{$addQuery}
";
$res = sql_fetch($sql);
$dt_data = [];
$dt_data = array();
if (isset($res['dt_data'])) {
$dt_data = unserialize(base64_decode($res['dt_data']));
}
@@ -189,4 +189,4 @@ function getFormObject() {
</script>
<?php
include_once(G5_PATH.'/tail.sub.php');
include_once(G5_PATH.'/tail.sub.php');
@@ -117,7 +117,7 @@ var char_max = parseInt(<?php echo $comment_max ?>); // 최대
<?php if ($comment_min || $comment_max) { ?><strong id="char_cnt"><span id="char_count"></span>글자</strong><?php } ?>
<textarea id="wr_content" name="wr_content" required title="댓글 내용"
<?php if ($comment_min || $comment_max) { ?>onkeyup="check_byte('wr_content', 'char_count');"<?php } ?> placeholder="댓글내용을 입력해주세요"><?php echo $c_wr_content; ?></textarea>
<?php if ($comment_min || $comment_max) { ?>onkeyup="check_byte('wr_content', 'char_count');"<?php } ?> placeholder="댓글내용을 입력해주세요"><?php echo get_text($c_wr_content); ?></textarea>
<?php if ($comment_min || $comment_max) { ?><script> check_byte('wr_content', 'char_count'); </script><?php } ?>
<div class="bo_vc_w_wr">
@@ -116,7 +116,7 @@ var char_max = parseInt(<?php echo $comment_max ?>); // 최대
<?php if ($comment_min || $comment_max) { ?><strong id="char_cnt"><span id="char_count"></span>글자</strong><?php } ?>
<textarea id="wr_content" name="wr_content" required title="댓글 내용"
<?php if ($comment_min || $comment_max) { ?>onkeyup="check_byte('wr_content', 'char_count');"<?php } ?> placeholder="댓글내용을 입력해주세요"><?php echo $c_wr_content; ?></textarea>
<?php if ($comment_min || $comment_max) { ?>onkeyup="check_byte('wr_content', 'char_count');"<?php } ?> placeholder="댓글내용을 입력해주세요"><?php echo get_text($c_wr_content); ?></textarea>
<?php if ($comment_min || $comment_max) { ?><script> check_byte('wr_content', 'char_count'); </script><?php } ?>
<div class="bo_vc_w_wr">
@@ -121,6 +121,10 @@ if ($config['cf_cert_use'] && ($config['cf_cert_simple'] || $config['cf_cert_ipi
$cert_url = G5_KCPCERT_URL.'/kcpcert_form.php';
$cert_type = 'kcp-hp';
break;
case 'kcp_v2':
$cert_url = G5_KCPCERT_V2_URL.'/kcpcert_form.php';
$cert_type = 'kcp_v2-hp';
break;
case 'lg':
$cert_url = G5_LGXPAY_URL.'/AuthOnlyReq.php';
$cert_type = 'lg-hp';
@@ -92,6 +92,10 @@ $(function() {
$cert_url = G5_KCPCERT_URL.'/kcpcert_form.php';
$cert_type = 'kcp-hp';
break;
case 'kcp_v2':
$cert_url = G5_KCPCERT_V2_URL.'/kcpcert_form.php';
$cert_type = 'kcp_v2-hp';
break;
case 'lg':
$cert_url = G5_LGXPAY_URL.'/AuthOnlyReq.php';
$cert_type = 'lg-hp';
@@ -328,10 +328,10 @@ if ($config['cf_cert_use'] && ($config['cf_cert_simple'] || $config['cf_cert_ipi
<!-- (선택) 개인정보 제3자 제공 동의 -->
<!-- SMS 사용시에만 -->
<?php
$configKeys = ['cf_sms_use'];
$companies = ['icode' => '아이코드'];
$configKeys = array('cf_sms_use');
$companies = array('icode' => '아이코드');
$usedCompanies = [];
$usedCompanies = array();
foreach ($configKeys as $key) {
if (!empty($config[$key]) && isset($companies[$config[$key]])) {
$usedCompanies[] = $companies[$config[$key]];
@@ -378,7 +378,7 @@ if ($config['cf_cert_use'] && ($config['cf_cert_simple'] || $config['cf_cert_ipi
</div>
</form>
<?php include_once(__DIR__ . '/consent_modal.inc.php'); ?>
<?php include_once(dirname(__FILE__) . '/consent_modal.inc.php'); ?>
<script>
$(function() {
@@ -428,6 +428,10 @@ if ($config['cf_cert_use'] && ($config['cf_cert_simple'] || $config['cf_cert_ipi
$cert_url = G5_KCPCERT_URL.'/kcpcert_form.php';
$cert_type = 'kcp-hp';
break;
case 'kcp_v2':
$cert_url = G5_KCPCERT_V2_URL.'/kcpcert_form.php';
$cert_type = 'kcp_v2-hp';
break;
case 'lg':
$cert_url = G5_LGXPAY_URL.'/AuthOnlyReq.php';
$cert_type = 'lg-hp';
@@ -628,4 +632,4 @@ if ($config['cf_cert_use'] && ($config['cf_cert_simple'] || $config['cf_cert_ipi
childPromo.forEach(cb => cb.addEventListener('change', syncParentFromChildren));
});
</script>
</div>
</div>
@@ -213,10 +213,10 @@ $email_msg = $is_exists_email ? '등록할 이메일이 중복되었습니다.
<!-- (선택) 개인정보 제3자 제공 동의 -->
<!-- SMS 사용시에만 -->
<?php
$configKeys = ['cf_sms_use'];
$companies = ['icode' => '아이코드'];
$configKeys = array('cf_sms_use');
$companies = array('icode' => '아이코드');
$usedCompanies = [];
$usedCompanies = array();
foreach ($configKeys as $key) {
if (!empty($config[$key]) && isset($companies[$config[$key]])) {
$usedCompanies[] = $companies[$config[$key]];
@@ -298,7 +298,7 @@ $email_msg = $is_exists_email ? '등록할 이메일이 중복되었습니다.
</div>
</div>
<?php include_once(__DIR__ . '/consent_modal.inc.php'); ?>
<?php include_once(dirname(__FILE__) . '/consent_modal.inc.php'); ?>
<script>
$(function() {
@@ -357,6 +357,10 @@ $email_msg = $is_exists_email ? '등록할 이메일이 중복되었습니다.
$cert_url = G5_KCPCERT_URL.'/kcpcert_form.php';
$cert_type = 'kcp-hp';
break;
case 'kcp_v2':
$cert_url = G5_KCPCERT_V2_URL.'/kcpcert_form.php';
$cert_type = 'kcp_v2-hp';
break;
case 'lg':
$cert_url = G5_LGXPAY_URL.'/AuthOnlyReq.php';
$cert_type = 'lg-hp';
@@ -465,4 +469,4 @@ $email_msg = $is_exists_email ? '등록할 이메일이 중복되었습니다.
});
</script>
<!-- } 회원정보 입력/수정 끝 -->
<!-- } 회원정보 입력/수정 끝 -->
@@ -51,22 +51,24 @@ class PHPMailerOAuthGoogle
private function getProvider()
{
return new League\OAuth2\Client\Provider\Google([
$providerClass = 'League\\OAuth2\\Client\\Provider\\Google';
return new $providerClass(array(
'clientId' => $this->oauthClientId,
'clientSecret' => $this->oauthClientSecret
]);
));
}
private function getGrant()
{
return new \League\OAuth2\Client\Grant\RefreshToken();
$grantClass = 'League\\OAuth2\\Client\\Grant\\RefreshToken';
return new $grantClass();
}
private function getToken()
{
$provider = $this->getProvider();
$grant = $this->getGrant();
return $provider->getAccessToken($grant, ['refresh_token' => $this->oauthRefreshToken]);
return $provider->getAccessToken($grant, array('refresh_token' => $this->oauthRefreshToken));
}
public function getOauth64()
+10 -102
View File
@@ -13,122 +13,30 @@
* PHP Version 5.4
*/
namespace League\OAuth2\Client\Provider;
if (version_compare(PHP_VERSION, '5.4.0', '<')) {
exit('This OAuth token helper requires PHP 5.4 or later.');
}
require 'vendor/autoload.php';
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use League\OAuth2\Client\Token\AccessToken;
use League\OAuth2\Client\Tool\BearerAuthorizationTrait;
use Psr\Http\Message\ResponseInterface;
session_start();
//If this automatic URL doesn't work, set it yourself manually
$redirectUri = isset($_SERVER['HTTPS']) ? 'https://' : 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
$redirectUri = (isset($_SERVER['HTTPS']) ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
//$redirectUri = 'http://localhost/phpmailer/get_oauth_token.php';
//These details obtained are by setting up app in Google developer console.
$clientId = 'RANDOMCHARS-----duv1n2.apps.googleusercontent.com';
$clientSecret = 'RANDOMCHARS-----lGyjPcRtvP';
class Google extends AbstractProvider
{
use BearerAuthorizationTrait;
const ACCESS_TOKEN_RESOURCE_OWNER_ID = 'id';
/**
* @var string If set, this will be sent to google as the "access_type" parameter.
* @link https://developers.google.com/accounts/docs/OAuth2WebServer#offline
*/
protected $accessType;
/**
* @var string If set, this will be sent to google as the "hd" parameter.
* @link https://developers.google.com/accounts/docs/OAuth2Login#hd-param
*/
protected $hostedDomain;
/**
* @var string If set, this will be sent to google as the "scope" parameter.
* @link https://developers.google.com/gmail/api/auth/scopes
*/
protected $scope;
public function getBaseAuthorizationUrl()
{
return 'https://accounts.google.com/o/oauth2/auth';
}
public function getBaseAccessTokenUrl(array $params)
{
return 'https://accounts.google.com/o/oauth2/token';
}
public function getResourceOwnerDetailsUrl(AccessToken $token)
{
return ' ';
}
protected function getAuthorizationParameters(array $options)
{
if (is_array($this->scope)) {
$separator = $this->getScopeSeparator();
$this->scope = implode($separator, $this->scope);
}
$params = array_merge(
parent::getAuthorizationParameters($options),
array_filter([
'hd' => $this->hostedDomain,
'access_type' => $this->accessType,
'scope' => $this->scope,
// if the user is logged in with more than one account ask which one to use for the login!
'authuser' => '-1'
])
);
return $params;
}
protected function getDefaultScopes()
{
return [
'email',
'openid',
'profile',
];
}
protected function getScopeSeparator()
{
return ' ';
}
protected function checkResponse(ResponseInterface $response, $data)
{
if (!empty($data['error'])) {
$code = 0;
$error = $data['error'];
if (is_array($error)) {
$code = $error['code'];
$error = $error['message'];
}
throw new IdentityProviderException($error, $code, $data);
}
}
protected function createResourceOwner(array $response, AccessToken $token)
{
return new GoogleUser($response);
}
}
//Set Redirect URI in Developer Console as [https/http]://<yourdomain>/<folder>/get_oauth_token.php
$provider = new Google(
$providerClass = 'League\\OAuth2\\Client\\Provider\\Google';
if (!class_exists($providerClass)) {
exit('League OAuth2 Google provider class was not found. Install the Composer dependencies first.');
}
$provider = new $providerClass(
array(
'clientId' => $clientId,
'clientSecret' => $clientSecret,
+59 -26
View File
@@ -1,7 +1,5 @@
<?php
namespace phpbrowscap;
/**
* Browscap.ini parsing class with caching and update capabilities
*
@@ -219,14 +217,14 @@ class Browscap
date_default_timezone_set(date_default_timezone_get());
if (!isset($cache_dir)) {
throw new Exception('You have to provide a path to read/store the browscap cache file');
throw new Browscap_Exception('You have to provide a path to read/store the browscap cache file');
}
$old_cache_dir = $cache_dir;
$cache_dir = realpath($cache_dir);
if (false === $cache_dir) {
throw new Exception(
throw new Browscap_Exception(
sprintf(
'The cache path %s is invalid. Are you sure that it exists and that you have permission to access it?',
$old_cache_dir
@@ -318,7 +316,7 @@ class Browscap
$cache_file = $this->cacheDir . $this->cacheFilename;
if (!$this->_cacheLoaded && !$this->_loadCache($cache_file)) {
throw new Exception('Cannot load cache file - the cache format is not compatible.');
throw new Browscap_Exception('Cannot load cache file - the cache format is not compatible.');
}
// Automatically detect the useragent
@@ -549,10 +547,10 @@ class Browscap
$lockRes = fopen($lockfile, 'w+');
if (false === $lockRes) {
throw new Exception(sprintf('error opening lockfile %s', $lockfile));
throw new Browscap_Exception(sprintf('error opening lockfile %s', $lockfile));
}
if (false === flock($lockRes, LOCK_EX | LOCK_NB)) {
throw new Exception(sprintf('error locking lockfile %s', $lockfile));
throw new Browscap_Exception(sprintf('error locking lockfile %s', $lockfile));
}
$ini_path = $this->cacheDir . $this->iniFilename;
@@ -586,12 +584,12 @@ class Browscap
// asume that all will be ok
if (false === ($fileRes = fopen($tmpFile, 'w+'))) {
// opening the temparary file failed
throw new Exception('opening temporary file failed');
throw new Browscap_Exception('opening temporary file failed');
}
if (false === fwrite($fileRes, $this->_buildCache())) {
// writing to the temparary file failed
throw new Exception('writing to temporary file failed');
throw new Browscap_Exception('writing to temporary file failed');
}
fclose($fileRes);
@@ -600,7 +598,7 @@ class Browscap
// renaming file failed, remove temp file
@unlink($tmpFile);
throw new Exception('could not rename temporary file to the cache file');
throw new Browscap_Exception('could not rename temporary file to the cache file');
}
@flock($lockRes, LOCK_UN);
@@ -611,6 +609,41 @@ class Browscap
return true;
}
/**
* Parse ini content on PHP versions that do not provide parse_ini_string().
*
* @param string $iniContent
* @param bool $processSections
*
* @return array
*/
protected function parseIniString($iniContent, $processSections = true)
{
if (function_exists('parse_ini_string')) {
if (defined('INI_SCANNER_RAW')) {
return parse_ini_string($iniContent, $processSections, INI_SCANNER_RAW);
}
return parse_ini_string($iniContent, $processSections);
}
$tmpDir = function_exists('sys_get_temp_dir') ? sys_get_temp_dir() : dirname(__FILE__);
$tmpFile = tempnam($tmpDir, 'browscap_ini_');
if ($tmpFile === false) {
throw new Browscap_Exception('could not create temporary ini file');
}
if (file_put_contents($tmpFile, $iniContent) === false) {
@unlink($tmpFile);
throw new Browscap_Exception('could not write temporary ini file');
}
$parsed = parse_ini_file($tmpFile, $processSections);
@unlink($tmpFile);
return is_array($parsed) ? $parsed : array();
}
/**
* creates the cache content
*
@@ -619,7 +652,7 @@ class Browscap
*/
protected function createCacheOldWay($iniContent, $actLikeNewVersion = false)
{
$browsers = parse_ini_string($iniContent, true, INI_SCANNER_RAW);
$browsers = $this->parseIniString($iniContent, true);
if ($actLikeNewVersion) {
$this->_source_version = (int) $browsers[self::BROWSCAP_VERSION_KEY]['Version'];
@@ -718,13 +751,13 @@ class Browscap
preg_match_all('/(?<=\[)(?:[^\r\n]+)(?=\])/m', $iniContent, $patternPositions);
if (!isset($patternPositions[0])) {
throw new Exception('could not extract patterns from ini file');
throw new Browscap_Exception('could not extract patterns from ini file');
}
$patternPositions = $patternPositions[0];
if (!count($patternPositions)) {
throw new Exception('no patterns were found inside the ini file');
throw new Browscap_Exception('no patterns were found inside the ini file');
}
// split the ini file into sections and save the data in one line with a hash of the belonging
@@ -735,7 +768,7 @@ class Browscap
$matches = array();
if (preg_match('/.*\[DefaultProperties\]([^[]*).*/', $iniContent, $matches)) {
$properties = parse_ini_string($matches[1], true, INI_SCANNER_RAW);
$properties = $this->parseIniString($matches[1], true);
$this->_properties = array_keys($properties);
@@ -766,7 +799,7 @@ class Browscap
continue;
}
$properties = parse_ini_string($iniParts[($position + 1)], true, INI_SCANNER_RAW);
$properties = $this->parseIniString($iniParts[($position + 1)], true);
if (empty($properties['Comment'])
|| false !== strpos($userAgent, '*')
@@ -1157,7 +1190,7 @@ class Browscap
// Check if it's possible to write to the .ini file.
if (is_file($path)) {
if (!is_writable($path)) {
throw new Exception(
throw new Browscap_Exception(
'Could not write to "' . $path . '" (check the permissions of the current/old ini file).'
);
}
@@ -1169,7 +1202,7 @@ class Browscap
fclose($test_file);
unlink($path);
} else {
throw new Exception(
throw new Browscap_Exception(
'Could not write to "' . $path . '" (check the permissions of the cache directory).'
);
}
@@ -1179,11 +1212,11 @@ class Browscap
$content = $this->_getRemoteData($url);
if (!is_string($content) || strlen($content) < 1) {
throw new Exception('Could not load .ini content from "' . $url . '"');
throw new Browscap_Exception('Could not load .ini content from "' . $url . '"');
}
if (false !== strpos('rate limit', $content)) {
throw new Exception(
throw new Browscap_Exception(
'Could not load .ini content from "' . $url . '" because the rate limit is exeeded for your IP'
);
}
@@ -1192,7 +1225,7 @@ class Browscap
$content = $this->sanitizeContent($content);
if (!file_put_contents($path, $content)) {
throw new Exception('Could not write .ini content to "' . $path . '"');
throw new Browscap_Exception('Could not write .ini content to "' . $path . '"');
}
return true;
@@ -1224,7 +1257,7 @@ class Browscap
$remote_tmstp = strtotime($remote_datetime);
if (!$remote_tmstp) {
throw new Exception("Bad datetime format from {$this->remoteVerUrl}");
throw new Browscap_Exception("Bad datetime format from {$this->remoteVerUrl}");
}
return $remote_tmstp;
@@ -1239,7 +1272,7 @@ class Browscap
protected function _getLocalMTime()
{
if (!is_readable($this->localFile) || !is_file($this->localFile)) {
throw new Exception('Local file is not readable');
throw new Browscap_Exception('Local file is not readable');
}
return filemtime($this->localFile);
@@ -1331,7 +1364,7 @@ class Browscap
if ($file !== false) {
return $file;
} else {
throw new Exception('Cannot open the local file');
throw new Browscap_Exception('Cannot open the local file');
}
case self::UPDATE_FOPEN:
if (ini_get('allow_url_fopen') && function_exists('file_get_contents')) {
@@ -1419,7 +1452,7 @@ class Browscap
}
}// else try with the next possibility
case false:
throw new Exception(
throw new Browscap_Exception(
'Your server can\'t connect to external resources. Please update the file manually.'
);
}
@@ -1452,7 +1485,7 @@ class Browscap
* @license http://www.opensource.org/licenses/MIT MIT License
* @link https://github.com/GaretJax/phpbrowscap/
*/
class Exception extends \Exception
class Browscap_Exception extends Exception
{
// nothing to do here
}
}
+1 -1
View File
@@ -21,7 +21,7 @@ if( !class_exists('HTMLPurifier_Filter_Iframevideo') ){
*/
public function preFilter($html, $config, $context)
{
if (strstr($html, '<iframe')) {
if (strstr((string)$html, '<iframe')) {
$html = preg_replace_callback('/<iframe.*?src="https?:\/\/www\.youtube\.com\/embed\/([^"]*)[^>]*>(.*?)?\/iframe>/i', array($this, 'trust_url_match'), $html);
$html = preg_replace_callback('/<iframe.*?src="https?:\/\/player\.vimeo.com\/video\/([^"]*)[^>]*>(.*?)?\/iframe>/i', array($this, 'trust_url_match'), $html);
$html = preg_replace_callback('/<iframe.*?src="https?:\/\/www\.facebook.com\/plugins\/([^"]*)[^>]*>(.*?)?\/iframe>/i', array($this, 'trust_url_match'), $html);
+3
View File
@@ -0,0 +1,3 @@
<?php
define('G5_CERT_IN_PROG', true);
include_once('../../common.php');
+104
View File
@@ -0,0 +1,104 @@
<?php
include_once('./_common.php');
include_once(G5_KCPCERT_V2_PATH.'/kcpcert_config.php');
$res_cd = isset($_POST['res_cd']) ? trim($_POST['res_cd']) : '';
$res_msg = isset($_POST['res_msg']) ? trim($_POST['res_msg']) : '';
$reg_cert_key = get_session('ss_kcp_v2_reg_cert_key');
$ordr_idxx = get_session('ss_kcp_v2_ordr_idxx');
set_session('ss_kcp_v2_reg_cert_key', '');
set_session('ss_kcp_v2_ordr_idxx', '');
set_session('ss_kcp_v2_page_type', '');
$g5['title'] = '휴대폰인증 결과';
include_once(G5_PATH.'/head.sub.php');
if ($res_cd === '') {
alert_close('본인확인 응답값이 없습니다. 처음부터 다시 시도해 주세요.');
}
@insert_cert_history($member['mb_id'], 'kcp_v2', 'hp');
if ($res_cd === '9999') {
alert_close('휴대폰 본인확인을 취소 하셨습니다.');
}
if ($res_cd !== '0000') {
alert_close('코드 : '.$res_cd.' '.urldecode($res_msg));
}
if (!$reg_cert_key || !$ordr_idxx) {
alert_close('본인확인 세션이 만료되었습니다. 처음부터 다시 시도해 주세요.');
}
$api = new C_KCP_API_V2($site_cd, $kcp_enc_key, $cert_reg_url, $cert_dec_url);
$cert = $api->get_cert_data($reg_cert_key, $ordr_idxx);
if ($cert['res_cd'] !== '0000') {
alert_close('본인확인 결과조회 실패 ('.$cert['res_cd'].' : '.$cert['res_msg'].')');
}
$phone_no = trim($cert['phone_no']);
$user_name = trim($cert['user_name']);
$birth_day = trim($cert['birth_day']);
$sex_code = trim($cert['sex_code']);
$ci = trim($cert['ci']);
$di = trim($cert['di']);
if (!$phone_no || !$user_name || !$birth_day || !$ci || !$di) {
alert_close('정상적인 인증이 아닙니다. 올바른 방법으로 이용해 주세요.');
}
$phone_no = hyphen_hp_number($phone_no);
$mb_dupinfo = $di;
$md5_ci = md5($ci.$ci);
$sql_dupinfo = sql_real_escape_string($mb_dupinfo);
$sql_md5_ci = sql_real_escape_string($md5_ci);
$row = sql_fetch("select mb_id from {$g5['member_table']} where mb_id <> '{$member['mb_id']}' and mb_dupinfo = '{$sql_md5_ci}'");
if (empty($row['mb_id'])) {
$row = sql_fetch("select mb_id from {$g5['member_table']} where mb_id <> '{$member['mb_id']}' and mb_dupinfo = '{$sql_dupinfo}'");
if (empty($row['mb_id'])) {
alert_close('인증하신 정보로 가입된 회원정보가 없습니다.');
}
} else {
$mb_dupinfo = $md5_ci;
}
$cert_type = 'hp';
$md5_cert_no = md5($reg_cert_key);
$hash_data = md5($user_name.$cert_type.$birth_day.$phone_no.$md5_cert_no);
$adult_day = date('Ymd', strtotime('-19 years', G5_SERVER_TIME));
$adult = ((int)$birth_day <= (int)$adult_day) ? 1 : 0;
set_session('ss_cert_type', $cert_type);
set_session('ss_cert_no', $md5_cert_no);
set_session('ss_cert_hash', $hash_data);
set_session('ss_cert_adult', $adult);
set_session('ss_cert_birth', $birth_day);
set_session('ss_cert_sex', ($sex_code == '01' ? 'M' : 'F'));
set_session('ss_cert_dupinfo', $mb_dupinfo);
set_session('ss_cert_mb_id', $row['mb_id']);
?>
<form name="mbFindForm" method="POST">
<input type="hidden" name="mb_id" value="<?php echo $row['mb_id']; ?>">
</form>
<script>
jQuery(function($) {
var $opener = window.opener;
if (!$opener) { window.close(); return; }
$opener.name = "parentPage";
document.mbFindForm.target = "parentPage";
document.mbFindForm.action = "<?php echo G5_BBS_URL.'/password_reset.php'; ?>";
document.mbFindForm.submit();
alert("본인인증이 완료되었습니다.");
window.close();
});
</script>
<?php
include_once(G5_PATH.'/tail.sub.php');
+32
View File
@@ -0,0 +1,32 @@
<?php
if (!defined('_GNUBOARD_')) exit;
if (version_compare(PHP_VERSION, '7.0.0', '<')) {
alert('KCP 휴대폰 본인확인 V2 모듈은 PHP 7.0 이상 환경에서만 동작합니다.', G5_URL);
}
if (!extension_loaded('openssl') || !function_exists('hash_pbkdf2') || !extension_loaded('curl')) {
alert('KCP 휴대폰 본인확인 V2 모듈에 필요한 PHP 확장(openssl/curl/hash_pbkdf2)이 활성화되어 있지 않습니다.', G5_URL);
}
$web_siteid = '';
if ($config['cf_cert_use'] == 2) {
$site_cd = 'SM'.trim($config['cf_cert_kcp_cd']);
$kcp_enc_key = isset($config['cf_cert_kcp_enckey']) ? $config['cf_cert_kcp_enckey'] : '';
$cert_reg_url = 'https://cert.kcp.co.kr/api/reg/certDataReg.do';
$cert_dec_url = 'https://cert.kcp.co.kr/api/query/getCertData.do';
} else if ($config['cf_cert_use'] == 1) {
$site_cd = 'AO7F3';
$kcp_enc_key = 'c2a22fa3ebe4698075bcac6b433d52e351c881b02fb83488d4283a43385b1f8e';
$cert_reg_url = 'https://testcert.kcp.co.kr/api/reg/certDataReg.do';
$cert_dec_url = 'https://testcert.kcp.co.kr/api/query/getCertData.do';
} else {
$site_cd = $kcp_enc_key = $cert_reg_url = $cert_dec_url = '';
}
if (!$site_cd || !$kcp_enc_key) {
alert('KCP 휴대폰 본인확인 V2 사이트코드 또는 ENC_KEY 가 설정되지 않았습니다.\n관리자 > 기본환경설정에서 입력해 주세요.', G5_URL);
}
require_once G5_KCPCERT_V2_PATH.'/lib/Crypto.php';
require_once G5_KCPCERT_V2_PATH.'/lib/kcp_api.php';
+59
View File
@@ -0,0 +1,59 @@
<?php
include_once('./_common.php');
setlocale(LC_CTYPE, 'ko_KR.UTF-8');
$page_type = isset($_GET['pageType']) ? $_GET['pageType'] : '';
switch ($page_type) {
case 'register':
$result_url = G5_KCPCERT_V2_URL.'/kcpcert_result.php';
break;
case 'find':
$result_url = G5_KCPCERT_V2_URL.'/find_kcpcert_result.php';
break;
default:
alert_close('잘못된 접근입니다.');
}
certify_count_check($member['mb_id'], 'hp');
include_once(G5_KCPCERT_V2_PATH.'/kcpcert_config.php');
$ordr_idxx = get_session('ss_uniqid');
if (!$ordr_idxx) $ordr_idxx = get_uniqid();
$api = new C_KCP_API_V2($site_cd, $kcp_enc_key, $cert_reg_url, $cert_dec_url);
$reg = $api->trade_reg($ordr_idxx, $result_url, $web_siteid);
if ($reg['res_cd'] !== '0000' || !$reg['call_url'] || !$reg['reg_cert_key']) {
$err = '본인확인 거래등록에 실패했습니다.\n('.$reg['res_cd'].' : '.$reg['res_msg'].')';
alert_close($err);
}
set_session('ss_kcp_v2_reg_cert_key', $reg['reg_cert_key']);
set_session('ss_kcp_v2_ordr_idxx', $ordr_idxx);
set_session('ss_kcp_v2_page_type', $page_type);
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<?php if (is_mobile()) { ?>
<meta name="viewport" content="user-scalable=yes, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, width=device-width, target-densitydpi=medium-dpi">
<?php } ?>
<title>휴대폰 본인확인</title>
</head>
<body oncontextmenu="return false;" ondragstart="return false;" onselectstart="return false;">
<form name="form_auth" method="post" action="<?php echo htmlspecialchars($reg['call_url'], ENT_QUOTES); ?>">
<input type="hidden" name="reg_cert_key" value="<?php echo htmlspecialchars($reg['reg_cert_key'], ENT_QUOTES); ?>">
<input type="hidden" name="kcp_page_submit_yn" value="Y">
</form>
<script>
window.onload = function() {
document.form_auth.submit();
};
</script>
</body>
</html>
+111
View File
@@ -0,0 +1,111 @@
<?php
include_once('./_common.php');
include_once(G5_KCPCERT_V2_PATH.'/kcpcert_config.php');
$res_cd = isset($_POST['res_cd']) ? trim($_POST['res_cd']) : '';
$res_msg = isset($_POST['res_msg']) ? trim($_POST['res_msg']) : '';
$reg_cert_key = get_session('ss_kcp_v2_reg_cert_key');
$ordr_idxx = get_session('ss_kcp_v2_ordr_idxx');
set_session('ss_kcp_v2_reg_cert_key', '');
set_session('ss_kcp_v2_ordr_idxx', '');
set_session('ss_kcp_v2_page_type', '');
$g5['title'] = '휴대폰인증 결과';
include_once(G5_PATH.'/head.sub.php');
if ($res_cd === '') {
alert_close('본인확인 응답값이 없습니다. 처음부터 다시 시도해 주세요.');
}
@insert_cert_history($member['mb_id'], 'kcp_v2', 'hp');
if ($res_cd === '9999') {
alert_close('휴대폰 본인확인을 취소 하셨습니다.');
}
if ($res_cd !== '0000') {
alert_close('코드 : '.$res_cd.' '.urldecode($res_msg));
}
if (!$reg_cert_key || !$ordr_idxx) {
alert_close('본인확인 세션이 만료되었습니다. 처음부터 다시 시도해 주세요.');
}
$api = new C_KCP_API_V2($site_cd, $kcp_enc_key, $cert_reg_url, $cert_dec_url);
$cert = $api->get_cert_data($reg_cert_key, $ordr_idxx);
if ($cert['res_cd'] !== '0000') {
alert_close('본인확인 결과조회 실패 ('.$cert['res_cd'].' : '.$cert['res_msg'].')');
}
$phone_no = trim($cert['phone_no']);
$user_name = trim($cert['user_name']);
$birth_day = trim($cert['birth_day']);
$sex_code = trim($cert['sex_code']);
$ci = trim($cert['ci']);
$di = trim($cert['di']);
if (!$phone_no || !$user_name || !$birth_day || !$ci || !$di) {
alert_close('정상적인 인증이 아닙니다. 올바른 방법으로 이용해 주세요.');
}
$phone_no = hyphen_hp_number($phone_no);
$mb_dupinfo = md5($ci.$ci);
$sql_dupinfo = sql_real_escape_string($mb_dupinfo);
if (!empty($member['mb_certify']) && !empty($member['mb_dupinfo']) && strlen($member['mb_dupinfo']) != 64) {
if ($member['mb_dupinfo'] != $mb_dupinfo) {
alert_close('해당 계정은 이미 다른명의로 본인인증 되어있는 계정입니다.');
}
}
$sql = " select mb_id from {$g5['member_table']} where mb_id <> '{$member['mb_id']}' and mb_dupinfo = '{$sql_dupinfo}' ";
$row = sql_fetch($sql);
if (!empty($row['mb_id'])) {
alert_close("입력하신 본인확인 정보로 가입된 내역이 존재합니다.\\n회원아이디 : ".$row['mb_id']);
}
$cert_type = 'hp';
$md5_cert_no = md5($reg_cert_key);
$hash_data = md5($user_name.$cert_type.$birth_day.$phone_no.$md5_cert_no);
$adult_day = date('Ymd', strtotime('-19 years', G5_SERVER_TIME));
$adult = ((int)$birth_day <= (int)$adult_day) ? 1 : 0;
set_session('ss_cert_type', $cert_type);
set_session('ss_cert_no', $md5_cert_no);
set_session('ss_cert_hash', $hash_data);
set_session('ss_cert_adult', $adult);
set_session('ss_cert_birth', $birth_day);
set_session('ss_cert_sex', ($sex_code == '01' ? 'M' : 'F'));
set_session('ss_cert_dupinfo', $mb_dupinfo);
$js_replace = array('\\' => '\\\\', '"' => '\\"', "'" => '\\u0027', '/' => '\\/', "\r" => '\\r', "\n" => '\\n', "\t" => '\\t', '<' => '\\u003C', '>' => '\\u003E', '&' => '\\u0026', "\xE2\x80\xA8" => '\\u2028', "\xE2\x80\xA9" => '\\u2029');
$js_cert_type = function_exists('get_js_safe_string') ? get_js_safe_string($cert_type) : '"'.strtr((string)$cert_type, $js_replace).'"';
$js_user_name = function_exists('get_js_safe_string') ? get_js_safe_string($user_name) : '"'.strtr((string)$user_name, $js_replace).'"';
$js_phone_no = function_exists('get_js_safe_string') ? get_js_safe_string($phone_no) : '"'.strtr((string)$phone_no, $js_replace).'"';
$js_md5_cert_no = function_exists('get_js_safe_string') ? get_js_safe_string($md5_cert_no) : '"'.strtr((string)$md5_cert_no, $js_replace).'"';
?>
<script>
jQuery(function($) {
var $opener = window.opener;
if (!$opener) { window.close(); return; }
$opener.$("input[name=cert_type]").val(<?php echo $js_cert_type; ?>);
$opener.$("input[name=mb_name]").val(<?php echo $js_user_name; ?>).attr("readonly", true);
$opener.$("input[name=mb_hp]").val(<?php echo $js_phone_no; ?>).attr("readonly", true);
$opener.$("input[name=cert_no]").val(<?php echo $js_md5_cert_no; ?>);
alert("본인의 휴대폰번호로 확인 되었습니다.");
if ($opener.$("form[name=fcertrefreshform]").length) {
$opener.$("form[name=fcertrefreshform]").submit();
}
window.close();
});
</script>
<?php
include_once(G5_PATH.'/tail.sub.php');
+54
View File
@@ -0,0 +1,54 @@
<?php
if (!class_exists('Crypto_KCP_V2')) {
class Crypto_KCP_V2
{
private static $a = "c2hhMjU2";
private static $b = 10000;
private static $c = 32;
private static $d = "QUVTLTI1Ni1DQkM=";
private static function x($p, $s)
{
return hash_pbkdf2(base64_decode(self::$a), $p, $s, self::$b, self::$c, true);
}
private static function y($d, $k, $i)
{
return openssl_encrypt($d, base64_decode(self::$d), $k, OPENSSL_RAW_DATA, $i);
}
private static function z($d, $k, $i)
{
return openssl_decrypt($d, base64_decode(self::$d), $k, OPENSSL_RAW_DATA, $i);
}
public static function encryptJson($data, $key, $site)
{
$s = random_bytes(16);
$k = self::x($key, $s);
$v = self::x($site, $s);
$i = substr($v, 0, 16);
$e = self::y($data, $k, $i);
return array(
"encData" => base64_encode($e),
"rv" => base64_encode($s),
);
}
public static function decryptJson($enc, $rv, $key, $site)
{
$s = base64_decode($rv);
$k = self::x($key, $s);
$v = self::x($site, $s);
$i = substr($v, 0, 16);
return self::z(base64_decode($enc), $k, $i);
}
}
}
+183
View File
@@ -0,0 +1,183 @@
<?php
if (!defined('_GNUBOARD_')) exit;
if (!class_exists('C_KCP_API_V2')) {
class C_KCP_API_V2
{
private $site_cd;
private $enc_key;
private $reg_url;
private $dec_url;
private $last_error = '';
public function __construct($site_cd, $enc_key, $reg_url, $dec_url)
{
$this->site_cd = $site_cd;
$this->enc_key = $enc_key;
$this->reg_url = $reg_url;
$this->dec_url = $dec_url;
}
public function trade_reg($ordr_idxx, $ret_url, $web_siteid = '', $opt1 = '', $opt2 = '', $opt3 = '')
{
$payload = array(
'site_cd' => $this->site_cd,
'ordr_idxx' => $ordr_idxx,
'Ret_URL' => $ret_url,
'web_siteid' => $web_siteid,
'param_opt_1' => $opt1,
'param_opt_2' => $opt2,
'param_opt_3' => $opt3,
);
$req_json = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
if ($req_json === false) {
return array(
'res_cd' => 'JSON_ERROR',
'res_msg' => 'KCP 거래등록 요청 데이터를 생성할 수 없습니다.',
'call_url' => '',
'reg_cert_key' => '',
);
}
$enc = Crypto_KCP_V2::encryptJson($req_json, $this->enc_key, $this->site_cd);
if (empty($enc['encData']) || empty($enc['rv'])) {
return array(
'res_cd' => 'ENCRYPT_ERROR',
'res_msg' => 'KCP 거래등록 요청 데이터를 암호화할 수 없습니다.',
'call_url' => '',
'reg_cert_key' => '',
);
}
$headers = array(
'Content-Type: application/json',
'site_cd: '.$this->site_cd,
'rv: '.$enc['rv'],
);
$body = $this->http_post($this->reg_url, $enc['encData'], $headers);
if ($body === false || $body === '') {
return array(
'res_cd' => 'HTTP_ERROR',
'res_msg' => $this->last_error ? $this->last_error : 'KCP 거래등록 API 응답이 없습니다.',
'call_url' => '',
'reg_cert_key' => '',
);
}
$res = json_decode($body, true);
if (!is_array($res)) {
return array(
'res_cd' => 'JSON_ERROR',
'res_msg' => 'KCP 거래등록 API 응답을 해석할 수 없습니다.',
'call_url' => '',
'reg_cert_key' => '',
);
}
return array(
'res_cd' => isset($res['res_cd']) ? $res['res_cd'] : '',
'res_msg' => isset($res['res_msg']) ? $res['res_msg'] : '',
'call_url' => isset($res['call_url']) ? $res['call_url'] : '',
'reg_cert_key' => isset($res['reg_cert_key']) ? $res['reg_cert_key'] : '',
);
}
public function get_cert_data($reg_cert_key, $ordr_idxx)
{
$req_json = json_encode(array(
'reg_cert_key' => $reg_cert_key,
'ordr_idxx' => $ordr_idxx,
), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
if ($req_json === false) {
return array('res_cd' => 'JSON_ERROR', 'res_msg' => 'KCP 본인확인 결과조회 요청 데이터를 생성할 수 없습니다.');
}
$headers = array(
'Content-Type: application/json',
'site_cd: '.$this->site_cd,
);
$body = $this->http_post($this->dec_url, $req_json, $headers);
if ($body === false || $body === '') {
return array(
'res_cd' => 'HTTP_ERROR',
'res_msg' => $this->last_error ? $this->last_error : 'KCP 본인확인 결과조회 API 응답이 없습니다.',
);
}
$res = json_decode($body, true);
if (!is_array($res)) {
return array('res_cd' => 'JSON_ERROR', 'res_msg' => 'KCP 본인확인 결과조회 API 응답을 해석할 수 없습니다.');
}
$res_cd = isset($res['res_cd']) ? $res['res_cd'] : '';
$res_msg = isset($res['res_msg']) ? $res['res_msg'] : '';
if ($res_cd !== '0000') {
return array('res_cd' => $res_cd, 'res_msg' => $res_msg);
}
$enc_cert_data = isset($res['enc_cert_data']) ? $res['enc_cert_data'] : '';
$rv = isset($res['rv']) ? $res['rv'] : '';
$plain = Crypto_KCP_V2::decryptJson($enc_cert_data, $rv, $this->enc_key, $this->site_cd);
if ($plain === false || $plain === '') {
return array('res_cd' => 'DECRYPT_ERROR', 'res_msg' => 'KCP 본인확인 결과 데이터를 복호화할 수 없습니다.');
}
$dec = json_decode($plain, true);
if (!is_array($dec)) {
return array('res_cd' => 'JSON_ERROR', 'res_msg' => 'KCP 본인확인 복호화 데이터를 해석할 수 없습니다.');
}
return array(
'res_cd' => $res_cd,
'res_msg' => $res_msg,
'phone_no' => isset($dec['phone_no']) ? $dec['phone_no'] : '',
'user_name' => isset($dec['user_name']) ? $dec['user_name'] : '',
'birth_day' => isset($dec['birth_day']) ? $dec['birth_day'] : '',
'comm_id' => isset($dec['comm_id']) ? $dec['comm_id'] : '',
'sex_code' => isset($dec['sex_code']) ? $dec['sex_code'] : '',
'local_code' => isset($dec['local_code']) ? $dec['local_code'] : '',
'ci' => isset($dec['CI']) ? $dec['CI'] : (isset($dec['ci']) ? $dec['ci'] : ''),
'di' => isset($dec['DI']) ? $dec['DI'] : (isset($dec['di']) ? $dec['di'] : ''),
'ci_url' => isset($dec['CI_URL']) ? urldecode($dec['CI_URL']) : '',
'di_url' => isset($dec['DI_URL']) ? urldecode($dec['DI_URL']) : '',
);
}
private function http_post($url, $body, $headers)
{
$this->last_error = '';
$ch = curl_init($url);
if (!$ch) {
$this->last_error = 'cURL 초기화에 실패했습니다.';
return false;
}
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$resp = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($resp === false) {
$this->last_error = 'KCP API 통신 실패: '.curl_error($ch);
} else if ($http_code && ($http_code < 200 || $http_code >= 300)) {
$this->last_error = 'KCP API HTTP 오류: '.$http_code;
}
curl_close($ch);
if ($this->last_error) {
return false;
}
return $resp;
}
}
}
+5 -4
View File
@@ -125,18 +125,19 @@ if (empty($row['mb_id'])) { // ci로 등록된 계정이 없다면
$mb_dupinfo = $md5_ci;
}
$md5_cert_no = md5($cert_no);
$hash_data = md5($user_name.$cert_type.$birth_day.$phone_no.$md5_cert_no);
$cert_type = 'hp';
$md5_cert_no = md5($req_num);
$hash_data = md5($mb_name.$cert_type.$mb_birth.$phone_no.$md5_cert_no);
// 성인인증결과
$adult_day = date("Ymd", strtotime("-19 years", G5_SERVER_TIME));
$adult = ((int)$birth_day <= (int)$adult_day) ? 1 : 0;
$adult = ((int)$mb_birth <= (int)$adult_day) ? 1 : 0;
set_session("ss_cert_type", $cert_type);
set_session("ss_cert_no", $md5_cert_no);
set_session("ss_cert_hash", $hash_data);
set_session("ss_cert_adult", $adult);
set_session("ss_cert_birth", $birth_day);
set_session("ss_cert_birth", $mb_birth);
set_session('ss_cert_sex', ($field[9] == 1 ? 'M' : 'F'));
set_session('ss_cert_dupinfo', $mb_dupinfo);
set_session('ss_cert_mb_id', $row['mb_id']);
+5 -4
View File
@@ -99,18 +99,19 @@ if (empty($row['mb_id'])) { // ci로 등록된 계정이 없다면
$mb_dupinfo = $md5_ci;
}
$md5_cert_no = md5($cert_no);
$hash_data = md5($user_name.$cert_type.$birth_day.$phone_no.$md5_cert_no);
$cert_type = 'ipin';
$md5_cert_no = md5($req_num);
$hash_data = md5($mb_name.$cert_type.$mb_birth.$md5_cert_no);
// 성인인증결과
$adult_day = date("Ymd", strtotime("-19 years", G5_SERVER_TIME));
$adult = ((int)$birth_day <= (int)$adult_day) ? 1 : 0;
$adult = ((int)$mb_birth <= (int)$adult_day) ? 1 : 0;
set_session("ss_cert_type", $cert_type);
set_session("ss_cert_no", $md5_cert_no);
set_session("ss_cert_hash", $hash_data);
set_session("ss_cert_adult", $adult);
set_session("ss_cert_birth", $birth_day);
set_session("ss_cert_birth", $mb_birth);
set_session('ss_cert_sex', ($field[9] == 1 ? 'M' : 'F'));
set_session('ss_cert_dupinfo', $mb_dupinfo);
set_session('ss_cert_mb_id', $row['mb_id']);
+4 -2
View File
@@ -98,7 +98,9 @@ if ($retcode == "B000") {
echo ("<script>request();</script>");
} else {
//요청 실패 페이지로 리턴
echo ("<script>alert(\"$retcode\"); self.close();</script>");
$js_replace = array('\\' => '\\\\', '"' => '\\"', "'" => '\\u0027', '/' => '\\/', "\r" => '\\r', "\n" => '\\n', "\t" => '\\t', '<' => '\\u003C', '>' => '\\u003E', '&' => '\\u0026', "\xE2\x80\xA8" => '\\u2028', "\xE2\x80\xA9" => '\\u2029');
$js_retcode = function_exists('get_js_safe_string') ? get_js_safe_string($retcode) : '"'.strtr((string)$retcode, $js_replace).'"';
echo ("<script>alert(".$js_retcode."); self.close();</script>");
}
include_once(G5_PATH.'/tail.sub.php');
include_once(G5_PATH.'/tail.sub.php');
+2 -2
View File
@@ -161,7 +161,7 @@ if($config['cf_sms_type'] == 'LMS') {
public $Result = array();
public $Log = array();
function Add($strDest, $strCallBack, $strCaller, $strSubject, $strURL, $strData, $strDate="", $nCount) {
function Add($strDest, $strCallBack, $strCaller, $strSubject, $strURL, $strData, $strDate="", $nCount=0) {
global $config;
// 아이코드 JSON 모듈은 UTF-8 을 사용하며, sms 또는 lms 는 euc-kr 로 사용한다.
@@ -280,7 +280,7 @@ if($config['cf_sms_type'] == 'LMS') {
break;
}
}
function Add2($strDest, $strCallBack, $strCaller, $strURL, $strMessage, $strDate="", $nCount) {
function Add2($strDest, $strCallBack, $strCaller, $strURL, $strMessage, $strDate="", $nCount=0) {
global $g5, $config;
$Error = $this->CheckCommonTypeDest($strDest, $nCount);
+2
View File
@@ -593,6 +593,7 @@ function social_check_login_before($p_service=''){
$params = array('provider'=>$provider_name);
$url = replaceQueryParams($url, $params);
check_url_host($url, '', G5_URL, true);
goto_url($url);
} else {
goto_url(G5_URL);
@@ -772,6 +773,7 @@ function social_member_comfirm_redirect(){
$params = array('provider'=>$provider_name);
$url = replaceQueryParams($url, $params);
check_url_host($url, '', G5_URL, true);
goto_url($url);
}
+2 -2
View File
@@ -104,7 +104,7 @@ $mb_marketing_agree = isset($_POST['mb_marketing_agree']) ? trim($_POST['mb_mark
//개인정보 제3자 제공 동의
$mb_thirdparty_agree = isset($_POST['mb_thirdparty_agree']) ? trim($_POST['mb_thirdparty_agree']) : "0";
$agree_items = [];
$agree_items = array();
$sql_agree = "";
// 마케팅 목적의 개인정보 수집 및 이용
if ($mb_marketing_agree == 1) {
@@ -340,4 +340,4 @@ if($result) {
alert('회원 가입 오류!', G5_URL );
}
}

Some files were not shown because too many files have changed in this diff Show More