mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-04-29 07:12:15 +09:00
Merge branch 'develop' into pr/1851
This commit is contained in:
commit
4eced6daf0
71 changed files with 1045 additions and 508 deletions
|
|
@ -127,7 +127,7 @@
|
|||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||
<label class="x_control-label" for="mail_smtp_pass">{$lang->cmd_advanced_mailer_smtp_pass}</label>
|
||||
<div class="x_controls">
|
||||
<input type="password" name="mail_{$driver_name}_smtp_pass" id="mail_{$driver_name}_smtp_pass" value="{$conf_value}" />
|
||||
<input type="password" name="mail_{$driver_name}_smtp_pass" id="mail_{$driver_name}_smtp_pass" value="{$conf_value}" autocomplete="new-password" />
|
||||
</div>
|
||||
</div>
|
||||
<!--@end-->
|
||||
|
|
@ -167,7 +167,7 @@
|
|||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||
<label class="x_control-label" for="mail_{$driver_name}_api_pass">{$lang->cmd_advanced_mailer_api_pass}</label>
|
||||
<div class="x_controls full-width">
|
||||
<input type="password" name="mail_{$driver_name}_api_pass" id="mail_{$driver_name}_api_pass" value="{$conf_value}" />
|
||||
<input type="password" name="mail_{$driver_name}_api_pass" id="mail_{$driver_name}_api_pass" value="{$conf_value}" autocomplete="new-password" />
|
||||
</div>
|
||||
</div>
|
||||
<!--@end-->
|
||||
|
|
@ -194,7 +194,7 @@
|
|||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||
<label class="x_control-label" for="mail_{$driver_name}_api_secret">{$lang->cmd_advanced_mailer_api_secret}</label>
|
||||
<div class="x_controls">
|
||||
<input type="password" name="mail_{$driver_name}_api_secret" id="mail_{$driver_name}_api_secret" value="{$conf_value}" />
|
||||
<input type="password" name="mail_{$driver_name}_api_secret" id="mail_{$driver_name}_api_secret" value="{$conf_value}" autocomplete="new-password" />
|
||||
</div>
|
||||
</div>
|
||||
<!--@end-->
|
||||
|
|
@ -258,7 +258,7 @@
|
|||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||
<label class="x_control-label" for="sms_{$driver_name}_api_pass">{$lang->cmd_advanced_mailer_api_pass}</label>
|
||||
<div class="x_controls full-width">
|
||||
<input type="password" name="sms_{$driver_name}_api_pass" id="sms_{$driver_name}_api_pass" value="{$conf_value}" />
|
||||
<input type="password" name="sms_{$driver_name}_api_pass" id="sms_{$driver_name}_api_pass" value="{$conf_value}" autocomplete="new-password" />
|
||||
</div>
|
||||
</div>
|
||||
<!--@end-->
|
||||
|
|
@ -285,7 +285,7 @@
|
|||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||
<label class="x_control-label" for="sms_{$driver_name}_api_secret">{$lang->cmd_advanced_mailer_api_secret}</label>
|
||||
<div class="x_controls">
|
||||
<input type="password" name="sms_{$driver_name}_api_secret" id="sms_{$driver_name}_api_secret" value="{$conf_value}" />
|
||||
<input type="password" name="sms_{$driver_name}_api_secret" id="sms_{$driver_name}_api_secret" value="{$conf_value}" autocomplete="new-password" />
|
||||
</div>
|
||||
</div>
|
||||
<!--@end-->
|
||||
|
|
@ -294,7 +294,7 @@
|
|||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||
<label class="x_control-label" for="sms_{$driver_name}_sender_key">{$lang->cmd_advanced_mailer_sender_key}</label>
|
||||
<div class="x_controls">
|
||||
<input type="password" name="sms_{$driver_name}_sender_key" id="sms_{$driver_name}_sender_key" value="{$conf_value}" />
|
||||
<input type="password" name="sms_{$driver_name}_sender_key" id="sms_{$driver_name}_sender_key" value="{$conf_value}" autocomplete="new-password" />
|
||||
<p class="x_help-block">{$lang->cmd_admin_sms_sender_key_help}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -363,7 +363,7 @@
|
|||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||
<label class="x_control-label" for="push_{$driver_name}_api_key">{$lang->cmd_advanced_mailer_fcm_api_key}</label>
|
||||
<div class="x_controls">
|
||||
<input type="password" name="push_{$driver_name}_api_key" id="push_{$driver_name}_api_key" value="{$conf_value|escape}" />
|
||||
<input type="password" name="push_{$driver_name}_api_key" id="push_{$driver_name}_api_key" value="{$conf_value|escape}" autocomplete="new-password" />
|
||||
</div>
|
||||
</div>
|
||||
<!--@end-->
|
||||
|
|
@ -381,7 +381,7 @@
|
|||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||
<label class="x_control-label" for="push_{$driver_name}_passphrase">{$lang->cmd_advanced_mailer_apns_passphrase}</label>
|
||||
<div class="x_controls">
|
||||
<input type="password" name="push_{$driver_name}_passphrase" id="push_{$driver_name}_passphrase" value="{$conf_value|escape}" />
|
||||
<input type="password" name="push_{$driver_name}_passphrase" id="push_{$driver_name}_passphrase" value="{$conf_value|escape}" autocomplete="new-password" />
|
||||
</div>
|
||||
</div>
|
||||
<!--@end-->
|
||||
|
|
|
|||
|
|
@ -45,11 +45,11 @@ class boardView extends board
|
|||
$count_category = count(DocumentModel::getCategoryList($this->module_info->module_srl));
|
||||
if($count_category)
|
||||
{
|
||||
if($this->module_info->hide_category)
|
||||
if(isset($this->module_info->hide_category))
|
||||
{
|
||||
$this->module_info->use_category = ($this->module_info->hide_category == 'Y') ? 'N' : 'Y';
|
||||
}
|
||||
else if($this->module_info->use_category)
|
||||
elseif(isset($this->module_info->use_category))
|
||||
{
|
||||
$this->module_info->hide_category = ($this->module_info->use_category == 'Y') ? 'N' : 'Y';
|
||||
}
|
||||
|
|
@ -655,7 +655,7 @@ class boardView extends board
|
|||
// List of columns that should always be selected
|
||||
$defaultColumnList = array(
|
||||
'document_srl', 'module_srl', 'category_srl', 'lang_code', 'is_notice',
|
||||
'title', 'title_bold', 'title_color', 'member_srl', 'nick_name', 'extra_vars',
|
||||
'title', 'title_bold', 'title_color', 'member_srl', 'nick_name', 'tags', 'extra_vars',
|
||||
'comment_count', 'trackback_count', 'uploaded_count', 'status', 'regdate', 'last_update',
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
<load target="css/mboard.css" />
|
||||
|
||||
<div class="bd">
|
||||
<!--@if(isset($module_info->mobile_header_text) && $module_info->mobile_header_text)-->
|
||||
<div class="bd_header_text">{$module_info->mobile_header_text}</div>
|
||||
<!--@endif-->
|
||||
<!--@if($oDocument->isExists())-->
|
||||
<include target="read.html" />
|
||||
<!--@else-->
|
||||
<include target="_list.html" />
|
||||
<!--@end-->
|
||||
<!--@if(isset($module_info->mobile_footer_text) && $module_info->mobile_footer_text)-->
|
||||
<div class="bd_footer_text">{$module_info->mobile_footer_text}</div>
|
||||
<!--@endif-->
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
<load target="css/mboard.css" />
|
||||
|
||||
<div class="bd">
|
||||
<!--@if(isset($module_info->mobile_header_text) && $module_info->mobile_header_text)-->
|
||||
<div class="bd_header_text">{$module_info->mobile_header_text}</div>
|
||||
<!--@endif-->
|
||||
<div class="hx h2">
|
||||
<h2><a href="{getUrl('','vid',$vid,'mid',$mid)}">{$module_info->browser_title}</a></h2>
|
||||
</div>
|
||||
|
|
@ -86,5 +89,8 @@
|
|||
<div class="bna">
|
||||
<button type="submit" class="bn dark">{$lang->cmd_registration}</button>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
<!--@if(isset($module_info->mobile_footer_text) && $module_info->mobile_footer_text)-->
|
||||
<div class="bd_footer_text">{$module_info->mobile_footer_text}</div>
|
||||
<!--@endif-->
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
<load target="css/mboard.css" />
|
||||
|
||||
<div class="bd">
|
||||
<!--@if(isset($module_info->mobile_header_text) && $module_info->mobile_header_text)-->
|
||||
<div class="bd_header_text">{$module_info->mobile_header_text}</div>
|
||||
<!--@endif-->
|
||||
<!--@if($oDocument->isExists())-->
|
||||
<!--#include("read.html")-->
|
||||
<include target="read.html" />
|
||||
<!--@else-->
|
||||
<!--#include("_list.html")-->
|
||||
<include target="_list.html" />
|
||||
<!--@end-->
|
||||
<!--@if(isset($module_info->mobile_footer_text) && $module_info->mobile_footer_text)-->
|
||||
<div class="bd_footer_text">{$module_info->mobile_footer_text}</div>
|
||||
<!--@endif-->
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,10 @@
|
|||
<load target="css/mboard.css" />
|
||||
|
||||
<div class="bd">
|
||||
<h2 class="h2"><a href="{getUrl('','vid',$vid,'mid',$mid)}">{$module_info->browser_title}</a> › {$lang->cmd_write}</h2>
|
||||
<!--@if(isset($module_info->mobile_header_text) && $module_info->mobile_header_text)-->
|
||||
<div class="bd_header_text">{$module_info->mobile_header_text}</div>
|
||||
<!--@endif-->
|
||||
<h2 class="h2"><a href="{getUrl('','vid',$vid,'mid',$mid)}">{$module_info->browser_title}</a> › {$lang->cmd_write}</h2>
|
||||
<form action="./" method="POST" onsubmit="return procFilter(this, insert)">
|
||||
<input type="hidden" name="mid" value="{$mid}" />
|
||||
<input type="hidden" name="document_srl" value="{$document_srl}" />
|
||||
|
|
@ -81,4 +84,7 @@
|
|||
<button type="submit" class="bn">{$lang->cmd_registration}</button>
|
||||
</div>
|
||||
</form>
|
||||
<!--@if(isset($module_info->mobile_footer_text) && $module_info->mobile_footer_text)-->
|
||||
<div class="bd_footer_text">{$module_info->mobile_footer_text}</div>
|
||||
<!--@endif-->
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -78,6 +78,9 @@
|
|||
<input cond="$module_info->secret=='Y'" type="checkbox" name="is_secret" value="Y" id="is_secret" class="iCheck" />
|
||||
<label cond="$module_info->secret=='Y'" for="is_secret">{$lang->secret}</label>
|
||||
</div>
|
||||
<div class="write_captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('comment')">
|
||||
{$captcha}
|
||||
</div>
|
||||
<div class="btnArea">
|
||||
<button type="submit" class="btn">{$lang->cmd_comment_registration}</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@
|
|||
<input cond="$module_info->secret=='Y'" type="checkbox" name="is_secret" value="Y" id="is_secret" checked="checked"|cond="$oComment->get('is_secret')=='Y'" class="iCheck" />
|
||||
<label cond="$module_info->secret=='Y'" for="is_secret">{$lang->secret}</label>
|
||||
</div>
|
||||
<div class="write_captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('comment')">
|
||||
{$captcha}
|
||||
</div>
|
||||
<div class="btnArea">
|
||||
<button type="submit" class="btn">{$lang->cmd_comment_registration}</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -73,6 +73,9 @@
|
|||
<input type="text" name="tags" id="tags" value="{htmlspecialchars($oDocument->get('tags'))}" class="iText" style="width:300px" title="Tag" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="write_captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('document')">
|
||||
{$captcha}
|
||||
</div>
|
||||
<div class="btnArea">
|
||||
<input type="submit" value="{$lang->cmd_registration}" class="btn" />
|
||||
<block cond="!$oDocument->isExists() || $oDocument->get('status') == 'TEMP'">
|
||||
|
|
|
|||
|
|
@ -86,6 +86,9 @@
|
|||
<input cond="$module_info->secret=='Y'" type="checkbox" name="is_secret" value="Y" id="is_secret" class="iCheck" />
|
||||
<label cond="$module_info->secret=='Y'" for="is_secret">{$lang->secret}</label>
|
||||
</div>
|
||||
<div class="write_captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('comment')">
|
||||
{$captcha}
|
||||
</div>
|
||||
<div style="float:right">
|
||||
<button type="submit" class="btn_insert"><i class="xi-message"></i> {$lang->cmd_comment_registration}</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
<input cond="$module_info->secret=='Y'" type="checkbox" name="is_secret" value="Y" id="is_secret" checked="checked"|cond="$oComment->get('is_secret')=='Y'" class="iCheck" />
|
||||
<label cond="$module_info->secret=='Y'" for="is_secret">{$lang->secret}</label>
|
||||
</div>
|
||||
<div class="write_captcha" cond="$captcha">
|
||||
<div class="write_captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('comment')">
|
||||
{$captcha}
|
||||
</div>
|
||||
<div style="float:right">
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
<input type="text" name="reason_update" id="reason_update" value="" class="iText" style="width:300px" title="reason update" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="write_captcha" cond="isset($captcha) && $captcha">
|
||||
<div class="write_captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('document')">
|
||||
{$captcha}
|
||||
</div>
|
||||
<div style="float:right">
|
||||
|
|
|
|||
|
|
@ -1334,7 +1334,7 @@ class documentController extends document
|
|||
);
|
||||
|
||||
$config = DocumentModel::getDocumentConfig();
|
||||
if (!$config->view_count_option || !isset($valid_options[$config->view_count_option]))
|
||||
if (!isset($config->view_count_option) || !isset($valid_options[$config->view_count_option]))
|
||||
{
|
||||
$config->view_count_option = 'once';
|
||||
}
|
||||
|
|
@ -1351,7 +1351,7 @@ class documentController extends document
|
|||
$logged_info = Context::get('logged_info');
|
||||
|
||||
// Option 'some': only count once per session.
|
||||
if ($config->view_count_option != 'all' && $_SESSION['readed_document'][$document_srl])
|
||||
if ($config->view_count_option != 'all' && isset($_SESSION['readed_document'][$document_srl]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1370,7 +1370,7 @@ class documentController extends document
|
|||
}
|
||||
|
||||
// Pass if the author's member_srl is the same as the visitor's.
|
||||
if($member_srl && $logged_info->member_srl && $logged_info->member_srl == $member_srl)
|
||||
if($member_srl && $logged_info && $logged_info->member_srl && $logged_info->member_srl == $member_srl)
|
||||
{
|
||||
$_SESSION['readed_document'][$document_srl] = true;
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ class documentItem extends BaseObject
|
|||
}
|
||||
|
||||
$logged_info = Context::get('logged_info');
|
||||
if (!$logged_info->member_srl)
|
||||
if (!$logged_info || !$logged_info->member_srl)
|
||||
{
|
||||
return $this->grant_cache = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -530,7 +530,7 @@ class installController extends install
|
|||
// Create a table if the schema xml exists in the "schemas" directory of the module
|
||||
$schema_dir = sprintf('%s/schemas/', $module_path);
|
||||
$schema_files = FileHandler::readDir($schema_dir, NULL, false, true);
|
||||
|
||||
$schema_sorted = [];
|
||||
foreach ($schema_files as $filename)
|
||||
{
|
||||
if (!preg_match('/\/([a-zA-Z0-9_]+)\.xml$/', $filename, $matches))
|
||||
|
|
@ -543,16 +543,24 @@ class installController extends install
|
|||
}
|
||||
|
||||
$table_name = $matches[1];
|
||||
if($oDB->isTableExists($table_name))
|
||||
if(isset($schema_sorted[$table_name]) || $oDB->isTableExists($table_name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$schema_sorted[$table_name] = $filename;
|
||||
}
|
||||
|
||||
$schema_sorted = Rhymix\Framework\Parsers\DBTableParser::resolveDependency($schema_sorted);
|
||||
foreach ($schema_sorted as $table_name => $filename)
|
||||
{
|
||||
$output = $oDB->createTable($filename);
|
||||
if(!$output->toBool())
|
||||
{
|
||||
throw new Exception(lang('msg_create_table_failed') . ': ' . $table_name . ': ' . $oDB->getError()->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Create a table and module instance and then execute install() method
|
||||
unset($oModule);
|
||||
$oModule = ModuleModel::getModuleInstallClass($module);
|
||||
|
|
|
|||
|
|
@ -505,7 +505,7 @@ class layoutModel extends layout
|
|||
$cache_file = $this->getUserLayoutCache($layout_srl, Context::getLangType());
|
||||
}
|
||||
|
||||
if(file_exists($cache_file)&&filemtime($cache_file)>filemtime($xml_file))
|
||||
if(file_exists($cache_file) && filemtime($cache_file) > filemtime($xml_file))
|
||||
{
|
||||
include($cache_file);
|
||||
|
||||
|
|
@ -513,7 +513,7 @@ class layoutModel extends layout
|
|||
{
|
||||
foreach($vars as $key => $value)
|
||||
{
|
||||
if(!$layout_info->extra_var->{$key} && !$layout_info->{$key})
|
||||
if(!isset($layout_info->extra_var->{$key}) && !isset($layout_info->{$key}))
|
||||
{
|
||||
$layout_info->{$key} = $value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,8 +38,6 @@
|
|||
<action name="procMemberInsert" type="controller" route="signup" />
|
||||
<action name="procMemberCheckValue" type="controller" />
|
||||
<action name="procMemberLogin" type="controller" route="login" />
|
||||
<action name="procMemberRegisterDevice" type="controller" route="device/register" />
|
||||
<action name="procMemberLoginWithDevice" type="controller" route="device/login" />
|
||||
<action name="procMemberFindAccount" type="controller" method="GET|POST" ruleset="findAccount" />
|
||||
<action name="procMemberFindAccountByQuestion" type="controller" method="GET|POST" />
|
||||
<action name="procMemberAuthAccount" type="controller" method="GET|POST" />
|
||||
|
|
@ -51,7 +49,6 @@
|
|||
<action name="procMemberModifyInfo" type="controller" permission="member" />
|
||||
<action name="procMemberModifyPassword" type="controller" permission="member" ruleset="modifyPassword" />
|
||||
<action name="procMemberModifyEmailAddress" type="controller" permission="member" ruleset="modifyEmailAddress" />
|
||||
<action name="procMemberDeleteDevice" type="controller" permission="member" />
|
||||
<action name="procMemberLeave" type="controller" permission="member" ruleset="leaveMember" />
|
||||
<action name="procMemberInsertProfileImage" type="controller" permission="member" ruleset="insertProfileImage" />
|
||||
<action name="procMemberDeleteProfileImage" type="controller" permission="member" />
|
||||
|
|
@ -73,6 +70,11 @@
|
|||
<action name="procMemberLogout" type="controller" permission="member" />
|
||||
<action name="procMemberSpammerManage" type="controller" permission="manager" check_var="module_srl" />
|
||||
|
||||
<action name="procMemberRegisterDevice" class="Controllers\Device" route="device/register" />
|
||||
<action name="procMemberLoginWithDevice" class="Controllers\Device" route="device/login" />
|
||||
<action name="procMemberUnregisterDevice" class="Controllers\Device" route="device/unregister" />
|
||||
<action name="procMemberDeleteDevice" class="Controllers\Device" permission="member" />
|
||||
|
||||
<action name="dispMemberAdminList" type="view" admin_index="true" menu_name="userList" menu_index="true"/>
|
||||
<action name="dispMemberAdminInfo" type="view" menu_name="userList" />
|
||||
<action name="dispMemberAdminInsert" type="view" menu_name="userList" />
|
||||
|
|
|
|||
376
modules/member/controllers/device.php
Normal file
376
modules/member/controllers/device.php
Normal file
|
|
@ -0,0 +1,376 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Modules\Member\Controllers;
|
||||
|
||||
class Device extends \member
|
||||
{
|
||||
/**
|
||||
* Automatically recognize device token from header or cookie and register it.
|
||||
*
|
||||
* If the device is already registered, just update its last active date.
|
||||
*
|
||||
* @return \BaseObject
|
||||
*/
|
||||
public function autoRegisterDevice(int $member_srl): \BaseObject
|
||||
{
|
||||
$device_token = $this->_getDeviceToken();
|
||||
if ($device_token)
|
||||
{
|
||||
$output = executeQuery('member.getMemberDevice', ['device_token' => $device_token]);
|
||||
if (!$output->data || $output->data->member_srl != $member_srl)
|
||||
{
|
||||
$output = $this->procMemberRegisterDevice($member_srl, $device_token);
|
||||
if ($output instanceof \BaseObject && !$output->toBool())
|
||||
{
|
||||
return $output;
|
||||
}
|
||||
$this->_setDeviceKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
executeQuery('member.updateMemberDeviceLastActiveDate', ['device_token' => $device_token]);
|
||||
}
|
||||
}
|
||||
return new \BaseObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register device
|
||||
*/
|
||||
public function procMemberRegisterDevice($member_srl = null, $device_token = null)
|
||||
{
|
||||
// Set the response method to JSON, but only if this method was called directly.
|
||||
// The response method will remain unchanged, for example, when this method was called by autoRegisterDevice()
|
||||
if (\Context::get('act') === 'procMemberRegisterDevice')
|
||||
{
|
||||
\Context::setResponseMethod('JSON');
|
||||
}
|
||||
|
||||
// Check user_id, password, device_token
|
||||
$allow_guest_device = config('push.allow_guest_device');
|
||||
$user_id = \Context::get('user_id');
|
||||
$password = \Context::get('password');
|
||||
$device_token = $device_token ?? \Context::get('device_token');
|
||||
$device_model = escape(\Context::get('device_model'));
|
||||
|
||||
// Return an error when id and password doesn't exist
|
||||
if (!$member_srl && $this->user->member_srl)
|
||||
{
|
||||
$member_srl = $this->user->member_srl;
|
||||
}
|
||||
if (!$member_srl && !$user_id && !$allow_guest_device)
|
||||
{
|
||||
return new \BaseObject(-1, 'NULL_USER_ID');
|
||||
}
|
||||
if (!$member_srl && !$password && !$allow_guest_device)
|
||||
{
|
||||
return new \BaseObject(-1, 'NULL_PASSWORD');
|
||||
}
|
||||
if (!$device_token)
|
||||
{
|
||||
return new \BaseObject(-1, 'NULL_DEVICE_TOKEN');
|
||||
}
|
||||
|
||||
// Get device information
|
||||
$browserInfo = \Rhymix\Framework\UA::getBrowserInfo();
|
||||
$device_type = escape(strtolower($browserInfo->os));
|
||||
$device_version = $browserInfo->os_version;
|
||||
if (!$device_model)
|
||||
{
|
||||
$device_model = escape($browserInfo->device);
|
||||
}
|
||||
|
||||
// Detect device token type
|
||||
if (preg_match('/^[0-9a-z]{64}$/', $device_token))
|
||||
{
|
||||
$device_token_type = 'apns';
|
||||
}
|
||||
elseif (preg_match('/^[0-9a-zA-Z:_-]+$/', $device_token) && strlen($device_token) > 64)
|
||||
{
|
||||
$device_token_type = 'fcm';
|
||||
}
|
||||
else
|
||||
{
|
||||
return new \BaseObject(-1, 'INVALID_DEVICE_TOKEN');
|
||||
}
|
||||
|
||||
if ($member_srl)
|
||||
{
|
||||
$member_srl = intval($member_srl);
|
||||
}
|
||||
elseif ($user_id && $password)
|
||||
{
|
||||
$output = \memberController::getInstance()->procMemberLogin($user_id, $password);
|
||||
if(!$output->toBool())
|
||||
{
|
||||
return new \BaseObject(-1, 'LOGIN_FAILED');
|
||||
}
|
||||
$logged_info = \Context::get('logged_info');
|
||||
$member_srl = intval($logged_info->member_srl);
|
||||
}
|
||||
else
|
||||
{
|
||||
$logged_info = null;
|
||||
$member_srl = 0;
|
||||
}
|
||||
|
||||
// Generate keys
|
||||
$random_key = \Rhymix\Framework\Security::getRandom();
|
||||
$device_key = hash_hmac('sha256', $random_key, $member_srl . ':' . config('crypto.authentication_key'));
|
||||
|
||||
// Prepare query arguments
|
||||
$args = new \stdClass;
|
||||
$args->device_srl = getNextSequence();
|
||||
$args->member_srl = $member_srl;
|
||||
$args->device_token = $device_token;
|
||||
$args->device_token_type = $device_token_type;
|
||||
$args->device_key = $device_key;
|
||||
$args->device_type = $device_type;
|
||||
$args->device_version = $device_version;
|
||||
$args->device_model = $device_model;
|
||||
|
||||
// Call trigger (before)
|
||||
$trigger_output = \ModuleHandler::triggerCall('member.insertMemberDevice', 'before', $args);
|
||||
if(!$trigger_output->toBool()) return $trigger_output;
|
||||
|
||||
// Start transaction
|
||||
$oDB = \DB::getInstance();
|
||||
$oDB->begin();
|
||||
|
||||
// Remove duplicated token key
|
||||
executeQuery('member.deleteMemberDevice', ['device_token' => $device_token]);
|
||||
|
||||
// Create member_device
|
||||
$output = executeQuery('member.insertMemberDevice', $args);
|
||||
if(!$output->toBool())
|
||||
{
|
||||
$oDB->rollback();
|
||||
return $output;
|
||||
}
|
||||
|
||||
// Call trigger (after)
|
||||
\ModuleHandler::triggerCall('member.insertMemberDevice', 'after', $args);
|
||||
|
||||
$oDB->commit();
|
||||
|
||||
// Set parameters
|
||||
$this->add('member_srl', $member_srl);
|
||||
$this->add('user_id', $logged_info ? $logged_info->user_id : null);
|
||||
$this->add('user_name', $logged_info ? $logged_info->user_name : null);
|
||||
$this->add('nick_name', $logged_info ? $logged_info->nick_name : null);
|
||||
$this->add('device_key', $random_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically log-in to registered device
|
||||
*/
|
||||
public function procMemberLoginWithDevice()
|
||||
{
|
||||
\Context::setResponseMethod('JSON');
|
||||
|
||||
// Check member_srl, device_token, device_key
|
||||
$allow_guest_device = config('push.allow_guest_device');
|
||||
$member_srl = abs(\Context::get('member_srl'));
|
||||
$device_token = strval(\Context::get('device_token'));
|
||||
$random_key = strval(\Context::get('device_key'));
|
||||
|
||||
// Return an error when id, password and device_key doesn't exist
|
||||
if (!$member_srl && !$allow_guest_device)
|
||||
{
|
||||
return new \BaseObject(-1, 'NULL_MEMBER_SRL');
|
||||
}
|
||||
if (!$device_token)
|
||||
{
|
||||
return new \BaseObject(-1, 'NULL_DEVICE_TOKEN');
|
||||
}
|
||||
if (!$random_key)
|
||||
{
|
||||
return new \BaseObject(-1, 'NULL_DEVICE_KEY');
|
||||
}
|
||||
|
||||
// Check the device token and key.
|
||||
$args = new \stdClass;
|
||||
$args->member_srl = $member_srl;
|
||||
$args->device_token = $device_token;
|
||||
$args->device_key = hash_hmac('sha256', $random_key, $member_srl . ':' . config('crypto.authentication_key'));
|
||||
$output = executeQuery('member.getMemberDevice', $args);
|
||||
if (!$output->toBool())
|
||||
{
|
||||
return new \BaseObject(-1, 'DEVICE_RETRIEVE_FAILED');
|
||||
}
|
||||
if (!$output->data || !is_object($output->data))
|
||||
{
|
||||
return new \BaseObject(-1, 'UNREGISTERED_DEVICE');
|
||||
}
|
||||
|
||||
// Log-in
|
||||
if($member_srl)
|
||||
{
|
||||
$member_info = \MemberModel::getMemberInfoByMemberSrl($member_srl);
|
||||
$output = \memberController::getInstance()->doLogin($member_info->user_id);
|
||||
if(!$output->toBool())
|
||||
{
|
||||
return new \BaseObject(-1, 'LOGIN_FAILED');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$member_info = null;
|
||||
}
|
||||
|
||||
// Update last active date
|
||||
executeQuery('member.updateMemberDeviceLastActiveDate', ['device_token' => $device_token]);
|
||||
|
||||
$this->add('member_srl', $member_srl);
|
||||
$this->add('user_id', $member_info ? $member_info->user_id : null);
|
||||
$this->add('user_name', $member_info ? $member_info->user_name : null);
|
||||
$this->add('nick_name', $member_info ? $member_info->nick_name : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a registered device.
|
||||
*
|
||||
* This action requires a device token and matching device key.
|
||||
* It is intended to be called by mobile applications.
|
||||
*/
|
||||
public function procMemberUnregisterDevice()
|
||||
{
|
||||
\Context::setResponseMethod('JSON');
|
||||
|
||||
// Check member_srl, device_token, device_key
|
||||
$allow_guest_device = config('push.allow_guest_device');
|
||||
$member_srl = abs(\Context::get('member_srl'));
|
||||
$device_token = strval(\Context::get('device_token'));
|
||||
$random_key = strval(\Context::get('device_key'));
|
||||
|
||||
// Return an error when id, password and device_key doesn't exist
|
||||
if (!$member_srl && !$allow_guest_device)
|
||||
{
|
||||
return new \BaseObject(-1, 'NULL_MEMBER_SRL');
|
||||
}
|
||||
if (!$device_token)
|
||||
{
|
||||
return new \BaseObject(-1, 'NULL_DEVICE_TOKEN');
|
||||
}
|
||||
if (!$random_key)
|
||||
{
|
||||
return new \BaseObject(-1, 'NULL_DEVICE_KEY');
|
||||
}
|
||||
|
||||
// Check the device token and key.
|
||||
$args = new \stdClass;
|
||||
$args->member_srl = $member_srl;
|
||||
$args->device_token = $device_token;
|
||||
$args->device_key = hash_hmac('sha256', $random_key, $member_srl . ':' . config('crypto.authentication_key'));
|
||||
$output = executeQuery('member.getMemberDevice', $args);
|
||||
if (!$output->toBool())
|
||||
{
|
||||
return new \BaseObject(-1, 'DEVICE_RETRIEVE_FAILED');
|
||||
}
|
||||
if (!$output->data || !is_object($output->data))
|
||||
{
|
||||
return new \BaseObject(-1, 'UNREGISTERED_DEVICE');
|
||||
}
|
||||
|
||||
// Delete the device.
|
||||
$args = new \stdClass;
|
||||
$args->device_token = $device_token;
|
||||
$output = executeQuery('member.deleteMemberDevice', $args);
|
||||
if (!$output->toBool())
|
||||
{
|
||||
return new \BaseObject(-1, 'DELETE_FAILED');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a registered device.
|
||||
*
|
||||
* This action requires only the device_srl, but it must belong to the currently logged in member.
|
||||
* It is intended to be called from the web frontend.
|
||||
*/
|
||||
public function procMemberDeleteDevice()
|
||||
{
|
||||
// Check the device_srl and member_srl of the currently logged in member.
|
||||
$device_srl = intval(\Context::get('device_srl'));
|
||||
if (!$device_srl)
|
||||
{
|
||||
throw new \Rhymix\Framework\Exceptions\InvalidRequest;
|
||||
}
|
||||
|
||||
$member_srl = $this->user->member_srl;
|
||||
if (!$member_srl)
|
||||
{
|
||||
throw new \Rhymix\Framework\Exceptions\NotPermitted;
|
||||
}
|
||||
|
||||
// Check that the device_srl matches the member.
|
||||
$args = new \stdClass;
|
||||
$args->device_srl = $device_srl;
|
||||
$args->member_srl = $member_srl;
|
||||
$output = executeQuery('member.getMemberDevice', $args);
|
||||
if (!$output->data || !is_object($output->data))
|
||||
{
|
||||
throw new \Rhymix\Framework\Exceptions\TargetNotFound;
|
||||
}
|
||||
|
||||
// Delete the device.
|
||||
$args = new \stdClass;
|
||||
$args->device_token = $output->data->device_token;
|
||||
$output = executeQuery('member.deleteMemberDevice', $args);
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get device token from POST parameter, HTTP header or cookie
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function _getDeviceToken()
|
||||
{
|
||||
// POST parameter named device_token
|
||||
$device_token = $_POST['device_token'] ?? null;
|
||||
if ($device_token && is_string($device_token) && $device_token !== '')
|
||||
{
|
||||
return $device_token;
|
||||
}
|
||||
|
||||
// HTTP header named X-Device-Token
|
||||
$device_token = $_SERVER['HTTP_X_DEVICE_TOKEN'] ?? null;
|
||||
if ($device_token)
|
||||
{
|
||||
return $device_token;
|
||||
}
|
||||
|
||||
// Cookie named device_token
|
||||
$device_token = $_COOKIE['device_token'] ?? null;
|
||||
if ($device_token)
|
||||
{
|
||||
return $device_token;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set device key via header or cookie
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function _setDeviceKey()
|
||||
{
|
||||
$member_srl = $this->get('member_srl');
|
||||
$device_key = $this->get('device_key');
|
||||
if (!$member_srl || !$device_key)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set header if header was given, or cookie otherwise
|
||||
if (isset($_SERVER['HTTP_X_DEVICE_TOKEN']))
|
||||
{
|
||||
header('X-Device-Key: ' . urlencode($member_srl . ':' . $device_key));
|
||||
}
|
||||
else
|
||||
{
|
||||
setcookie('device_key', $member_srl . ':' . $device_key, time() + 60, \RX_BASEURL, null, !!config('session.use_ssl_cookies'), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -303,6 +303,7 @@ $lang->cmd_optional = 'Optional';
|
|||
$lang->cmd_disabled = 'Disabled';
|
||||
$lang->cmd_image_max_width = 'Max Width';
|
||||
$lang->cmd_image_max_height = 'Max Height';
|
||||
$lang->cmd_image_force_ratio = 'Fixed Aspect Ratio';
|
||||
$lang->cmd_input_extend_form = 'Add Signup Form Field';
|
||||
$lang->about_multi_type = 'Enter the value of multi-or single-item selection.(separated by line breaks)';
|
||||
$lang->msg_delete_extend_form = 'Delete the selected item.';
|
||||
|
|
|
|||
|
|
@ -317,6 +317,7 @@ $lang->cmd_optional = '선택';
|
|||
$lang->cmd_disabled = '사용 안 함';
|
||||
$lang->cmd_image_max_width = '너비 제한';
|
||||
$lang->cmd_image_max_height = '높이 제한';
|
||||
$lang->cmd_image_force_ratio = '가로세로 비율 고정';
|
||||
$lang->cmd_input_extend_form = '회원가입 추가 항목 생성';
|
||||
$lang->about_multi_type = '다중 또는 단일 항목의 선택 값을 입력하세요.(줄 바꿈으로 구분)';
|
||||
$lang->msg_delete_extend_form = '선택한 항목을 삭제합니다.';
|
||||
|
|
|
|||
|
|
@ -17,7 +17,10 @@
|
|||
<input id="email_address1" type="email" name="email_address" />
|
||||
</li>
|
||||
</ul>
|
||||
<div class="captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('recovery')">
|
||||
{$captcha}
|
||||
</div>
|
||||
<div class="bna">
|
||||
<input type="submit" class="bn dark" value="{$lang->cmd_send_mail}" />
|
||||
<input type="submit" class="bn dark" value="{$lang->cmd_send_mail}" />
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
<li><label for="id"><!--@if($identifier == 'user_id')-->{$lang->user_id}<!--@else-->{$lang->email_address}<!--@end--></label><input name="user_id" type="<!--@if($identifier == 'user_id')-->text<!--@else-->email<!--@end-->" id="id" value="" /></li>
|
||||
<li><label for="pw">{$lang->password}</label><input name="password" type="password" id="pw" value="" /></li>
|
||||
</ul>
|
||||
<div class="captcha" cond="$captcha">
|
||||
<div class="captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('login')">
|
||||
{$captcha}
|
||||
</div>
|
||||
<div class="hp" id="keep_msg" style="display:none;">
|
||||
|
|
|
|||
|
|
@ -60,9 +60,12 @@
|
|||
</block>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="bna">
|
||||
<input type="submit" class="bn dark" value="{$lang->cmd_registration}" />
|
||||
</div>
|
||||
<div class="captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('signup')">
|
||||
{$captcha}
|
||||
</div>
|
||||
<div class="bna">
|
||||
<input type="submit" class="bn dark" value="{$lang->cmd_registration}" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<script>
|
||||
|
|
@ -95,4 +98,4 @@
|
|||
return false;});
|
||||
});
|
||||
})(jQuery);
|
||||
</script>
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -156,7 +156,13 @@ class memberAdminController extends member
|
|||
$validity_info = Rhymix\Framework\Session::getValidityInfo($args->member_srl);
|
||||
$validity_info->invalid_before = time();
|
||||
Rhymix\Framework\Session::setValidityInfo($args->member_srl, $validity_info);
|
||||
executeQuery('member.deleteAutologin', (object)array('member_srl' => $args->member_srl));
|
||||
executeQuery('member.deleteAutologin', ['member_srl' => $args->member_srl]);
|
||||
}
|
||||
|
||||
// Invalidate auth mail if denied or limited
|
||||
if ($args->denied === 'Y' || $args->limited >= date('Ymd'))
|
||||
{
|
||||
executeQuery('member.deleteAuthMail', ['member_srl' => $args->member_srl]);
|
||||
}
|
||||
|
||||
// Save Signature
|
||||
|
|
@ -371,7 +377,7 @@ class memberAdminController extends member
|
|||
'emailhost_check',
|
||||
'special_phone_number', 'special_phone_code', 'max_auth_sms_count', 'max_auth_sms_count_time', 'redirect_url',
|
||||
'phone_number_default_country', 'phone_number_hide_country', 'phone_number_allow_duplicate', 'phone_number_verify_by_sms',
|
||||
'profile_image_max_width', 'profile_image_max_height', 'profile_image_max_filesize',
|
||||
'profile_image_max_width', 'profile_image_max_height', 'profile_image_max_filesize', 'profile_image_force_ratio',
|
||||
'image_name_max_width', 'image_name_max_height', 'image_name_max_filesize',
|
||||
'image_mark_max_width', 'image_mark_max_height', 'image_mark_max_filesize',
|
||||
'signature_editor_skin', 'sel_editor_colorset', 'signature_html', 'signature_html_retroact', 'member_allow_fileupload'
|
||||
|
|
@ -469,6 +475,7 @@ class memberAdminController extends member
|
|||
$signupItem->max_width = $all_args->{$key.'_max_width'};
|
||||
$signupItem->max_height = $all_args->{$key.'_max_height'};
|
||||
$signupItem->max_filesize = $all_args->{$key.'_max_filesize'};
|
||||
$signupItem->force_ratio = $all_args->{$key.'_force_ratio'} === 'N' ? 'N' : 'Y';
|
||||
}
|
||||
|
||||
// set extends form
|
||||
|
|
|
|||
|
|
@ -33,22 +33,50 @@ class memberController extends member
|
|||
throw new Rhymix\Framework\Exception('null_user_id');
|
||||
}
|
||||
|
||||
// Variables
|
||||
if(!$user_id) $user_id = Context::get('user_id');
|
||||
$user_id = trim($user_id);
|
||||
$config = MemberModel::getMemberConfig();
|
||||
|
||||
if(!$password) $password = Context::get('password');
|
||||
$password = trim($password);
|
||||
// User ID, email address or phone number
|
||||
if (!$user_id)
|
||||
{
|
||||
$user_id = trim(Context::get('user_id'));
|
||||
}
|
||||
if (!$user_id && $config->identifiers && in_array('email_address', $config->identifiers))
|
||||
{
|
||||
$user_id = trim(Context::get('email_address'));
|
||||
}
|
||||
if (!$user_id && $config->identifiers && in_array('phone_number', $config->identifiers))
|
||||
{
|
||||
$user_id = trim(Context::get('phone_number'));
|
||||
}
|
||||
if (!$user_id)
|
||||
{
|
||||
throw new Rhymix\Framework\Exception('null_user_id');
|
||||
}
|
||||
|
||||
if(!$keep_signed) $keep_signed = Context::get('keep_signed');
|
||||
// Return an error when id and password doesn't exist
|
||||
if(!$user_id) throw new Rhymix\Framework\Exception('null_user_id');
|
||||
if(!$password) throw new Rhymix\Framework\Exception('null_password');
|
||||
// Password
|
||||
if (!$password)
|
||||
{
|
||||
$password = trim(Context::get('password'));
|
||||
}
|
||||
if (!$password)
|
||||
{
|
||||
throw new Rhymix\Framework\Exception('null_password');
|
||||
}
|
||||
|
||||
$output = $this->doLogin($user_id, $password, $keep_signed=='Y'?true:false);
|
||||
if (!$output->toBool()) return $output;
|
||||
// Autologin option
|
||||
if (!$keep_signed)
|
||||
{
|
||||
$keep_signed = Context::get('keep_signed');
|
||||
}
|
||||
|
||||
$config = ModuleModel::getModuleConfig('member');
|
||||
// Attempt login
|
||||
$output = $this->doLogin($user_id, $password, $keep_signed === 'Y' ? true : false);
|
||||
if (!$output->toBool())
|
||||
{
|
||||
return $output;
|
||||
}
|
||||
|
||||
// Get info of member who just logged in
|
||||
$member_info = Context::get('logged_info');
|
||||
|
||||
// Check change_password_date
|
||||
|
|
@ -71,24 +99,7 @@ class memberController extends member
|
|||
executeQuery('member.deleteAuthMail', $args);
|
||||
|
||||
// If a device token is supplied, attempt to register it.
|
||||
$device_token = $this->_getDeviceToken();
|
||||
if ($device_token)
|
||||
{
|
||||
$output = executeQuery('member.getMemberDevice', ['device_token' => $device_token]);
|
||||
if (!$output->data || $output->data->member_srl != $member_info->member_srl)
|
||||
{
|
||||
$output = $this->procMemberRegisterDevice($member_info->member_srl, $device_token);
|
||||
if ($output instanceof BaseObject && !$output->toBool())
|
||||
{
|
||||
return $output;
|
||||
}
|
||||
$this->_setDeviceKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
executeQuery('member.updateMemberDeviceLastActiveDate', ['device_token' => $device_token]);
|
||||
}
|
||||
}
|
||||
Rhymix\Modules\Member\Controllers\Device::getInstance()->autoRegisterDevice($member_info->member_srl);
|
||||
|
||||
if(!$config->after_login_url)
|
||||
{
|
||||
|
|
@ -101,242 +112,6 @@ class memberController extends member
|
|||
return $this->setRedirectUrl($returnUrl, $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register device
|
||||
*/
|
||||
function procMemberRegisterDevice($member_srl = null, $device_token = null)
|
||||
{
|
||||
if (Context::get('act') === 'procMemberRegisterDevice')
|
||||
{
|
||||
Context::setResponseMethod('JSON');
|
||||
}
|
||||
|
||||
// Check user_id, password, device_token
|
||||
$allow_guest_device = config('push.allow_guest_device');
|
||||
$user_id = Context::get('user_id');
|
||||
$password = Context::get('password');
|
||||
$device_token = $device_token ?? Context::get('device_token');
|
||||
$device_model = escape(Context::get('device_model'));
|
||||
|
||||
// Return an error when id and password doesn't exist
|
||||
if(!$member_srl && $this->user->member_srl)
|
||||
{
|
||||
$member_srl = $this->user->member_srl;
|
||||
}
|
||||
if(!$member_srl && !$user_id && !$allow_guest_device)
|
||||
{
|
||||
return new BaseObject(-1, 'NULL_USER_ID');
|
||||
}
|
||||
if(!$member_srl && !$password && !$allow_guest_device)
|
||||
{
|
||||
return new BaseObject(-1, 'NULL_PASSWORD');
|
||||
}
|
||||
if(!$device_token)
|
||||
{
|
||||
return new BaseObject(-1, 'NULL_DEVICE_TOKEN');
|
||||
}
|
||||
|
||||
// Get device information
|
||||
$browserInfo = Rhymix\Framework\UA::getBrowserInfo();
|
||||
$device_type = escape(strtolower($browserInfo->os));
|
||||
$device_version = $browserInfo->os_version;
|
||||
if(!$device_model)
|
||||
{
|
||||
$device_model = escape($browserInfo->device);
|
||||
}
|
||||
|
||||
// Detect device token type
|
||||
if (preg_match('/^[0-9a-z]{64}$/', $device_token))
|
||||
{
|
||||
$device_token_type = 'apns';
|
||||
}
|
||||
elseif (preg_match('/^[0-9a-zA-Z:_-]+$/', $device_token) && strlen($device_token) > 64)
|
||||
{
|
||||
$device_token_type = 'fcm';
|
||||
}
|
||||
else
|
||||
{
|
||||
return new BaseObject(-1, 'INVALID_DEVICE_TOKEN');
|
||||
}
|
||||
|
||||
if ($member_srl)
|
||||
{
|
||||
$member_srl = intval($member_srl);
|
||||
}
|
||||
elseif ($user_id && $password)
|
||||
{
|
||||
$output = $this->procMemberLogin($user_id, $password);
|
||||
if(!$output->toBool())
|
||||
{
|
||||
return new BaseObject(-1, 'LOGIN_FAILED');
|
||||
}
|
||||
$logged_info = Context::get('logged_info');
|
||||
$member_srl = intval($logged_info->member_srl);
|
||||
}
|
||||
else
|
||||
{
|
||||
$logged_info = null;
|
||||
$member_srl = 0;
|
||||
}
|
||||
|
||||
// Generate keys
|
||||
$random_key = Rhymix\Framework\Security::getRandom();
|
||||
$device_key = hash_hmac('sha256', $random_key, $member_srl . ':' . config('crypto.authentication_key'));
|
||||
|
||||
// Prepare query arguments
|
||||
$args = new stdClass;
|
||||
$args->device_srl = getNextSequence();
|
||||
$args->member_srl = $member_srl;
|
||||
$args->device_token = $device_token;
|
||||
$args->device_token_type = $device_token_type;
|
||||
$args->device_key = $device_key;
|
||||
$args->device_type = $device_type;
|
||||
$args->device_version = $device_version;
|
||||
$args->device_model = $device_model;
|
||||
|
||||
// Call trigger (before)
|
||||
$trigger_output = ModuleHandler::triggerCall('member.insertMemberDevice', 'before', $args);
|
||||
if(!$trigger_output->toBool()) return $trigger_output;
|
||||
|
||||
// Start transaction
|
||||
$oDB = DB::getInstance();
|
||||
$oDB->begin();
|
||||
|
||||
// Remove duplicated token key
|
||||
executeQuery('member.deleteMemberDevice', ['device_token' => $device_token]);
|
||||
|
||||
// Create member_device
|
||||
$output = executeQuery('member.insertMemberDevice', $args);
|
||||
if(!$output->toBool())
|
||||
{
|
||||
$oDB->rollback();
|
||||
return $output;
|
||||
}
|
||||
|
||||
// Call trigger (after)
|
||||
ModuleHandler::triggerCall('member.insertMemberDevice', 'after', $args);
|
||||
|
||||
$oDB->commit();
|
||||
|
||||
// Set parameters
|
||||
$this->add('member_srl', $member_srl);
|
||||
$this->add('user_id', $logged_info ? $logged_info->user_id : null);
|
||||
$this->add('user_name', $logged_info ? $logged_info->user_name : null);
|
||||
$this->add('nick_name', $logged_info ? $logged_info->nick_name : null);
|
||||
$this->add('device_key', $random_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically log-in to registered device
|
||||
*/
|
||||
function procMemberLoginWithDevice()
|
||||
{
|
||||
Context::setResponseMethod('JSON');
|
||||
|
||||
// Check member_srl, device_token, device_key
|
||||
$allow_guest_device = config('push.allow_guest_device');
|
||||
$member_srl = intval(Context::get('member_srl'));
|
||||
$device_token = Context::get('device_token');
|
||||
$random_key = Context::get('device_key');
|
||||
|
||||
// Return an error when id, password and device_key doesn't exist
|
||||
if(!$member_srl && !$allow_guest_device) return new BaseObject(-1, 'NULL_MEMBER_SRL');
|
||||
if(!$device_token) return new BaseObject(-1, 'NULL_DEVICE_TOKEN');
|
||||
if(!$random_key) return new BaseObject(-1, 'NULL_DEVICE_KEY');
|
||||
|
||||
$args = new stdClass;
|
||||
$args->member_srl = $member_srl;
|
||||
$args->device_token = $device_token;
|
||||
$args->device_key = hash_hmac('sha256', $random_key, $member_srl . ':' . config('crypto.authentication_key'));
|
||||
$output = executeQueryArray('member.getMemberDevice', $args);
|
||||
if(!$output->toBool())
|
||||
{
|
||||
return new BaseObject(-1, 'DEVICE_RETRIEVE_FAILED');
|
||||
}
|
||||
|
||||
if(!$output->data)
|
||||
{
|
||||
return new BaseObject(-1, 'UNREGISTERED_DEVICE');
|
||||
}
|
||||
|
||||
// Log-in
|
||||
if($member_srl)
|
||||
{
|
||||
$member_info = MemberModel::getMemberInfoByMemberSrl($member_srl);
|
||||
$output = $this->doLogin($member_info->user_id);
|
||||
if(!$output->toBool())
|
||||
{
|
||||
return new BaseObject(-1, 'LOGIN_FAILED');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$member_info = null;
|
||||
}
|
||||
|
||||
// Update last active date
|
||||
executeQuery('member.updateMemberDeviceLastActiveDate', ['device_token' => $device_token]);
|
||||
|
||||
$this->add('member_srl', $member_srl);
|
||||
$this->add('user_id', $member_info ? $member_info->user_id : null);
|
||||
$this->add('user_name', $member_info ? $member_info->user_name : null);
|
||||
$this->add('nick_name', $member_info ? $member_info->nick_name : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get device token from POST parameter, HTTP header or cookie
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function _getDeviceToken()
|
||||
{
|
||||
// POST parameter named device_token
|
||||
$device_token = Context::get('device_token');
|
||||
if ($device_token && $_SERVER['REQUEST_METHOD'] === 'POST')
|
||||
{
|
||||
return $device_token;
|
||||
}
|
||||
|
||||
// HTTP header named X-Device-Token
|
||||
$device_token = $_SERVER['HTTP_X_DEVICE_TOKEN'] ?? null;
|
||||
if ($device_token)
|
||||
{
|
||||
return $device_token;
|
||||
}
|
||||
|
||||
// Cookie named device_token
|
||||
$device_token = $_COOKIE['device_token'] ?? null;
|
||||
if ($device_token)
|
||||
{
|
||||
return $device_token;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set device key via header or cookie
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function _setDeviceKey()
|
||||
{
|
||||
$member_srl = $this->get('member_srl');
|
||||
$device_key = $this->get('device_key');
|
||||
if (!$member_srl || !$device_key)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set header if header was given, or cookie otherwise
|
||||
if (isset($_SERVER['HTTP_X_DEVICE_TOKEN']))
|
||||
{
|
||||
header('X-Device-Key: ' . urlencode($member_srl . ':' . $device_key));
|
||||
}
|
||||
else
|
||||
{
|
||||
setcookie('device_key', $member_srl . ':' . $device_key, time() + 60, \RX_BASEURL, null, !!config('session.use_ssl_cookies'), true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log-out
|
||||
*
|
||||
|
|
@ -1050,16 +825,7 @@ class memberController extends member
|
|||
}
|
||||
|
||||
// Register device
|
||||
$device_token = $this->_getDeviceToken();
|
||||
if ($device_token)
|
||||
{
|
||||
$output = $this->procMemberRegisterDevice($args->member_srl, $device_token);
|
||||
if ($output instanceof BaseObject && !$output->toBool())
|
||||
{
|
||||
return $output;
|
||||
}
|
||||
$this->_setDeviceKey();
|
||||
}
|
||||
Rhymix\Modules\Member\Controllers\Device::getInstance()->autoRegisterDevice($args->member_srl, false);
|
||||
|
||||
// Results
|
||||
$this->add('member_srl', $args->member_srl);
|
||||
|
|
@ -1431,7 +1197,7 @@ class memberController extends member
|
|||
* Insert a profile image
|
||||
*
|
||||
* @param int $member_srl
|
||||
* @param object $target_file
|
||||
* @param string $target_file
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
|
@ -1458,14 +1224,27 @@ class memberController extends member
|
|||
}
|
||||
|
||||
$target_path = sprintf('files/member_extra_info/profile_image/%s', getNumberingPath($member_srl));
|
||||
$target_filename = sprintf('%s%d.%s', $target_path, $member_srl, $ext);
|
||||
FileHandler::makeDir($target_path);
|
||||
|
||||
$target_filename = sprintf('%s%d.%s', $target_path, $member_srl, $ext);
|
||||
// Convert if the image size is larger than a given size
|
||||
if($width > $max_width || $height > $max_height)
|
||||
if ($width > $max_width || $height > $max_height)
|
||||
{
|
||||
$resize = true;
|
||||
}
|
||||
elseif ($config->profile_image_force_ratio !== 'N' && ($width / $height !== $max_width / $max_height))
|
||||
{
|
||||
$resize = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$resize = false;
|
||||
}
|
||||
|
||||
if ($resize)
|
||||
{
|
||||
$temp_filename = sprintf('files/cache/tmp/profile_image_%d.%s', $member_srl, $ext);
|
||||
FileHandler::createImageFile($target_file, $temp_filename, $max_width, $max_height, $ext);
|
||||
FileHandler::createImageFile($target_file, $temp_filename, $max_width, $max_height, $ext, 'fill', 75);
|
||||
|
||||
// 파일 용량 제한
|
||||
FileHandler::clearStatCache($temp_filename);
|
||||
|
|
@ -3686,35 +3465,6 @@ class memberController extends member
|
|||
$_SESSION['verify_by_sms']['status'] = true;
|
||||
return new BaseObject(0, 'verify_by_sms_code_confirmed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a registered device.
|
||||
*/
|
||||
public function procMemberDeleteDevice()
|
||||
{
|
||||
$device_srl = intval(Context::get('device_srl'));
|
||||
$logged_info = Context::get('logged_info');
|
||||
|
||||
$args = new stdClass;
|
||||
$args->device_srl = $device_srl;
|
||||
$output = executeQuery('member.getMemberDevice', $args);
|
||||
if (!$output->data || !is_object($output->data))
|
||||
{
|
||||
throw new Rhymix\Framework\Exceptions\TargetNotFound;
|
||||
}
|
||||
if (!$output->data->member_srl || $output->data->member_srl != $logged_info->member_srl)
|
||||
{
|
||||
throw new Rhymix\Framework\Exceptions\TargetNotFound;
|
||||
}
|
||||
|
||||
$args = new stdClass;
|
||||
$args->device_token = $output->data->device_token;
|
||||
$output = executeQuery('member.deleteMemberDevice', $args);
|
||||
if (!$output->toBool())
|
||||
{
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* trigger for document.getDocumentMenu. Append to popup menu a button for procMemberSpammerManage()
|
||||
|
|
|
|||
|
|
@ -481,8 +481,17 @@ class memberModel extends member
|
|||
$oSecurity = new Security($info);
|
||||
$oSecurity->encodeHTML('user_id', 'user_name', 'nick_name', 'find_account_answer', 'description', 'address.', 'group_list..');
|
||||
|
||||
$info->homepage = strip_tags($info->homepage);
|
||||
$info->blog = strip_tags($info->blog);
|
||||
// Validate URLs
|
||||
$info->homepage = escape(strip_tags($info->homepage));
|
||||
if ($info->homepage !== '' && !preg_match('!^https?://[^\\\\/]+!', $info->homepage))
|
||||
{
|
||||
$info->homepage = '';
|
||||
}
|
||||
$info->blog = escape(strip_tags($info->blog));
|
||||
if ($info->blog !== '' && !preg_match('!^https?://[^\\\\/]+!', $info->blog))
|
||||
{
|
||||
$info->blog = '';
|
||||
}
|
||||
|
||||
if($extra_vars)
|
||||
{
|
||||
|
|
@ -499,18 +508,6 @@ class memberModel extends member
|
|||
}
|
||||
}
|
||||
|
||||
// Check format.
|
||||
$oValidator = new Validator();
|
||||
if(!$oValidator->applyRule('url', $info->homepage))
|
||||
{
|
||||
$info->homepage = '';
|
||||
}
|
||||
|
||||
if(!$oValidator->applyRule('url', $info->blog))
|
||||
{
|
||||
$info->blog = '';
|
||||
}
|
||||
|
||||
$GLOBALS['__member_info__'][$info->member_srl] = $info;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -607,9 +607,18 @@ class memberView extends member
|
|||
*/
|
||||
function dispMemberLoginForm()
|
||||
{
|
||||
// Get referer URL
|
||||
$referer_url = Context::get('referer_url') ?: ($_SERVER['HTTP_REFERER'] ?? '');
|
||||
if (!$referer_url || !Rhymix\Framework\URL::isInternalURL($referer_url) || contains('procMember', $referer_url))
|
||||
{
|
||||
$referer_url = getNotEncodedUrl('act', '');
|
||||
}
|
||||
Context::set('referer_url', $referer_url);
|
||||
|
||||
// Return to previous screen if already logged in.
|
||||
if(Context::get('is_logged'))
|
||||
{
|
||||
$this->setRedirectUrl(getNotEncodedUrl('act',''));
|
||||
$this->setRedirectUrl($referer_url);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -617,6 +626,7 @@ class memberView extends member
|
|||
$config = $this->member_config;
|
||||
Context::set('identifier', $config->identifier);
|
||||
|
||||
// Get validator status
|
||||
$XE_VALIDATOR_MESSAGE = Context::get('XE_VALIDATOR_MESSAGE');
|
||||
$XE_VALIDATOR_ERROR = Context::get('XE_VALIDATOR_ERROR');
|
||||
if($XE_VALIDATOR_ERROR == -11)
|
||||
|
|
@ -624,15 +634,6 @@ class memberView extends member
|
|||
Context::set('XE_VALIDATOR_MESSAGE', $XE_VALIDATOR_MESSAGE . $config->limit_day_description);
|
||||
}
|
||||
|
||||
if(strpos(Context::get('referer_url'), 'procMember') !== false || ($XE_VALIDATOR_ERROR < -10 && $XE_VALIDATOR_ERROR > -21))
|
||||
{
|
||||
Context::set('referer_url', getUrl(''));
|
||||
}
|
||||
else
|
||||
{
|
||||
Context::set('referer_url', escape($_SERVER['HTTP_REFERER']));
|
||||
}
|
||||
|
||||
// Set a template file
|
||||
$this->setTemplateFile('login_form');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,9 @@
|
|||
<input type="hidden" name="xe_validator_id" value="modules/member/skin/default/find_member_account/1" />
|
||||
<div>
|
||||
<input type="email" name="email_address" required placeholder="{$lang->email_address}" title="{$lang->email_address}" /><br />
|
||||
<block cond="$captcha">{$captcha}<br /></block>
|
||||
<block cond="isset($captcha) && $captcha && $captcha->isTargetAction('recovery')">
|
||||
{$captcha}<br />
|
||||
</block>
|
||||
<input type="submit" class="btn btn-inverse" value="{$lang->cmd_find_member_account}" />
|
||||
</div>
|
||||
</form>
|
||||
|
|
@ -33,7 +35,9 @@
|
|||
<input type="hidden" name="xe_validator_id" value="modules/member/skin/default/find_member_account/3" />
|
||||
<div>
|
||||
<input type="email" id="email_address" name="email_address" value="" required placeholder="{$lang->email_address}" title="{$lang->email_address}" /><br />
|
||||
<block cond="$captcha">{$captcha}<br /></block>
|
||||
<block cond="isset($captcha) && $captcha && $captcha->isTargetAction('recovery')">
|
||||
{$captcha}<br />
|
||||
</block>
|
||||
<input type="submit" value="{$lang->cmd_resend_auth_mail}" class="btn btn-inverse" />
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
<input type="email" cond="$identifier != 'user_id'" name="user_id" id="uid" required placeholder="{$lang->email_address}" title="{$lang->email_address}" />
|
||||
<input type="password" name="password" id="upw" required placeholder="{$lang->password}" title="{$lang->password}" />
|
||||
</div>
|
||||
<div class="control-group captcha" cond="$captcha">
|
||||
<div class="control-group captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('login')">
|
||||
{$captcha}
|
||||
</div>
|
||||
<div class="control-group">
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@
|
|||
<label for="allow_{$key}" loop="$lang->allow_message_type=>$key,$val"><input type="radio" name="allow_message" value="{$key}" checked="checked"|cond="$member_info->allow_message == $key || (!$member_info && $key == 'Y')" id="allow_{$key}" /> {$val}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group" cond="$captcha">
|
||||
<div class="control-group captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('signup')">
|
||||
<div class="control-label">{$lang->captcha}</div>
|
||||
<div class="controls">{$captcha}</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -152,6 +152,13 @@
|
|||
<p class="x_help-block">
|
||||
<label class="x_inline" for="{$item->name}_max_filesize">{$lang->allowed_filesize}</label> <input type="number" min="1" name="{$item->name}_max_filesize" id="{$item->name}_max_filesize" value="{$item->max_filesize}" /> KB
|
||||
</p>
|
||||
<!--@if($item->name === 'profile_image')-->
|
||||
<p class="x_help-block">
|
||||
<label class="x_inline">{$lang->cmd_image_force_ratio}</label>
|
||||
<label class="x_inline"><input type="radio" name="profile_image_force_ratio" value="Y" checked="checked"|cond="$config->profile_image_force_ratio !== 'N'" /> {$lang->cmd_yes}</label>
|
||||
<label class="x_inline"><input type="radio" name="profile_image_force_ratio" value="N" checked="checked"|cond="$config->profile_image_force_ratio === 'N'" /> {$lang->cmd_no}</label>
|
||||
</p>
|
||||
<!--@endif-->
|
||||
</div>
|
||||
|
||||
<div cond="$item->name == 'phone_number'" class="_subItem" style="display:none"|cond="!$item->isUse">
|
||||
|
|
|
|||
|
|
@ -1939,9 +1939,9 @@ class moduleModel extends module
|
|||
$module_info->module = $module_info->module_srl = 0;
|
||||
}
|
||||
|
||||
if (isset($GLOBALS['__MODULE_GRANT__'][$module_info->module][intval($module_info->module_srl ?? 0)][intval($member_info->member_srl)]))
|
||||
if (isset($GLOBALS['__MODULE_GRANT__'][$module_info->module][intval($module_info->module_srl ?? 0)][intval($member_info->member_srl ?? 0)]))
|
||||
{
|
||||
$__cache = &$GLOBALS['__MODULE_GRANT__'][$module_info->module][intval($module_info->module_srl ?? 0)][intval($member_info->member_srl)];
|
||||
$__cache = &$GLOBALS['__MODULE_GRANT__'][$module_info->module][intval($module_info->module_srl ?? 0)][intval($member_info->member_srl ?? 0)];
|
||||
if (is_object($__cache) && !$xml_info)
|
||||
{
|
||||
return $__cache;
|
||||
|
|
@ -1975,7 +1975,7 @@ class moduleModel extends module
|
|||
foreach($privilege_list as $val)
|
||||
{
|
||||
// If an administrator, grant all
|
||||
if($member_info->is_admin == 'Y')
|
||||
if($member_info && $member_info->is_admin == 'Y')
|
||||
{
|
||||
$grant->{$val} = true;
|
||||
}
|
||||
|
|
@ -2018,7 +2018,7 @@ class moduleModel extends module
|
|||
}
|
||||
|
||||
// Log-in member only
|
||||
if($member_info->member_srl)
|
||||
if($member_info && $member_info->member_srl)
|
||||
{
|
||||
if($val->group_srl == -1 || $val->group_srl == -2)
|
||||
{
|
||||
|
|
@ -2063,7 +2063,7 @@ class moduleModel extends module
|
|||
}
|
||||
|
||||
// Log-in member only
|
||||
if($member_info->member_srl)
|
||||
if($member_info && $member_info->member_srl)
|
||||
{
|
||||
if($item->default == 'member' || $item->default == 'site')
|
||||
{
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ class ncenterliteController extends ncenterlite
|
|||
$args->target_url = $url;
|
||||
$args->target_browser = '';
|
||||
$args->target_summary = '';
|
||||
$args->target_content = null;
|
||||
|
||||
if (is_object($message))
|
||||
{
|
||||
|
|
@ -388,6 +389,7 @@ class ncenterliteController extends ncenterlite
|
|||
$args->target_type = $this->_TYPE_ADMIN_DOCUMENT;
|
||||
$args->target_url = getNotEncodedUrl('', 'mid', $module_info->mid, 'document_srl', $obj->document_srl);
|
||||
$args->target_summary = cut_str(strip_tags($obj->title), 50);
|
||||
$args->target_content = mb_substr(trim(utf8_normalize_spaces(strip_tags($obj->content))), 0, 200, 'UTF-8') ?: (strpos($obj->content, '<img') !== false ? lang('ncenterlite_content_image') : lang('ncenterlite_content_empty'));
|
||||
$args->regdate = date('YmdHis');
|
||||
$args->target_browser = $module_info->browser_title;
|
||||
$args->module_srl = $obj->module_srl;
|
||||
|
|
@ -446,6 +448,7 @@ class ncenterliteController extends ncenterlite
|
|||
$args->target_type = $this->_TYPE_COMMENT_ALL;
|
||||
$args->target_url = getNotEncodedUrl('', 'mid', $module_info->mid, 'document_srl', $document_srl, 'comment_srl', $comment_srl) . '#comment_' . $comment_srl;
|
||||
$args->target_summary = cut_str(trim(utf8_normalize_spaces(strip_tags($content))), 50) ?: (strpos($content, '<img') !== false ? lang('ncenterlite_content_image') : lang('ncenterlite_content_empty'));
|
||||
$args->target_content = null;
|
||||
$args->target_nick_name = $obj->nick_name;
|
||||
$args->target_email_address = $obj->email_address;
|
||||
$args->regdate = date('YmdHis');
|
||||
|
|
@ -482,6 +485,7 @@ class ncenterliteController extends ncenterlite
|
|||
$args->target_type = $this->_TYPE_ADMIN_COMMENT;
|
||||
$args->target_url = getNotEncodedUrl('', 'mid', $module_info->mid, 'document_srl', $document_srl, 'comment_srl', $comment_srl) . '#comment_' . $comment_srl;
|
||||
$args->target_summary = cut_str(trim(utf8_normalize_spaces(strip_tags($content))), 50) ?: (strpos($content, '<img') !== false ? lang('ncenterlite_content_image') : lang('ncenterlite_content_empty'));
|
||||
$args->target_content = null;
|
||||
$args->target_nick_name = $obj->nick_name;
|
||||
$args->target_email_address = $obj->email_address;
|
||||
$args->regdate = date('YmdHis');
|
||||
|
|
@ -560,6 +564,7 @@ class ncenterliteController extends ncenterlite
|
|||
$args->target_type = $this->_TYPE_COMMENT;
|
||||
$args->target_url = getNotEncodedUrl('', 'mid', $module_info->mid, 'document_srl', $document_srl, 'comment_srl', $comment_srl) . '#comment_' . $comment_srl;
|
||||
$args->target_summary = cut_str(trim(utf8_normalize_spaces(strip_tags($content))), 50) ?: (strpos($content, '<img') !== false ? lang('ncenterlite_content_image') : lang('ncenterlite_content_empty'));
|
||||
$args->target_content = null;
|
||||
$args->target_nick_name = $obj->nick_name;
|
||||
$args->target_email_address = $obj->email_address;
|
||||
$args->regdate = $regdate;
|
||||
|
|
@ -609,6 +614,7 @@ class ncenterliteController extends ncenterlite
|
|||
$args->target_type = $this->_TYPE_COMMENT;
|
||||
$args->target_url = getNotEncodedUrl('', 'mid', $module_info->mid, 'document_srl', $document_srl, 'comment_srl', $comment_srl) . '#comment_' . $comment_srl;
|
||||
$args->target_summary = cut_str(trim(utf8_normalize_spaces(strip_tags($content))), 50) ?: (strpos($content, '<img') !== false ? lang('ncenterlite_content_image') : lang('ncenterlite_content_empty'));
|
||||
$args->target_content = null;
|
||||
$args->target_nick_name = $obj->nick_name;
|
||||
$args->target_email_address = $obj->email_address;
|
||||
$args->regdate = $regdate;
|
||||
|
|
@ -658,6 +664,7 @@ class ncenterliteController extends ncenterlite
|
|||
$args->type = $this->_TYPE_MESSAGE;
|
||||
$args->target_type = $this->_TYPE_MESSAGE;
|
||||
$args->target_summary = $obj->title;
|
||||
$args->target_content = mb_substr(trim(utf8_normalize_spaces(strip_tags($obj->content))), 0, 200, 'UTF-8');
|
||||
$args->regdate = date('YmdHis');
|
||||
$args->notify = $this->_getNotifyId($args);
|
||||
$args->target_url = getNotEncodedUrl('', 'act', 'dispCommunicationMessages', 'message_srl', $obj->related_srl);
|
||||
|
|
@ -698,6 +705,7 @@ class ncenterliteController extends ncenterlite
|
|||
$args->type = $this->_TYPE_DOCUMENT;
|
||||
$args->target_type = $this->_TYPE_SCRAPPED;
|
||||
$args->target_summary = $obj->title;
|
||||
$args->target_content = null;
|
||||
$args->regdate = date('YmdHis');
|
||||
$args->notify = $this->_getNotifyId($args);
|
||||
$args->target_url = getNotEncodedUrl('', 'mid', $module_info->mid, 'document_srl', $obj->document_srl);
|
||||
|
|
@ -741,6 +749,7 @@ class ncenterliteController extends ncenterlite
|
|||
$args->type = $this->_TYPE_DOCUMENT;
|
||||
$args->target_type = $this->_TYPE_VOTED;
|
||||
$args->target_summary = $oDocument->get('title');
|
||||
$args->target_content = null;
|
||||
$args->regdate = date('YmdHis');
|
||||
$args->notify = $this->_getNotifyId($args);
|
||||
$args->target_url = getNotEncodedUrl('', 'mid', $module_info->mid, 'document_srl', $obj->document_srl);
|
||||
|
|
@ -821,6 +830,7 @@ class ncenterliteController extends ncenterlite
|
|||
$args->type = $this->_TYPE_COMMENT;
|
||||
$args->target_type = $this->_TYPE_VOTED;
|
||||
$args->target_summary = cut_str(trim(utf8_normalize_spaces(strip_tags($content))), 50);
|
||||
$args->target_content = null;
|
||||
$args->regdate = date('YmdHis');
|
||||
$args->module_srl = $obj->module_srl;
|
||||
$args->notify = $this->_getNotifyId($args);
|
||||
|
|
@ -958,7 +968,7 @@ class ncenterliteController extends ncenterlite
|
|||
{
|
||||
$comment_srl = Context::get('comment_srl');
|
||||
$logged_info = Context::get('logged_info');
|
||||
if($comment_srl && $logged_info)
|
||||
if($comment_srl && $logged_info && $logged_info->member_srl)
|
||||
{
|
||||
$args->target_srl = $comment_srl;
|
||||
$args->member_srl = $logged_info->member_srl;
|
||||
|
|
@ -975,7 +985,7 @@ class ncenterliteController extends ncenterlite
|
|||
$document_srl = Context::get('document_srl');
|
||||
$logged_info = Context::get('logged_info');
|
||||
|
||||
if($document_srl && $config->document_read == 'Y' && $logged_info->member_srl)
|
||||
if($document_srl && $config->document_read == 'Y' && $logged_info && $logged_info->member_srl)
|
||||
{
|
||||
$args->srl = $document_srl;
|
||||
$args->member_srl = $logged_info->member_srl;
|
||||
|
|
@ -1562,10 +1572,28 @@ class ncenterliteController extends ncenterlite
|
|||
$target_url = Rhymix\Framework\URL::getCurrentDomainUrl($target_url);
|
||||
}
|
||||
|
||||
if (!isset($args->extra_data) || !$args->extra_data)
|
||||
{
|
||||
$args->extra_data = [];
|
||||
$args->extra_data['sender'] = strval($args->target_nick_name);
|
||||
$args->extra_data['profile_image'] = '';
|
||||
if ($args->target_member_srl > 0)
|
||||
{
|
||||
$profile_image = MemberModel::getProfileImage($args->target_member_srl);
|
||||
if ($profile_image && $profile_image->src)
|
||||
{
|
||||
$args->extra_data['profile_image'] = Rhymix\Framework\URL::getCurrentDomainUrl($profile_image->src);
|
||||
}
|
||||
}
|
||||
$args->extra_data['type'] = strval($args->target_type);
|
||||
$args->extra_data['subject'] = strval($args->target_summary);
|
||||
$args->extra_data['content'] = isset($args->target_content) ? mb_substr($args->target_content, 0, 200, 'UTF-8') : '';
|
||||
}
|
||||
|
||||
$oPush = new \Rhymix\Framework\Push();
|
||||
$oPush->setSubject($content);
|
||||
$oPush->setContent(strval($args->extra_content));
|
||||
$oPush->setData($args->extra_data ?: []);
|
||||
$oPush->setData($args->extra_data);
|
||||
$oPush->setURL(strval($target_url));
|
||||
$oPush->addTo(intval($args->member_srl));
|
||||
$oPush->send();
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ $lang->point_recal_finished = 'Point recalculation is finished.';
|
|||
$lang->point_update_desc = 'Insert + in front of the number to increase the point or - to decrease, and update the point. If you don\'t insert + or -, the point will be set as the value you entered.';
|
||||
$lang->give_point = 'Give or Take Points';
|
||||
$lang->point_given_prefix = '';
|
||||
$lang->point_given_suffix = 'points';
|
||||
$lang->point_given_suffix = '$point';
|
||||
$lang->point_time_limit_prefix = 'until';
|
||||
$lang->point_time_limit_suffix = 'days after submission';
|
||||
$lang->search_target_list['nick_name'] = 'Nick Name';
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ $lang->point_recal_finished = '포인트 재계산이 완료되었습니다.';
|
|||
$lang->point_update_desc = '포인트를 증가시키려면 +를 감소시키려면 -를 숫자앞에 표기한 후 업데이트해 주세요. + 또는 - 표시가 없으면 입력한 값으로 설정됩니다.';
|
||||
$lang->give_point = '포인트 부여/차감';
|
||||
$lang->point_given_prefix = '';
|
||||
$lang->point_given_suffix = '포인트';
|
||||
$lang->point_given_suffix = '$point';
|
||||
$lang->point_time_limit_prefix = '작성 후';
|
||||
$lang->point_time_limit_suffix = '일까지';
|
||||
$lang->search_target_list['nick_name'] = '닉네임';
|
||||
|
|
|
|||
|
|
@ -410,7 +410,7 @@ class pointController extends point
|
|||
public function triggerBeforeDownloadFile($obj)
|
||||
{
|
||||
$logged_info = Context::get('logged_info');
|
||||
$logged_member_srl = $logged_info->member_srl;
|
||||
$logged_member_srl = $logged_info ? $logged_info->member_srl : 0;
|
||||
$author_member_srl = abs($obj->member_srl);
|
||||
$module_srl = $obj->module_srl;
|
||||
if ($logged_member_srl && $logged_member_srl == $author_member_srl)
|
||||
|
|
@ -443,7 +443,7 @@ class pointController extends point
|
|||
public function triggerDownloadFile($obj)
|
||||
{
|
||||
$logged_info = Context::get('logged_info');
|
||||
$logged_member_srl = $logged_info->member_srl;
|
||||
$logged_member_srl = $logged_info ? $logged_info->member_srl : 0;
|
||||
$author_member_srl = abs($obj->member_srl);
|
||||
$module_srl = $obj->module_srl;
|
||||
if ($logged_member_srl && $logged_member_srl == $author_member_srl)
|
||||
|
|
@ -481,7 +481,7 @@ class pointController extends point
|
|||
public function triggerUpdateReadedCount($obj)
|
||||
{
|
||||
$logged_info = Context::get('logged_info');
|
||||
$logged_member_srl = $logged_info->member_srl;
|
||||
$logged_member_srl = $logged_info ? $logged_info->member_srl : 0;
|
||||
$author_member_srl = abs($obj->get('member_srl'));
|
||||
$module_srl = $obj->get('module_srl');
|
||||
if ($logged_member_srl && $logged_member_srl == $author_member_srl)
|
||||
|
|
@ -587,7 +587,7 @@ class pointController extends point
|
|||
public function triggerUpdateVotedCount($obj)
|
||||
{
|
||||
$logged_info = Context::get('logged_info');
|
||||
$logged_member_srl = $logged_info->member_srl;
|
||||
$logged_member_srl = $logged_info ? $logged_info->member_srl : 0;
|
||||
$target_member_srl = abs($obj->member_srl);
|
||||
if ($logged_member_srl && $logged_member_srl == $target_member_srl)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -89,18 +89,18 @@
|
|||
<tr>
|
||||
<th class="nowr">{$lang->cmd_signup}</td>
|
||||
<td class="nowr">
|
||||
{$lang->point_given_prefix}
|
||||
{strtr($lang->point_given_prefix, ['$'.'point' => $config->point_name])}
|
||||
<input type="number" value="{$config->signup_point ?: '0'}" name="signup_point" id="signup_point" />
|
||||
{$lang->point_given_suffix}
|
||||
{strtr($lang->point_given_suffix, ['$'.'point' => $config->point_name])}
|
||||
</td>
|
||||
<td class="nowr"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="nowr">{$lang->cmd_login}</td>
|
||||
<td class="nowr">
|
||||
{$lang->point_given_prefix}
|
||||
{strtr($lang->point_given_prefix, ['$'.'point' => $config->point_name])}
|
||||
<input type="number" value="{$config->login_point ?: '0'}" name="login_point" id="login_point" />
|
||||
{$lang->point_given_suffix}
|
||||
{strtr($lang->point_given_suffix, ['$'.'point' => $config->point_name])}
|
||||
</td>
|
||||
<td class="nowr"></td>
|
||||
</tr>
|
||||
|
|
@ -108,9 +108,9 @@
|
|||
<tr>
|
||||
<th class="nowr">{lang('point_' . $action_type)}</td>
|
||||
<td class="nowr">
|
||||
{$lang->point_given_prefix}
|
||||
{strtr($lang->point_given_prefix, ['$'.'point' => $config->point_name])}
|
||||
<input type="number" value="{$config_array[$action_type] ?: '0'}" name="{$action_type}" id="{$action_type}" />
|
||||
{$lang->point_given_suffix}
|
||||
{strtr($lang->point_given_suffix, ['$'.'point' => $config->point_name])}
|
||||
<block cond="$action_config['except_notice']">
|
||||
<label class="x_inline" for="{$action_type}_except_notice" style="margin-left:10px">
|
||||
<input type="checkbox" value="Y" name="{$action_type}_except_notice" id="{$action_type}_except_notice" checked="checked"|cond="$config_array[$action_type . '_except_notice']" />
|
||||
|
|
|
|||
|
|
@ -30,9 +30,7 @@ class pollController extends poll
|
|||
$stop_date = date('YmdHis', $_SERVER['REQUEST_TIME']+60*60*24*30);
|
||||
}
|
||||
|
||||
$logged_info = Context::get('logged_info');
|
||||
$vars = Context::getRequestVars();
|
||||
|
||||
$args = new stdClass;
|
||||
$tmp_args = array();
|
||||
|
||||
|
|
@ -70,9 +68,9 @@ class pollController extends poll
|
|||
$tmp_args[$poll_index]->item = array();
|
||||
}
|
||||
|
||||
if($logged_info->is_admin != 'Y')
|
||||
if(!$this->user->isAdmin())
|
||||
{
|
||||
$val = htmlspecialchars($val, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
|
||||
$val = escape($val, false);
|
||||
}
|
||||
|
||||
switch($tmp_arr[0])
|
||||
|
|
@ -108,15 +106,14 @@ class pollController extends poll
|
|||
|
||||
// Configure the variables
|
||||
$poll_srl = getNextSequence();
|
||||
$member_srl = $logged_info->member_srl?$logged_info->member_srl:0;
|
||||
|
||||
$oDB = &DB::getInstance();
|
||||
$oDB = DB::getInstance();
|
||||
$oDB->begin();
|
||||
|
||||
// Register the poll
|
||||
$poll_args = new stdClass;
|
||||
$poll_args->poll_srl = $poll_srl;
|
||||
$poll_args->member_srl = $member_srl;
|
||||
$poll_args->member_srl = $this->user->member_srl;
|
||||
$poll_args->list_order = $poll_srl*-1;
|
||||
$poll_args->stop_date = $args->stop_date;
|
||||
$poll_args->poll_count = 0;
|
||||
|
|
@ -180,8 +177,10 @@ class pollController extends poll
|
|||
|
||||
if($poll_item_title=='') throw new Rhymix\Framework\Exception('msg_item_title_cannot_empty');
|
||||
|
||||
$logged_info = Context::get('logged_info');
|
||||
if(!$logged_info) throw new Rhymix\Framework\Exception('msg_cannot_add_item');
|
||||
if(!$this->user->member_srl)
|
||||
{
|
||||
throw new Rhymix\Framework\Exception('msg_cannot_add_item');
|
||||
}
|
||||
|
||||
if(!$poll_srl || !$poll_index_srl) throw new Rhymix\Framework\Exceptions\InvalidRequest;
|
||||
|
||||
|
|
@ -196,12 +195,12 @@ class pollController extends poll
|
|||
|
||||
if(!$this->isAbletoAddItem($type)) throw new Rhymix\Framework\Exception('msg_cannot_add_item');
|
||||
|
||||
if($logged_info->is_admin != 'Y')
|
||||
if(!$this->user->isAdmin())
|
||||
{
|
||||
$poll_item_title = htmlspecialchars($poll_item_title, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
|
||||
$poll_item_title = escape($poll_item_title, false);
|
||||
}
|
||||
|
||||
$oDB = &DB::getInstance();
|
||||
$oDB = DB::getInstance();
|
||||
$oDB->begin();
|
||||
|
||||
$item_args = new stdClass;
|
||||
|
|
@ -210,7 +209,7 @@ class pollController extends poll
|
|||
$item_args->title = $poll_item_title;
|
||||
$item_args->poll_count = 0;
|
||||
$item_args->upload_target_srl = 0;
|
||||
$item_args->add_user_srl = $logged_info->member_srl;
|
||||
$item_args->add_user_srl = $this->user->member_srl;
|
||||
$output = executeQuery('poll.insertPollItem', $item_args);
|
||||
if(!$output->toBool())
|
||||
{
|
||||
|
|
@ -226,8 +225,10 @@ class pollController extends poll
|
|||
$poll_index_srl = (int) Context::get('index_srl');
|
||||
$poll_item_srl = Context::get('item_srl');
|
||||
|
||||
$logged_info = Context::get('logged_info');
|
||||
if(!$logged_info) throw new Rhymix\Framework\Exception('msg_cannot_delete_item');
|
||||
if(!$this->user->member_srl)
|
||||
{
|
||||
throw new Rhymix\Framework\Exception('msg_cannot_delete_item');
|
||||
}
|
||||
|
||||
if(!$poll_srl || !$poll_index_srl || !$poll_item_srl) throw new Rhymix\Framework\Exceptions\InvalidRequest;
|
||||
|
||||
|
|
@ -248,8 +249,14 @@ class pollController extends poll
|
|||
if(!$output->data) throw new Rhymix\Framework\Exception('poll_no_poll_or_deleted_poll');
|
||||
$poll_member_srl = $output->data->member_srl;
|
||||
|
||||
if($add_user_srl!=$logged_info->member_srl && $poll_member_srl!=$logged_info->member_srl) throw new Rhymix\Framework\Exception('msg_cannot_delete_item');
|
||||
if($poll_count>0) throw new Rhymix\Framework\Exception('msg_cannot_delete_item_poll_exist');
|
||||
if($add_user_srl != $this->user->member_srl && $poll_member_srl != $this->user->member_srl)
|
||||
{
|
||||
throw new Rhymix\Framework\Exception('msg_cannot_delete_item');
|
||||
}
|
||||
if($poll_count > 0)
|
||||
{
|
||||
throw new Rhymix\Framework\Exception('msg_cannot_delete_item_poll_exist');
|
||||
}
|
||||
|
||||
$oDB = &DB::getInstance();
|
||||
$oDB->begin();
|
||||
|
|
@ -330,11 +337,7 @@ class pollController extends poll
|
|||
$log_args = new stdClass;
|
||||
$log_args->poll_srl = $poll_srl;
|
||||
$log_args->poll_item = $args->poll_item_srl;
|
||||
|
||||
$logged_info = Context::get('logged_info');
|
||||
$member_srl = $logged_info->member_srl?$logged_info->member_srl:0;
|
||||
|
||||
$log_args->member_srl = $member_srl;
|
||||
$log_args->member_srl = $this->user->member_srl;
|
||||
$log_args->ipaddress = \RX_CLIENT_IP;
|
||||
$output = executeQuery('poll.insertPollLog', $log_args);
|
||||
|
||||
|
|
|
|||
|
|
@ -239,19 +239,19 @@ class spamfilterController extends spamfilter
|
|||
return;
|
||||
}
|
||||
|
||||
$enable = false;
|
||||
$target_actions = [];
|
||||
foreach (['signup', 'login', 'recovery', 'document', 'comment'] as $action)
|
||||
{
|
||||
if ($config->captcha->target_actions[$action])
|
||||
{
|
||||
if (preg_match(self::$_captcha_actions[$action], $obj->act) || ($action === 'comment' && !$obj->act && Context::get('document_srl')))
|
||||
if (preg_match(self::$_captcha_actions[$action], $obj->act) || ($action === 'comment' && (!$obj->act || $obj->act === 'dispBoardContent') && Context::get('document_srl')))
|
||||
{
|
||||
$enable = true;
|
||||
$target_actions[$action] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($enable)
|
||||
if (count($target_actions))
|
||||
{
|
||||
include_once __DIR__ . '/spamfilter.lib.php';
|
||||
spamfilter_reCAPTCHA::init($config->captcha);
|
||||
|
|
@ -262,7 +262,10 @@ class spamfilterController extends spamfilter
|
|||
}
|
||||
else
|
||||
{
|
||||
Context::set('captcha', new spamfilter_reCAPTCHA());
|
||||
$captcha = new spamfilter_reCAPTCHA();
|
||||
$captcha->setTargetActions($target_actions);
|
||||
$captcha->addScripts();
|
||||
Context::set('captcha', $captcha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ class spamfilter_reCAPTCHA
|
|||
protected static $scripts_added = false;
|
||||
protected static $instances_inserted = 0;
|
||||
protected static $sequence = 1;
|
||||
protected $_target_actions = [];
|
||||
|
||||
public static function init($config)
|
||||
{
|
||||
|
|
@ -47,19 +48,29 @@ class spamfilter_reCAPTCHA
|
|||
$_SESSION['recaptcha_authenticated'] = true;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
public function addScripts()
|
||||
{
|
||||
if (!self::$scripts_added)
|
||||
{
|
||||
self::$scripts_added = true;
|
||||
Context::loadFile(array('./modules/spamfilter/tpl/js/recaptcha.js', 'body'));
|
||||
Context::addHtmlFooter('<script src="https://www.google.com/recaptcha/api.js?render=explicit&onload=reCaptchaCallback" async defer></script>');
|
||||
$html = '<div id="recaptcha-config" data-sitekey="%s" data-theme="%s" data-size="%s"></div>';
|
||||
$html = sprintf($html, escape(self::$config->site_key), self::$config->theme ?: 'light', self::$config->size ?: 'normal');
|
||||
$html = '<div id="recaptcha-config" data-sitekey="%s" data-theme="%s" data-size="%s" data-targets="%s"></div>';
|
||||
$html = sprintf($html, escape(self::$config->site_key), self::$config->theme ?: 'light', self::$config->size ?: 'normal', implode(',', array_keys($this->_target_actions)));
|
||||
Context::addHtmlFooter($html);
|
||||
}
|
||||
}
|
||||
|
||||
public function setTargetActions(array $target_actions)
|
||||
{
|
||||
$this->_target_actions = $target_actions;
|
||||
}
|
||||
|
||||
public function isTargetAction(string $action): bool
|
||||
{
|
||||
return isset($this->_target_actions[$action]);
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf('<div id="recaptcha-instance-%d" class="g-recaptcha"></div>', self::$instances_inserted++);
|
||||
|
|
|
|||
|
|
@ -3,15 +3,31 @@ function reCaptchaCallback() {
|
|||
var recaptcha_config = $("#recaptcha-config");
|
||||
var recaptcha_instances = $(".g-recaptcha");
|
||||
var recaptcha_instance_id = 1;
|
||||
var recaptcha_targets = String(recaptcha_config.data("targets")).split(",");
|
||||
|
||||
if (recaptcha_instances.size() === 0) {
|
||||
if (recaptcha_instances.length === 0) {
|
||||
var autoinsert_candidates = $("form").filter(function() {
|
||||
var actinput = $("input[name='act']", this);
|
||||
if (actinput.size() && actinput.val() && actinput.val().match(/^proc.+(Insert(Document|Comment|)|Login|FindAccount|ResendAuthMail)/i)) {
|
||||
return true;
|
||||
if (actinput.length && actinput.val()) {
|
||||
var act = String(actinput.val());
|
||||
if (act.match(/^procMemberInsert$/i) && recaptcha_targets.indexOf("signup") > -1) {
|
||||
return true;
|
||||
}
|
||||
if (act.match(/^procMemberLogin$/i) && recaptcha_targets.indexOf("login") > -1) {
|
||||
return true;
|
||||
}
|
||||
if (act.match(/^procMember(FindAccount|ResendAuthMail)$/i) && recaptcha_targets.indexOf("recovery") > -1) {
|
||||
return true;
|
||||
}
|
||||
if (act.match(/^proc[A-Z][a-zA-Z0-9_]+InsertDocument$/i) && recaptcha_targets.indexOf("document") > -1) {
|
||||
return true;
|
||||
}
|
||||
if (act.match(/^proc[A-Z][a-zA-Z0-9_]+InsertComment$/i) && recaptcha_targets.indexOf("comment") > -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
var procfilter = $(this).attr("onsubmit");
|
||||
if (procfilter && procfilter.match(/procFilter\b.+\binsert/i)) {
|
||||
if (procfilter && procfilter.match(/procFilter\b.+\binsert/i) && (recaptcha_targets.indexOf("document") > -1 || recaptcha_targets.indexOf("comment") > -1)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue