Warning: No message defined for "+b.name+""),e=/\$?\{(\d+)\}/g;return"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),d},formatAndAdd:function(a,b){var c=this.defaultMessage(a,b);this.errorList.push({message:c,element:a,method:b.method}),this.errorMap[a.name]=c,this.submitted[a.name]=c},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g,h=this.errorsFor(b),i=this.idOrName(b),j=a(b).attr("aria-describedby");h.length?(h.removeClass(this.settings.validClass).addClass(this.settings.errorClass),h.html(c)):(h=a("<"+this.settings.errorElement+">").attr("id",i+"-error").addClass(this.settings.errorClass).html(c||""),d=h,this.settings.wrapper&&(d=h.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement.call(this,d,a(b)):d.insertAfter(b),h.is("label")?h.attr("for",i):0===h.parents("label[for='"+this.escapeCssMeta(i)+"']").length&&(f=h.attr("id"),j?j.match(new RegExp("\\b"+this.escapeCssMeta(f)+"\\b"))||(j+=" "+f):j=f,a(b).attr("aria-describedby",j),e=this.groups[b.name],e&&(g=this,a.each(g.groups,function(b,c){c===e&&a("[name='"+g.escapeCssMeta(b)+"']",g.currentForm).attr("aria-describedby",h.attr("id"))})))),!c&&this.settings.success&&(h.text(""),"string"==typeof this.settings.success?h.addClass(this.settings.success):this.settings.success(h,b)),this.toShow=this.toShow.add(h)},errorsFor:function(b){var c=this.escapeCssMeta(this.idOrName(b)),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+this.escapeCssMeta(d).replace(/\s+/g,", #")),this.errors().filter(e)},escapeCssMeta:function(a){return a.replace(/([\\!"#$%&'()*+,.\/:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+this.escapeCssMeta(b)+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return!this.dependTypes[typeof a]||this.dependTypes[typeof a](a,b)},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(b){this.pending[b.name]||(this.pendingRequest++,a(b).addClass(this.settings.pendingClass),this.pending[b.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],a(b).removeClass(this.settings.pendingClass),c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.submitButton&&a("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b,c){return c="string"==typeof c&&c||"remote",a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,{method:c})})},destroy:function(){this.resetForm(),a(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur")}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},normalizeAttributeRule:function(a,b,c,d){/min|max|step/.test(c)&&(null===b||/number|range|text/.test(b))&&(d=Number(d),isNaN(d)&&(d=void 0)),d||0===d?a[c]=d:b===c&&"range"!==b&&(a[c]=!0)},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),this.normalizeAttributeRule(e,g,c,d);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),this.normalizeAttributeRule(e,g,c,d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0===e.param||e.param:(a.data(c.form,"validator").resetElements(a(c)),delete b[d])}}),a.each(b,function(d,e){b[d]=a.isFunction(e)&&"normalizer"!==d?e(c):e}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var c;b[this]&&(a.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(c=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(c[0]),Number(c[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:b.length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[\/?#]\S*)?$/i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a).toString())},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e<=d},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||a<=c},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},step:function(b,c,d){var e,f=a(c).attr("type"),g="Step attribute on input type "+f+" is not supported.",h=["text","number","range"],i=new RegExp("\\b"+f+"\\b"),j=f&&!i.test(h.join()),k=function(a){var b=(""+a).match(/(?:\.(\d+))?$/);return b&&b[1]?b[1].length:0},l=function(a){return Math.round(a*Math.pow(10,e))},m=!0;if(j)throw new Error(g);return e=k(d),(k(b)>e||l(b)%l(d)!==0)&&(m=!1),this.optional(c)||m},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-equalTo-blur").length&&e.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d,e){if(this.optional(c))return"dependency-mismatch";e="string"==typeof e&&e||"remote";var f,g,h,i=this.previousValue(c,e);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),i.originalMessage=i.originalMessage||this.settings.messages[c.name][e],this.settings.messages[c.name][e]=i.message,d="string"==typeof d&&{url:d}||d,h=a.param(a.extend({data:b},d.data)),i.old===h?i.valid:(i.old=h,f=this,this.startRequest(c),g={},g[c.name]=b,a.ajax(a.extend(!0,{mode:"abort",port:"validate"+c.name,dataType:"json",data:g,context:f.currentForm,success:function(a){var d,g,h,j=a===!0||"true"===a;f.settings.messages[c.name][e]=i.originalMessage,j?(h=f.formSubmitted,f.resetInternals(),f.toHide=f.errorsFor(c),f.formSubmitted=h,f.successList.push(c),f.invalid[c.name]=!1,f.showErrors()):(d={},g=a||f.defaultMessage(c,{method:e,parameters:b}),d[c.name]=i.message=g,f.invalid[c.name]=!0,f.showErrors(d)),i.valid=j,f.stopRequest(c,j)}},d)),"pending")}}});var b,c={};return a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,d){var e=a.port;"abort"===a.mode&&(c[e]&&c[e].abort(),c[e]=d)}):(b=a.ajax,a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return"abort"===e?(c[f]&&c[f].abort(),c[f]=b.apply(this,arguments),c[f]):b.apply(this,arguments)}),a});
\ No newline at end of file
diff --git a/f_func/func.php b/f_func/func.php
index 9906dd79..0dc98f67 100644
--- a/f_func/func.php
+++ b/f_func/func.php
@@ -107,3 +107,28 @@ function delExpiredInDir($dir, $t) {
}
+function returnJson($value, $noCache = true, $pretty = false, $die = true){
+ header('Content-Type: application/json');
+
+ if($noCache){
+ header('Expires: Sun, 01 Jan 2014 00:00:00 GMT');
+ header('Cache-Control: no-store, no-cache, must-revalidate');
+ header('Cache-Control: post-check=0, pre-check=0', FALSE);
+ header('Pragma: no-cache');
+ }
+
+ if($pretty){
+ $flag = JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT;
+ }
+ else{
+ $flag = JSON_UNESCAPED_UNICODE;
+ }
+ echo json_encode($value, $flag);
+ if($die){
+ die();
+ }
+}
+
+function hashPassword($salt, $password){
+ return hash('sha512', $salt.$password.$salt);
+}
\ No newline at end of file
diff --git a/tmp_kakao/_common.php b/tmp_kakao/_common.php
new file mode 100644
index 00000000..c95ed0e0
--- /dev/null
+++ b/tmp_kakao/_common.php
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+ 카카오 로그인하기
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tmp_kakao/j_check_dup.php b/tmp_kakao/j_check_dup.php
new file mode 100644
index 00000000..67a26fdf
--- /dev/null
+++ b/tmp_kakao/j_check_dup.php
@@ -0,0 +1,24 @@
+queryFirstField('SELECT REG FROM `SYSTEM` WHERE `NO` = 1');
+if($canJoin != 'Y'){
+ returnJson([
+ 'result'=>false,
+ 'reason'=>'현재는 가입이 금지되어있습니다!'
+ ]);
+}
+
+$nowDate = _Time::DatetimeNow();
+
+$access_token = util::array_get($_SESSION['access_token']);
+$expires = util::array_get($_SESSION['expires']);
+$refresh_token = util::array_get($_SESSION['refresh_token']);
+$refresh_token_expires = util::array_get($_SESSION['refresh_token_expires']);
+if(!$access_token){
+ returnJson([
+ 'result'=>false,
+ 'reason'=>'로그인 토큰 에러. 다시 카카오로그인을 수행해주세요.'
+ ]);
+}
+if($refresh_token_expires < $nowDate){
+ returnJson([
+ 'result'=>false,
+ 'reason'=>'로그인 토큰 만료.'.$refresh_token_expires.' 다시 카카오로그인을 수행해주세요.'
+ ]);
+}
+$secret_agree =util::array_get($_POST['secret_agree']);
+$username = util::array_get($_POST['username']);
+$password = util::array_get($_POST['password']);
+$nickname = util::array_get($_POST['nickname']);
+
+if(!$username || !$password || !$nickname){
+ returnJson([
+ 'result'=>false,
+ 'reason'=>'입력값이 설정되지 않았습니다.'
+ ]);
+}
+
+if(strlen($password)!=128){
+ returnJson([
+ 'result'=>false,
+ 'reason'=>'올바르지 않은 비밀번호 해시 포맷입니다.'
+ ]);
+}
+
+if(!$secret_agree){
+ returnJson([
+ 'result'=>false,
+ 'reason'=>'약관에 동의해야 가입하실 수 있습니다.'
+ ]);
+}
+
+$usernameChk = checkUsernameDup($username);
+if($usernameChk !== true){
+ returnJson([
+ 'result'=>false,
+ 'reason'=>$usernameChk
+ ]);
+}
+
+$nicknameChk = checkNicknameDup($nickname);
+if($nicknameChk !== true){
+ returnJson([
+ 'result'=>false,
+ 'reason'=>$nicknameChk
+ ]);
+}
+
+$userSalt = bin2hex(random_bytes(8));
+$finalPassword = hashPassword($userSalt, $password);
+
+//클라이언트 단에서 보내준 데이터 준비가 끝났다.
+$restAPI = new Kakao_REST_API_Helper($access_token);
+
+if($expires < $nowDate){
+ $result = $restAPI->refresh_access_token($refresh_token);
+ if(!isset($refresh_token)){
+ returnJson([
+ 'result'=>false,
+ 'reason'=>'카카오 로그인 과정 중 추가 갱신 절차를 실패했습니다'
+ ]);
+ }
+
+ $access_token = $result['access_token'];
+ $expires = _Time::DatetimeFromNowSecond($nowDate, $result['expires_in']);
+ if(isset($result['refresh_token'])){
+ $refresh_token = util::array_get($result['refresh_token']);
+ $refresh_token_expires = _Time::DatetimeFromNowSecond($nowDate, $result['refresh_token_expires_in']);
+ }
+}
+
+
+$signupResult = $restAPI->signup();
+$kakaoID = util::array_get($signupResult['id']);
+
+if(!$kakaoID && util::array_get($signupResult['msg'])!='already registered'){
+ returnJson([
+ 'result'=>false,
+ 'reason'=>'카카오 로그인 과정 중 앱 연결 절차를 실패했습니다'.json_encode($signupResult)
+ ]);
+}
+
+$me = $restAPI->meWithEmail();
+if(!util::array_get($me['kaccount_email_verified'],false)){
+ $restAPI->unlink();
+ returnJson([
+ 'result'=>false,
+ 'reason'=>'카카오 계정 이메일이 아직 인증되지 않았습니다'
+ ]);
+}
+
+$email = $me['kaccount_email'];
+$emailChk = checkEmailDup($email);
+if($emailChk !== true){
+ $restAPI->unlink();
+ returnJson([
+ 'result'=>false,
+ 'reason'=>$emailChk
+ ]);
+}
+
+//모든 절차 종료. 등록.
+
+
+getRootDB()->insert('auth_kakao',[
+ 'id'=>$kakaoID,
+ 'access_token'=>$access_token,
+ 'refresh_token'=>$refresh_token,
+ 'expires'=>$expires,
+ 'refresh_token_expires'=>$refresh_token_expires,
+ 'datetime'=>$nowDate,
+ 'email'=>$email
+]);
+
+getRootDB()->insert('member',[
+ 'oauth_id' => $kakaoID,
+ 'oauth_type' => 'KAKAO',
+ 'id' => $username,
+ 'email' => $email,
+ 'pw' => $finalPassword,
+ 'salt' => $userSalt,
+ 'name'=>$nickname,
+ 'reg_date'=>$nowDate
+]);
+
+returnJson([
+ 'result'=>true,
+ 'reason'=>'success'
+]);
+
diff --git a/tmp_kakao/join.css b/tmp_kakao/join.css
new file mode 100644
index 00000000..c6a9338e
--- /dev/null
+++ b/tmp_kakao/join.css
@@ -0,0 +1,75 @@
+/*
+/* Created by Filipe Pina
+ * Specific styles of signin, register, component
+ */
+/*
+ * General styles
+ */
+
+ body, html{
+ height: 100%;
+ background-repeat: no-repeat;
+}
+
+.main{
+ margin-top: 70px;
+}
+
+h1.title {
+ font-size: 50px;
+ font-family: 'Passion One', cursive;
+ font-weight: 400;
+}
+
+hr{
+ width: 10%;
+ /*color: #fff;*/
+}
+
+.form-group{
+ margin-bottom: 15px;
+}
+
+label{
+ margin-bottom: 15px;
+}
+
+input,
+input::-webkit-input-placeholder {
+ font-size: 11px;
+ padding-top: 3px;
+}
+
+.main-login{
+ /*background-color: #fff;*/
+ /* shadows and rounded borders */
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ border-radius: 2px;
+ -moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
+ -webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
+ box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
+
+}
+
+.main-center{
+ margin-top: 30px;
+ margin: 0 auto;
+ max-width: 330px;
+ padding: 40px 40px;
+
+}
+
+.login-button{
+ margin-top: 5px;
+}
+
+.login-register{
+ font-size: 11px;
+ text-align: center;
+}
+
+
+.terms{
+ max-height: 200px; overflow: auto;
+}
\ No newline at end of file
diff --git a/tmp_kakao/join.js b/tmp_kakao/join.js
new file mode 100644
index 00000000..ee88c181
--- /dev/null
+++ b/tmp_kakao/join.js
@@ -0,0 +1,122 @@
+$(document).ready( function () {
+ $( "#main_form" ).validate( {
+ rules: {
+ username: {
+ required: true,
+ minlength: 4,
+ maxlength: 64,
+ remote: {
+ url: "j_check_dup.php",
+ type: "post",
+ data: {
+ type:'username',
+ 'value':function(){
+ return $('#username').val();
+ }
+ },
+ dataType: 'json'
+ }
+ },
+ password: {
+ required: true,
+ minlength: 6
+ },
+ confirm_password: {
+ required: true,
+ minlength: 6,
+ equalTo: "#password"
+ },
+ nickname:{
+ required: true,
+ maxlength: 6,
+ remote: {
+ url: "j_check_dup.php",
+ type: "post",
+ data: {
+ type:'nickname',
+ 'value':function(){
+ return $('#nickname').val();
+ }
+ },
+ dataType: 'json'
+ }
+ },
+ secret_agree: "required"
+ },
+ messages: {
+ username: {
+ required: "유저명을 입력해주세요",
+ minlength: "{0}글자 이상 입력하셔야 합니다",
+ maxlength: '{0}자를 넘을 수 없습니다'
+ },
+ password: {
+ required: "비밀번호를 입력해주세요",
+ minlength: "비밀번호는 적어도 {0}글자 이상이어야 합니다"
+ },
+ confirm_password: {
+ required: "비밀번호를 입력해주세요",
+ minlength: "비밀번호는 적어도 {0}글자 이상이어야 합니다",
+ equalTo: "비밀번호가 일치하지 않습니다"
+ },
+ nickname: {
+ required: "닉네임을 입력해주세요",
+ maxlength: '닉네임은 {0}자를 넘을 수 없습니다'
+ },
+ secret_agree: "동의해야만 가입하실 수 있습니다."
+ },
+ errorElement: "div",
+ errorPlacement: function ( error, element ) {
+ // Add the `help-block` class to the error element
+ error.addClass( "invalid-feedback" );
+
+ if ( element.prop( "type" ) === "checkbox" ) {
+ error.insertAfter( element.parent( "label" ) );
+ } else {
+ error.insertAfter( element );
+ }
+ },
+ highlight: function ( element, errorClass, validClass ) {
+ $( element ).addClass( "is-invalid" ).removeClass( "is-valid" );
+ },
+ unhighlight: function (element, errorClass, validClass) {
+ $( element ).addClass( "is-valid" ).removeClass( "is-invalid" );
+ }
+ } );
+
+ $( "#main_form" ).submit(function(){
+ var raw_password = $('#password').val();
+ var salt = $('#global_salt').val();
+ var hash_pw = sha512(salt + raw_password + salt);
+
+ $.post({
+ url:'j_join_process.php',
+ dataType:'json',
+ data:{
+ 'secret_agree':$('#secret_agree').val(),
+ 'username':$('#username').val(),
+ 'password':hash_pw,
+ 'nickname':$('#nickname').val(),
+
+ }
+ }).then(function(obj){
+ if(!obj.result){
+ alert(obj.reason);
+ }
+ else{
+ alert('정상적으로 가입되었습니다.');
+ }
+
+ window.location.href = '../';
+
+ });
+ console.log('Yes!');
+ return false;
+ });
+} );
+
+
+$(function($){
+ $.get('terms.html').then(function(txt){
+ $('#terms').html(txt);
+ });
+});
\ No newline at end of file
diff --git a/tmp_kakao/join.php b/tmp_kakao/join.php
new file mode 100644
index 00000000..f317665e
--- /dev/null
+++ b/tmp_kakao/join.php
@@ -0,0 +1,120 @@
+queryFirstField('SELECT REG FROM `SYSTEM` WHERE `NO` = 1');
+if($canJoin != 'Y'){
+ die('현재는 가입이 금지되어있습니다!');
+}
+
+
+
+//session_write_close();
+?>
+
+
+
+
+
+ 회원가입
+
+
+
+
+
+
+
+
+
+
+ =_Time::DatetimeNow()?>
+ =util::array_get($_SESSION['access_token'])?>
+=util::array_get($_SESSION['expires'])?>
+=util::array_get($_SESSION['refresh_token'])?>
+=util::array_get($_SESSION['refresh_token_expires'])?>
+ =$_SESSION['tmpx']?>
+
+
diff --git a/tmp_kakao/kakao.php b/tmp_kakao/kakao.php
new file mode 100644
index 00000000..f3c4b864
--- /dev/null
+++ b/tmp_kakao/kakao.php
@@ -0,0 +1,464 @@
+access_token = $access_token;
+ }
+
+ self::$admin_apis = array(
+ User_Management_Path::$USER_IDS,
+ Push_Notification_Path::$REGISTER,
+ Push_Notification_Path::$TOKENS,
+ Push_Notification_Path::$DEREGISTER,
+ Push_Notification_Path::$SEND
+ );
+ }
+
+ public function request($api_path, $params = '', $http_method = GET)
+ {
+ if ($api_path != Story_Path::$UPLOAD_MULTI && is_array($params)) { // except for uploading
+ $params = http_build_query($params);
+ }
+
+ $requestUrl = ($api_path == '/oauth/token' ? self::$OAUTH_HOST : self::$API_HOST) . $api_path;
+
+ if (($http_method == GET || $http_method == DELETE) && !empty($params)) {
+ $requestUrl .= '?'.$params;
+ }
+
+ $opts = array(
+ CURLOPT_URL => $requestUrl,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_SSL_VERIFYPEER => false,
+ CURLOPT_SSLVERSION => 1,
+ );
+
+ if ($api_path != '/oauth/token')
+ {
+ if (in_array($api_path, self::$admin_apis)) {
+
+ if (!$this->admin_key) {
+ throw new Exception('admin key should not be null or empty.');
+ }
+ $headers = array('Authorization: KakaoAK ' . $this->admin_key);
+
+ } else {
+
+ if (!$this->access_token) {
+ throw new Exception('access token should not be null or empty.');
+ }
+ $headers = array('Authorization: Bearer ' . $this->access_token);
+ }
+
+ $opts[CURLOPT_HEADER] = false;
+ $opts[CURLOPT_HTTPHEADER] = $headers;
+ }
+
+ if ($http_method == POST) {
+ $opts[CURLOPT_POST] = true;
+ if ($params) {
+ $opts[CURLOPT_POSTFIELDS] = $params;
+ }
+ } else if ($http_method == DELETE) {
+ $opts[CURLOPT_CUSTOMREQUEST] = DELETE;
+ }
+
+ $curl_session = curl_init();
+ curl_setopt_array($curl_session, $opts);
+ $return_data = curl_exec($curl_session);
+
+ if (curl_errno($curl_session)) {
+ throw new Exception(curl_error($curl_session));
+ } else {
+ // 디버깅 시에 주석을 풀고 응답 내용 확인할 때
+ //print_r(curl_getinfo($curl_session));
+ curl_close($curl_session);
+ return json_decode($return_data, true);
+ }
+ }
+
+ public function set_access_token($access_token) {
+ $this->access_token = $access_token;
+ }
+
+ public function set_admin_key($admin_key) {
+ $this->admin_key = $admin_key;
+ }
+
+ ///////////////////////////////////////////////////////////////
+ // User Management
+ ///////////////////////////////////////////////////////////////
+
+ private function _create_or_refresh_access_token($params) {
+ return $this->request(User_Management_Path::$TOKEN, $params, POST);
+ }
+
+ public function create_access_token($authorization_code){
+ $this->AUTHORIZATION_CODE = $authorization_code;
+ $params = [
+ 'grant_type'=>'authorization_code',
+ 'client_id'=>$this->REST_KEY,
+ 'redirect_uri'=>$this->REDIRECT_URI,
+ 'code'=>$this->AUTHORIZATION_CODE
+ ];
+ $result = $this->_create_or_refresh_access_token($params);
+
+ return $result;
+ }
+
+ public function refresh_access_token($refresh_token){
+ $params = [
+ 'grant_type'=>'refresh_token',
+ 'client_id'=>$this->REST_KEY,
+ 'redirect_uri'=>$this->REDIRECT_URI,
+ 'code'=>$refresh_token
+ ];
+ $result = $this->_create_or_refresh_access_token($params);
+
+ return $result;
+ }
+
+ public function signup() {
+ return $this->request(User_Management_Path::$SIGNUP);
+ }
+
+ public function unlink() {
+ return $this->request(User_Management_Path::$UNLINK);
+ }
+
+ public function logout() {
+ return $this->request(User_Management_Path::$UNLINK);
+ }
+
+ public function me() {
+ return $this->request(User_Management_Path::$ME);
+ }
+
+ public function meWithEmail(){
+ $params = [
+ 'propertyKeys'=>'["id","kaacount_email","kaccount_email_verified"]'
+ ];
+ return $this->request(User_Management_Path::$ME);
+ }
+
+ public function update_profile($params) {
+ return $this->request(User_Management_Path::$UPDATE_PROFILE, $params, POST);
+ }
+
+ public function user_ids() {
+ return $this->request(User_Management_Path::$USER_IDS);
+ }
+
+ ///////////////////////////////////////////////////////////////
+ // Kakao Story
+ ///////////////////////////////////////////////////////////////
+
+ public function isstoryuser() {
+ return $this->request(Story_Path::$ISSTORYUSER);
+ }
+
+ public function story_profile() {
+ return $this->request(Story_Path::$PROFILE);
+ }
+
+ ///////////////////////////////////////////////////////////////
+ // Kakao Talk
+ ///////////////////////////////////////////////////////////////
+
+ public function talk_profile() {
+ return $this->request(Talk_Path::$TALK_PROFILE);
+ }
+
+
+ ///////////////////////////////////////////////////////////////
+ // API Test
+ ///////////////////////////////////////////////////////////////
+
+
+ private $REST_KEY = KakaoKey::REST_KEY; // 디벨로퍼스의 앱 설정에서 확인할 수 있습니다.
+ private $REDIRECT_URI = KakaoKey::REDIRECT_URI; // 설정에 등록한 사이트 도메인 + redirect uri
+ private $AUTHORIZATION_CODE = ''; // 동의를 한 후 발급되는 code
+ private $REFRESH_TOKEN = '';
+
+ /*
+ * 유저 관리 API 테스트
+ */
+ public function test_user_management_api()
+ {
+
+/*
+ // authorization code로 access token 얻기
+ $params = array();
+ $params['grant_type'] = 'authorization_code';
+ $params['client_id'] = $this->REST_KEY;
+ $params['redirect_uri'] = $this->REDIRECT_URI;
+ $params['code'] = $this->AUTHORIZATION_CODE;
+ $this->create_or_refresh_access_token($params);
+*/
+
+/*
+ // refresh token으로 access token 얻기
+ $params = array();
+ $params['grant_type'] = 'refresh_token';
+ $params['client_id'] = $this->REST_KEY;
+ $params['refresh_token'] = $this->REFRESH_TOKEN;
+ echo $this->create_or_refresh_access_token($params);
+*/
+
+/*
+ // 앱 사용자 정보 요청 (signup 후에 사용 가능)
+ echo $this->me();
+*/
+
+/*
+ // 앱 연결
+ echo $this->signup();
+*/
+
+/*
+ // 앱 탈퇴 (unlink를 하면 access/refresh token이 삭제됩니다.)
+ //echo $this->unlink();
+*/
+
+/*
+ // 앱 로그아웃 (로그아웃을 하면 access/refresh token이 삭제됩니다.)
+ echo $this->logout();
+*/
+
+/*
+ // 앱 사용자 정보 업데이트
+ $params = array();
+ $params['properties'] = '{"nickname":"test11"}';
+ echo $this->updateProfile($params);
+ echo $this->me();
+*/
+
+/*
+ // 앱 사용자 리스트 요청 (파라미터)
+ // 테스트하시려면 admin key 지정해야 합니다.
+ echo $this->user_ids();
+*/
+
+ }
+
+ /*
+ * 카카오스토리 API 테스트
+ */
+ public function test_story_api()
+ {
+
+/*
+ // 스토리 프로파일 요청
+ echo $this->story_profile();
+*/
+
+/*
+ // 스토리 유저인지 확인
+ //echo $this->isstoryuser();
+*/
+
+/*
+ $story_common_params = array();
+
+ // 글 포스팅이면 필수
+ $story_common_params['content'] = '더 나은 세상을 꿈꾸고 그것을 현실로 만드는 이를 위하여 카카오에서 앱 개발 플랫폼 서비스를 시작합니다.';
+
+ // 스토리 포스팅 공통 파라미터. 필요한 것만 선택하여 사용.
+ //$story_common_params['permission'] = 'A'; // A : 전체공개, F: 친구에게만 공개, M: 나만보기
+ //$story_common_params['enable_share'] = 'true'; // 공개 기능 허용 여부
+ //$story_common_params['android_exec_param'] = 'cafe_id=1234'; // 앱 이동시 추가 파라미터
+ //$story_common_params['ios_exec_param'] = 'cafe_id=1234';
+ //$story_common_params['android_market_param'] = 'cafe_id=1234';
+ //$story_common_params['ios_market_param'] = 'cafe_id=1234';
+
+ //$res = $helper->post_note($story_common_params);
+ //echo $res;
+ //$obj = json_decode($res);
+ //this->delete_mystory($obj->id); // 포스팅된 스토리 삭제.
+*/
+
+/*
+ // 스토리 포스팅 공통 파라미터. 필요한 것만 선택하여 사용.
+ $story_common_params = array();
+ //$story_common_params['content'] = '더 나은 세상을 꿈꾸고 그것을 현실로 만드는 이를 위하여 카카오에서 앱 개발 플랫폼 서비스를 시작합니다.';
+ //$story_common_params['permission'] = 'A'; // A : 전체공개, F: 친구에게만 공개, M: 나만보기
+ //$story_common_params['enable_share'] = 'true'; // 공개 기능 허용 여부
+ //$story_common_params['android_exec_param'] = 'cafe_id=1234'; // 앱 이동시 추가 파라미터
+ //$story_common_params['ios_exec_param'] = 'cafe_id=1234';
+ //$story_common_params['android_market_param'] = 'cafe_id=1234';
+ //$story_common_params['ios_market_param'] = 'cafe_id=1234';
+
+ // 링크 포스팅
+ $test_site_url = 'https://developers.kakao.com';
+ $res = $this->post_link($test_site_url, $story_common_params);
+ echo $res;
+ $obj = json_decode($res);
+ //$this->delete_mystory($obj->id); // 포스팅된 테스트 스토리 삭제.
+*/
+
+/*
+ // 스토리 포스팅 공통 파라미터. 필요한 것만 선택하여 사용.
+ $story_common_params = array();
+ $story_common_params['content'] = '더 나은 세상을 꿈꾸고 그것을 현실로 만드는 이를 위하여 카카오에서 앱 개발 플랫폼 서비스를 시작합니다.';
+ //$story_common_params['permission'] = 'A'; // A : 전체공개, F: 친구에게만 공개, M: 나만보기
+ //$story_common_params['enable_share'] = 'true'; // 공개 기능 허용 여부
+ //$story_common_params['android_exec_param'] = 'cafe_id=1234'; // 앱 이동시 추가 파라미터
+ //$story_common_params['ios_exec_param'] = 'cafe_id=1234';
+ //$story_common_params['android_market_param'] = 'cafe_id=1234';
+ //$story_common_params['ios_market_param'] = 'cafe_id=1234';
+
+ // 사진 포스팅 (최대 10개까지 가능)
+ $file_params = array(
+ 'file[0]'=>"@/Users/tom/sample1.png",
+ 'file[1]'=>"@/Users/tom/sample2.png"
+ );
+
+ // PHP 5 >= 5.5.0
+ $file_params = array(
+ 'file[0]'=>new CurlFile('/Users/tom/sample1.png','image/png','sample1'),
+ 'file[1]'=>new CurlFile('/Users/tom/sample2.png','image/png','sample2')
+ );
+
+ $res = $this->post_photo($file_params, $story_common_params);
+ echo $res;
+ $obj = json_decode($res);
+ $this->delete_mystory($obj->id); // 포스팅된 테스트 스토리 삭제.
+*/
+
+/*
+ $test_mystory_id = '_cDLHO.GBNzGysmIZ9';
+
+ // 복수개의 내스토리 정보 요청
+ echo $this->get_mystories();
+
+ // 복수개의 내스토리 정보 요청 (특정 아이디 부터)
+ echo $this->get_mystories($test_mystory_id);
+
+ // 내스토리 정보 요청
+ echo $this->get_mystory($test_mystory_id); // 포스팅된 테스트 스토리 삭제.
+*/
+
+ }
+
+ /*
+ * 카카오톡 API 테스트
+ */
+ public function test_talk_api()
+ {
+ // 카카오톡 프로필 요청
+ //echo $this->talk_profile();
+ }
+
+ /*
+ * 푸시 알림 API 테스트
+ */
+ public function test_push_notification_api()
+ {
+ // 파라미터 설명
+ // @param uuid 사용자의 고유 ID. 1~(2^63 -1), 숫자만 가능
+ // @param push_type gcm or apns
+ // @param push_token apns(64자) or GCM으로부터 발급받은 push token
+ // @param uuids 기기의 고유한 ID 리스트 (최대 100개까지 가능)
+
+ // 푸시 알림 관련 API를 테스트하시려면 admin key 지정해야 합니다.
+
+/*
+ // 푸시 등록
+ $params = array(
+ "uuid" => "10000",
+ "push_type" => "gcm",
+ "push_token" => "xxxxxxxxxx",
+ "device_id" => ""
+ );
+ $this->register_push($params);
+*/
+
+/*
+ // 푸시 토큰 조회
+ $param = array("uuid" => "10000");
+ $this->get_push_tokens($param);
+*/
+
+/*
+ // 푸시 해제
+ $params = array(
+ "uuid" => "10000",
+ "push_type" => "gcm",
+ "push_token" => "xxxxxxxxxx"
+ );
+ $this->deregister_push($params);
+*/
+
+/*
+ // 푸시 보내기
+ $param = array("uuids" => "[\"1\",\"2\", \"3\"]");
+ $this->sendPush($param);
+*/
+ }
+}
\ No newline at end of file
diff --git a/tmp_kakao/kakao_btn.png b/tmp_kakao/kakao_btn.png
new file mode 100644
index 00000000..a29c7a7f
Binary files /dev/null and b/tmp_kakao/kakao_btn.png differ
diff --git a/tmp_kakao/lib.join.php b/tmp_kakao/lib.join.php
new file mode 100644
index 00000000..33bc6ca7
--- /dev/null
+++ b/tmp_kakao/lib.join.php
@@ -0,0 +1,56 @@
+ 64){
+ return '적절하지 않은 길이입니다.';
+ }
+
+ $cnt = getRootDB()->queryFirstField('SELECT count(no) FROM member WHERE `id` = %s LIMIT 1', $username);
+ if($cnt != 0){
+ return '이미 사용중인 계정명입니다';
+ }
+ return true;
+}
+
+function checkNicknameDup($nickname){
+ if(!$nickname){
+ return '닉네임을 입력해주세요';
+ }
+
+ $length = strlen($nickname);
+ if($length < 1 || $length > 6){
+ return '적절하지 않은 길이입니다.';
+ }
+
+ $cnt = getRootDB()->queryFirstField('SELECT count(no) FROM member WHERE `name` = %s LIMIT 1', $nickname);
+ if($cnt != 0){
+ return '이미 사용중인 닉네임입니다';
+ }
+ return true;
+}
+
+
+function checkEmailDup($email){
+ if(!$email){
+ return '이메일을 입력해주세요';
+ }
+
+ $length = strlen($email);
+ if($length < 1 || $length > 64){
+ return '적절하지 않은 길이입니다.';
+ }
+
+ $cnt = getRootDB()->queryFirstField('SELECT count(no) FROM member WHERE `email` = %s LIMIT 1', $email);
+ if($cnt != 0){
+ return '이미 사용중인 이메일입니다';
+ }
+ return true;
+}
\ No newline at end of file
diff --git a/tmp_kakao/oauth.php b/tmp_kakao/oauth.php
new file mode 100644
index 00000000..3f6c54c8
--- /dev/null
+++ b/tmp_kakao/oauth.php
@@ -0,0 +1,64 @@
+create_access_token($auth_code);
+
+//항상 scope = account_email profile임
+//항상 token_type = bearer임
+
+//토큰을 받아옴.
+
+
+
+if(util::array_get($result['expires_in'], -1) > 0){
+ session_start();
+ $restAPI->set_access_token($result['access_token']);
+ $now = _Time::DatetimeNow();
+ $_SESSION['access_token'] = $result['access_token'];
+ $_SESSION['expires'] = _Time::DatetimeFromSecond($now, $result['expires_in']);
+ $_SESSION['refresh_token'] = util::array_get($result['refresh_token']);
+ $_SESSION['refresh_token_expires'] = _Time::DatetimeFromSecond($now, $result['refresh_token_expires_in']);
+}
+else{
+ die('알 수 없는 에러:'.$me['msg']);
+}
+
+$_SESSION['tmpx'] = json_encode($result,JSON_UNESCAPED_UNICODE);
+
+//echo "
\n";
+$me = $restAPI->meWithEmail();
+
+var_dump($me);
+
+$me['code'] = util::array_get($me['code'], 0);
+if($me['code']< 0){
+ switch($me['msg']){
+ case 'NotRegisteredUserException':
+ header('Location:join.php', true, 303);
+ die();
+ default:
+ die('알 수 없는 에러:'.$me['msg']);
+ }
+}
+
+
+
+//이메일 주소를 받아옴
+
+//
+//$db = getRootDB();
+//TODO: 로그인된 유저인지 확인해야함.
diff --git a/tmp_kakao/oauth_fail.html b/tmp_kakao/oauth_fail.html
new file mode 100644
index 00000000..b9f54799
--- /dev/null
+++ b/tmp_kakao/oauth_fail.html
@@ -0,0 +1,11 @@
+
+
+
+ >
+
+ OAuth 로그인 실패
+
+
+로그인에 실패하였습니다.
+
+
\ No newline at end of file
diff --git a/tmp_kakao/oauth_leave.php b/tmp_kakao/oauth_leave.php
new file mode 100644
index 00000000..d2bb3234
--- /dev/null
+++ b/tmp_kakao/oauth_leave.php
@@ -0,0 +1 @@
+YES
\ No newline at end of file
diff --git a/tmp_kakao/terms.html b/tmp_kakao/terms.html
new file mode 100644
index 00000000..0f0a471d
--- /dev/null
+++ b/tmp_kakao/terms.html
@@ -0,0 +1,5 @@
+개인정보로써 이메일, 계정명, 닉네임을 수집하며, 유저 로그인 및 다중 접속 탐지를 위해 사용함. 이메일은 필요에 따라 공지사항 등 본 사이트의 정보를 전파하는데 사용될 수 있음. 위의 언급한 내용 이외의 용도로 개인정보를 사용하지 않음.
+수집된 개인정보는 탈퇴 후 1개월간 보관됨.
+게임 시스템을 오용하거나, 서버에 해킹시도하거나, 분란을 야기하는 경우 경고 처리 후 차단될 수 있으며, 경중에 따라 경고 처리 없이 바로 차단될 수 있음.
+개인정보 관리자 : Hide_D
+문의는 hided62@gmail.com 으로.
\ No newline at end of file
diff --git a/tmp_kakao/try_login.php b/tmp_kakao/try_login.php
new file mode 100644
index 00000000..1de80261
--- /dev/null
+++ b/tmp_kakao/try_login.php
@@ -0,0 +1,17 @@
+set_admin_key('');
+
+$helper->test_user_management_api();
+//$helper->test_story_api();
+//$helper->test_talk_api();
+//$helper->test_push_notification_api();