1
0
Fork 0
mirror of https://github.com/Eggbertx/gochan.git synced 2025-08-02 10:56:25 -07:00

Use v1 base64captcha API

Also check for sql.ErrNoRows when SELECTing from DBPREFIXinfo, fixes #16
This commit is contained in:
Eggbertx 2020-02-07 21:46:30 -08:00
parent 21bee813b1
commit d4b7185ecd
11 changed files with 144 additions and 33 deletions

View file

@ -1,4 +1,4 @@
Copyright (c) 2013-2019, Eggbertx Copyright (c) 2013-2020, Eggbertx
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View file

@ -205,7 +205,9 @@ while [ -n "$1" ]; do
golang.org/x/crypto/bcrypt \ golang.org/x/crypto/bcrypt \
github.com/frustra/bbcode \ github.com/frustra/bbcode \
github.com/mattn/go-sqlite3 \ github.com/mattn/go-sqlite3 \
github.com/tdewolff/minify github.com/tdewolff/minify \
gopkg.in/mojocn/base64Captcha.v1
# github.com/mojocn/base64Captcha
;; ;;
docker-image) docker-image)
# echo "Docker image creation not yet implemented" # echo "Docker image creation not yet implemented"

View file

@ -7,6 +7,6 @@
<h1>404: File not found</h1> <h1>404: File not found</h1>
<img src="/error/lol 404.gif" border="0" alt=""> <img src="/error/lol 404.gif" border="0" alt="">
<p>The requested file could not be found on this server. Are you just typing random stuff in the address bar? If you followed a link from this site here, then post <a href="/site">here</a></p> <p>The requested file could not be found on this server. Are you just typing random stuff in the address bar? If you followed a link from this site here, then post <a href="/site">here</a></p>
<hr><address>http://gochan.org powered by Gochan v2.11.1</address> <hr><address>http://gochan.org powered by Gochan v2.11.2</address>
</body> </body>
</html> </html>

View file

@ -7,6 +7,6 @@
<h1>500: Internal Server error</h1> <h1>500: Internal Server error</h1>
<img src="/error/derpy server.gif" border="0" alt=""> <img src="/error/derpy server.gif" border="0" alt="">
<p>The server encountered an error while trying to serve the page, and we apologize for the inconvenience. The <a href="https://en.wikipedia.org/wiki/Idiot">system administrator</a> will try to fix things as soon has he/she/it can.</p> <p>The server encountered an error while trying to serve the page, and we apologize for the inconvenience. The <a href="https://en.wikipedia.org/wiki/Idiot">system administrator</a> will try to fix things as soon has he/she/it can.</p>
<hr><address>http://gochan.org powered by Gochan v2.11.1</address> <hr><address>http://gochan.org powered by Gochan v2.11.2</address>
</body> </body>
</html> </html>

95
html/javascript/gochan.min.js vendored Normal file
View file

@ -0,0 +1,95 @@
var $jq=jQuery.noConflict();var down_arrow_symbol="&#9660;";var up_arrow_symbol="&#9650;";var $topbar;var $settings_menu;var $staff_btn;var $watched_threads_btn;var settings=[];var current_staff;var dropdown_div_created=false;var $qr;var movable_postpreviews=true;var expandable_postrefs=true;var opRegex=/(\d+)(p(\d)+)?.html$/;var Staff=function(name,rank,boards){this.name=name;this.rank=rank;this.boards=boards;}
function addStaffButtons(){$jq("input#delete-password").remove();$jq("input[value=Delete]").after("<input type=\"submit\" name=\"Ban\" value=\"Ban\" onclick=\"banSelectedPost(); return false;\" />")}
function getManagePage(){}
function banSelectedPost(){var board_dir_arr=location.pathname.split("/");if(board_dir_arr.length<2)return;var board_dir=board_dir_arr[1];var checks=$jq("input[type=checkbox]");if(checks.length==0){alert("No posts selected");return false;}
var post_id=0;for(var i=0;i<checks.length;i++){if(checks[i].id.indexOf("check")==0){post_id=checks[i].id.replace("check","");break;}}
window.location=webroot+"manage?action=bans&dir="+board_dir+"&postid="+post_id;}
function makeNewStaff(){var on_manage_page=false;if(window.location.pathname=="/manage"){on_manage_page=true;}else{var username_txt=$jq("input#username").val();var password_txt=$jq("input#password").val();var rank_sel=$jq("select#rank").val();$jq.ajax({method:'POST',url:webroot+"manage?action=staff",data:{"do":"add",username:username_txt,password:password_txt,rank:rank_sel,boards:"all"},cache:false,async:true,success:function(result){var rank_str;switch(rank_sel){case "3":rank_str="admin";break;case "2":rank_str="mod";break;case "1":rank_str="janitor";break;}
$jq("table#stafftable tr:last").after("<tr><td>"+username_txt+"</td><td>"+rank_str+"</td><td>all</td><td>now</td><td></td></tr>")},error:function(){alert("Something went wrong...")}});}
return on_manage_page;}
function getStaff(){var s;$jq.ajax({method:'GET',url:webroot+"manage",data:{action:'getstaffjquery',},dataType:"text",cache:true,async:false,success:function(result){var return_data=result.trim().split(";");s=new Staff(return_data[0],return_data[1],return_data[2].split(","));},error:function(){s=new Staff("nobody","0","");}});return s;}
function getStaffMenuHTML(){var s="<ul class=\"staffmenu\">";$jq.ajax({method:'GET',url:webroot+"manage",data:{action:'staffmenu',},dataType:"text",cache:true,async:false,success:function(result){var lines=result.substring(result.indexOf("body>")+5,result.indexOf("</body")).trim().split("\n")
var num_lines=lines.length;for(var l=0;l<num_lines;l++){if(lines[l]!=""){if(lines[l].indexOf("<a href=")>-1){s+=lines[l].substr(0,lines[l].indexOf("\">")+2)+"<li>"+$jq(lines[l]).text()+"</li></a>";}else{s+="<li>"+lines[l]+"</li>";}}}},error:function(){s="Something went wrong :/";}});return s+"</ul>";}
function openStaffLightBox(action_url){$jq.ajax({method:'GET',url:webroot+"manage",data:{action:action_url,},dataType:"html",async:false,success:function(result){var body='<div id="body-mock">'+result.replace(/^[\s\S]*<body.*?>|<\/body>[\s\S]*$/ig,'')+'</div>';var $body=$jq(body);var header=$body.find("h1");var header_text=header.text();header.remove();if(header_text=="")header_text="Manage";showLightBox(header_text,$body.html());},error:function(result){var responsetext=result.responseText;header=responsetext.substring(responsetext.indexOf("<h1>")+4,responsetext.indexOf("</h1>"))
responsetext=responsetext.substring(responsetext.indexOf("</h1>")+5,responsetext.indexOf("</body>"));if(header==""){showLightBox("Manage",responsetext);}else{showLightBox(header,responsetext);}}});}
function preparePostPreviews(is_inline){var m_type="mousemove";if(!movable_postpreviews)m_type="mouseover";var hvr_str="a.postref";if(is_inline)hvr_str="div.inlinepostprev "+hvr_str;$jq(hvr_str).hover(function(){var replaced=this.innerHTML.replace("&gt;&gt;","");var postID="div.reply#reply"+replaced+",div.op-post#op"+replaced;var $clone=$jq(postID).clone()
$jq(document.body).append($clone.attr({"class":"postprev","id":postID+"preview"}));$clone.find(".inlinepostprev").remove();$jq(document).bind(m_type,function(e){$jq('.postprev').css({left:e.pageX+8,top:e.pageY+8});})},function(){$jq(".postprev").remove();});if(expandable_postrefs){var clk_str="a.postref";if(is_inline)clk_str="div.inlinepostprev "+clk_str;$jq(clk_str).click(function(){$this=$jq(this);if($this.next().attr("class")!="inlinepostprev"){$jq(".postprev").remove();var replaced=this.innerHTML.replace("&gt;&gt;","");var postID="div.reply#reply"+replaced+",div.op-post#op"+replaced;var $clone=$jq(postID).clone()
$clone.find("postprev").remove();$this.after($clone.attr("class","inlinepostprev"));}else{$this.next().remove();}
return false;});}}
function getUploadPostID(upload,container){var jqu=container?$jq(upload):$jq(upload).parent();if(insideOP(jqu))return jqu.siblings().eq(4).text();else return jqu.siblings().eq(3).text();}
function insideOP(elem){return $jq(elem).parents("div.op-post").length>0;}
function prepareThumbnails(){$jq("a.upload-container").click(function(e){var a=$jq(this);var thumb=a.find("img.upload");var thumbURL=thumb.attr("src");var uploadURL=thumb.attr("alt");thumb.removeAttr("width").removeAttr("height");var file_info_elem=a.prevAll(".file-info:first");if((thumbURL+uploadURL).indexOf(".webm")>0){thumb.hide();var video=$jq("<video />").prop({src:uploadURL,autoplay:true,controls:true,class:"upload",loop:true}).insertAfter(file_info_elem);file_info_elem.append($jq("<a />").prop("href","javascript:;").click(function(e){video.remove();thumb.show();this.remove();thumb.prop({src:thumbURL,alt:uploadURL});}).css({"padding-left":"8px"}).html("[Close]<br />"));}else{thumb.attr({src:uploadURL,alt:thumbURL});}
return false;});}
var TopBarButton=function(title,callback_open,callback_close){this.title=title;$topbar.append("<a href=\"javascript:void(0)\" class=\"dropdown-button\" id=\""+title.toLowerCase()+"\">"+title+down_arrow_symbol+"</a>");var button_open=false;$topbar.find("a#"+title.toLowerCase()).click(function(event){if(!button_open){callback_open();if(callback_close!=null){$jq(document).bind("click",function(){callback_close();});button_open=true;}}else{if(callback_close!=null){callback_close();}
button_open=false;}
return false;});}
var DropDownMenu=function(title,menu_html){this.title=title;this.menuHTML=menu_html;this.button=new TopBarButton(title,function(){$topbar.after("<div id=\""+title.toLowerCase()+"\" class=\"dropdown-menu\">"+menu_html+"</div>");$jq("a#"+title.toLowerCase()+"-menu").children(0).html(title+up_arrow_symbol);$jq("div#"+title.toLowerCase()).css({top:$topbar.outerHeight()});},function(){$jq("div#"+title.toLowerCase()+".dropdown-menu").remove();$jq("a#"+title.toLowerCase()+"-menu").children(0).html(title+down_arrow_symbol);});}
function showLightBox(title,innerHTML){$jq(document.body).prepend("<div class=\"lightbox-bg\"></div><div class=\"lightbox\"><div class=\"lightbox-title\">"+title+"<a href=\"#\" class=\"lightbox-x\">X</a><hr /></div>"+innerHTML+"</div>");$jq("a.lightbox-x").click(function(){$jq(".lightbox").remove();$jq(".lightbox-bg").remove();});$jq(".lightbox-bg").click(function(){$jq(".lightbox").remove();$jq(".lightbox-bg").remove();});}
function showMessage(msg){if(!lightbox_css_added){$jq(document).find("head").append("\t<link rel=\"stylesheet\" href=\"/css/lightbox.css\" />");lightbox_css_added=true;}
$jq(document.body).prepend("<div class=\"lightbox-bg\"></div><div class=\"lightbox-msg\">"+msg+"<br /><button class=\"lightbox-msg-ok\" style=\"float: right; margin-top:8px;\">OK</button></div>");var centeroffset=parseInt($jq(".lightbox-msg").css("transform-origin").replace("px",""),10)+$jq(".lightbox-msg").width()/2
$jq(".lightbox-msg").css({"position":"fixed","left":$jq(document).width()/2-centeroffset/2-16});$jq(".lightbox-msg-ok").click(function(){$jq(".lightbox-msg").remove();$jq(".lightbox-bg").remove();});$jq(".lightbox-bg").click(function(){$jq(".lightbox-msg").remove();$jq(".lightbox-bg").remove();});}
function quote(e){var msgbox_id="postmsg";if(document.selection){document.getElementById(msgbox_id).focus();var t=document.getselection.createRange();t.text=">>"+e+"\n"}else if(document.getElementById(msgbox_id).selectionStart||"0"==document.getElementById(msgbox_id).selectionStart){var n=document.getElementById(msgbox_id).selectionStart,o=document.getElementById(msgbox_id).selectionEnd;document.getElementById(msgbox_id).value=document.getElementById(msgbox_id).value.substring(0,n)+">>"+e+"\n"+document.getElementById(msgbox_id).value.substring(o,document.getElementById(msgbox_id).value.length)}else document.getElementById(msgbox_id).value+=">>"+e+"\n"
window.scroll(0,document.getElementById(msgbox_id).offsetTop-48);}
function deletePost(id){var password=prompt("Password (this doesn't do anything yet)");}
function deleteCheckedPosts(){if(confirm('Are you sure you want to delete these posts?')==true){var form=$jq("form#main-form");form.append("<input type=\"hidden\" name=\"action\" value=\"delete\" ");form.get(0).submit();return true;}}
function getArg(name){var href=window.location.href;var args=href.substr(href.indexOf("?")+1,href.length);args=args.split("&");for(var i=0;i<args.length;i++){temp_args=args[i];temp_args=temp_args.split("=");temp_name=temp_args[0];temp_value=temp_args[1];args[temp_name]=temp_value;args[i]=temp_args;}
return args[name];}
function hidePost(id){var posttext=$jq("div#"+id+".post .posttext");if(posttext.length>0)posttext.remove();var fileinfo=$jq("div#"+id+".post .file-info")
if(fileinfo.length>0)fileinfo.remove();var postimg=$jq("div#"+id+".post img")
if(postimg.length>0)postimg.remove();}
function initCookies(){$jq("input[name=postname]").val(getCookie("name",""));$jq("input[name=postemail]").val(getCookie("email",""));$jq("input[name=postpassword]").val(getCookie("password",""));$jq("input[name=delete-password]").val(getCookie("password",""));}
function setCookie(name,value,expires){var expiresStr="";if(expires){expiresStr=";expires="
var d=new Date();d.setTime(d.getTime()+1000*60*60*24*expires)
expiresStr+=d.toUTCString();}
document.cookie=name+"="+escape(value)+expiresStr+";path="+webroot;}
function getCookie(name,defaultVal){var val=defaultVal;var cookie_arr=document.cookie.split("; ");for(var i=0;i<cookie_arr.length;i++){pair=cookie_arr[i].split("=");if(pair[0]==name){try{val=decodeURIComponent(pair[1].replace("+"," ").replace("%2B","+"))}catch(err){return defaultVal;}
break;}}
return val;}
function reportPost(id){var reason=prompt("Reason (this doesn't do anything yet)");}
$jq(document).keydown(function(e){var tag;if(e.ctrlKey){switch(e.keyCode){case 10:if(e.target.nodeName=="TEXTAREA")
document.getElementById("postform").submit();break;case 13:if(e.target.nodeName=="TEXTAREA")
document.getElementById("postform").submit();break;case 66:tag="b";break;case 73:tag="i";break;case 82:tag="s";break;case 83:tag="?";break;case 85:tag="u";break;}}
if(tag!=null&&e.target.nodeName=="TEXTAREA"){e.preventDefault();var ta=e.target;var val=ta.value;var ss=ta.selectionStart;var se=ta.selectionEnd;var r=se+2+tag.length;ta.value=val.slice(0,ss)+("["+tag+"]")+val.slice(ss,se)+("[/"+tag+"]")+val.slice(se);ta.setSelectionRange(r,r);}});function getBoard(){var rootIndex=window.location.pathname.indexOf(webroot);var board=window.location.pathname.substring(rootIndex+webroot.length);if(board.length>0&&board.indexOf("/")>-1){board=board.split("/")[0];}else{board="";}
return board;}
function getPageThread(){var arr=opRegex.exec(window.location.pathname);var info={board:getBoard(),boardID:-1,op:-1,page:0};if(arr==null)return info;if(arr.length>1)info.op=arr[1];if(arr.length>3)info.page=arr[3];if(arr.board!="")info.boardID=$jq("form#postform input[name=boardid]").val()-1;return info;}
function changePage(sel){var info=getPageThread();if(info.board==""||info.op==-1)return;if(sel.value!="")
window.location=webroot+info.board+"/res/"+info.op+"p"+sel.value+".html";}
function getSetting(id){for(var s=0;s<settings.length;s++){if(settings[s].id==id)return settings[s];}
return{};}
var Setting=function(id,text,type,defaultVal,callback,options){this.id=id;this.text=text;this.type=type;this.defaultVal=defaultVal;if(getCookie(this.id)==undefined){this.setCookie(this.defaultVal,7);}
if(this.type=="select")this.options=options;if(!callback)this.callback=function(){};else this.callback=callback;}
Setting.prototype.save=function(newVal,expires){setCookie(this.id,newVal,expires);this.callback();}
Setting.prototype.getCookie=function(defaultVal){var val=getCookie(this.id,defaultVal);if(this.type=="checkbox")val=(val=="true");return val;}
Setting.prototype.setCookie=function(val,expires){setCookie(this.id,val,expires);}
Setting.prototype.getVal=function(){var elem=document.getElementById(this.id);if(elem!=null){if(elem.type=="checkbox")return elem.checked;return elem.value;}}
Setting.prototype.renderHTML=function(){var html;switch(this.type){case "checkbox":if(this.getCookie()==true)html="<input id=\""+this.id+"\" type=\"checkbox\" checked=\"checked\" />";else html="<input id=\""+this.id+"\" type=\"checkbox\" />";break;case "select":html="<select id=\""+this.id+"\" name=\""+this.id+"\" style=\"min-width:50%\">";for(var o=0;o<this.options.length;o++){html+="<option value=\""+this.options[o].val+"\""
if(this.getCookie()==this.options[o].val)html+="selected=\""+this.getCookie()+"\"";html+=">"+this.options[o].text+"</option>";}
html+="</select>";break;case "textarea":html="<textarea id=\""+this.id+"\" name=\""+this.id+"\">"+this.getCookie()+"</textarea>";break;default:html="<input id=\""+this.id+"\" type=\"checkbox\" val=\""+this.getCookie()+"\" />";break;}
return html;}
function initSettings(){var settings_html="<div id=\"settings-container\" style=\"overflow:auto\"><table width=\"100%\"><colgroup><col span=\"1\" width=\"50%\"><col span=\"1\" width=\"50%\"></colgroup>";settings.push(new Setting("style","Style","select",defaultStyle,function(){document.getElementById("theme").setAttribute("href",webroot+"css/"+this.getCookie(defaultStyle));},[]),new Setting("pintopbar","Pin top bar","checkbox",true),new Setting("enableposthover","Preview post on hover","checkbox",true),new Setting("enablepostclick","Preview post on click","checkbox",true),new Setting("useqr","Use Quick Reply box","checkbox",true));for(var s=0;s<styles.length;s++){settings[0].options.push({text:styles[s].Name,val:styles[s].Filename});}
for(var s=0;s<settings.length;s++){var setting=settings[s];settings_html+="<tr><td><b>"+setting.text+":</b></td><td>"+setting.renderHTML()+"</td></tr>";}
settings_html+="</table></div><div class=\"lightbox-footer\"><hr /><button id=\"save-settings-button\">Save Settings</button></div>";$settings_menu=new TopBarButton("Settings",function(){showLightBox("Settings",settings_html,null)
$jq("button#save-settings-button").click(function(){for(var s=0;s<settings.length;s++){var val=settings[s].getVal();settings[s].save(val);}});});}
function initQR(pageThread){var $qrbuttons=$jq("<div />").prop("id","qrbuttons").append("<input type=\"file\" id=\"imagefile\" name=\"imagefile\" style=\"display: none;\" />"+
"<input name=\"imagefilebtn\" type=\"button\" onclick=\"document.getElementById('imagefile').click();\" value=\"Browse...\">"+
"<input type=\"submit\" value=\"Post\" style=\"float:right;\"/>")
var $postform=$jq("<form />").prop({id:"qrpostform",name:"qrpostform",action:"/post",method:"POST",enctype:"multipart/form-data"}).append("<input type=\"hidden\" name=\"threadid\" value=\""+pageThread.op+"\" />"+
"<input type=\"hidden\" name=\"boardid\" value=\"1\" />"+
"<div id=\"qrpostname\"><input id=\"qrpostname\" type=\"text\" name=\"postname\" value=\""+getCookie("name","")+"\" placeholder=\"Name\"/></div>"+
"<div id=\"qrpostemail\"><input id=\"qrpostemail\" type=\"text\" name=\"postemail\" value=\""+getCookie("email","")+"\" placeholder=\"Email\"/></div>"+
"<div id=\"qrpostsubject\"><input id=\"qrpostsubject\" type=\"text\" name=\"postsubject\" placeholder=\"Subject\"/></div>"+
"<div id=\"qrpostmsg\"><textarea id=\"qrpostmsg\" name=\"postmsg\" id=\"postmsg\" placeholder=\"Message\"></textarea></div>",$qrbuttons);var qrTop=32;if(!getCookie("pintopbar",true))qrTop=$topbar.outerHeight()+16;var qrPos=JSON.parse(getCookie("qrpos",JSON.stringify({top:qrTop,left:16})));$qr=$jq("<div />").prop({id:"qr-box",style:"top:"+qrPos.top+"px;left:"+qrPos.left+"px;position:fixed"}).append($jq("<div id=\"qr-title\" >"+
"<span id=\"qr-message\"></span>"+
"<span id=\"qr-buttons\"><a href=\"javascript:toBottom();\">&#9660;</a>"+
"<a href=\"javascript:toTop();\">&#9650;</a><a href=\"javascript:closeQR();\">X</a></span></div>"),$postform).draggable({handle:"div#qr-title",scroll:false,containment:"window",drag:function(event,ui){setCookie("qrpos",JSON.stringify(ui.position),7);if(ui.position.top<=$topbar.outerHeight())return false;}}).insertAfter("div#footer");}
function closeQR(){if($qr)$qr.remove();}
function toTop(){window.scrollTo(0,0);}
function toBottom(){window.scrollTo(0,document.body.scrollHeight);}
$jq(document).ready(function(){var pageThread=getPageThread();var style=getCookie("style",defaultStyle);var themeElem=document.getElementById("theme");if(themeElem)themeElem.setAttribute("href",webroot+"css/"+style);current_staff=getStaff()
initCookies();$topbar=$jq("div#topbar");if(!getCookie("pintopbar",true)){$topbar.css({"position":"absolute","top":"0px","padding-left":"0px","padding-right":"0px",});}
initSettings();$watched_threads_btn=new TopBarButton("WT",function(){});if(current_staff.rank>0){$staff_btn=new DropDownMenu("Staff",getStaffMenuHTML())
$jq("a#staff.dropdown-button").click(function(){$jq("a.staffmenu-item").click(function(){var url=$jq(this).attr("id");openStaffLightBox(url)});});addStaffButtons();}
if(pageThread.board!=""){prepareThumbnails();if(getCookie("useqr")=="true")initQR(pageThread);}
preparePostPreviews(false);$jq(".plus").click(function(){var block=$jq(this).parent().next();if(block.css("display")=="none"){block.show();$jq(this).html("-");}else{block.hide();$jq(this).html("+");}});thread_menu_open=false;$jq(".thread-ddown a, body").click(function(e){e.stopPropagation();var post_id=$jq(this).parent().parent().parent().attr("id");var is_op=$jq(this).parent().parent().parent().attr("class")=="thread";if(post_id==undefined)return;if($jq(this).parent().find("div.thread-ddown-menu").length==0){$jq("div.thread-ddown-menu").remove();menu_html="<div class=\"thread-ddown-menu\" id=\""+post_id+"\">";if(!is_op)menu_html+="<ul><li><a href=\"javascript:hidePost("+post_id+");\" class=\"hide-post\">Show/Hide post</a></li>";menu_html+="<li><a href=\"javascript:deletePost("+post_id+");\" class=\"delete-post\">Delete post</a></li>"+
"<li><a href=\"javascript:reportPost("+post_id+");\" class=\"report-post\">Report Post</a></li></ul>"+
"</div>";$jq(this).parent().append(menu_html);thread_menu_open=true;}else{$jq("div.thread-ddown-menu").remove();thread_menu_open=false;}});});

View file

@ -2,14 +2,17 @@ package main
import ( import (
"fmt" "fmt"
"image/color"
"net/http" "net/http"
"strconv" "strconv"
"github.com/mojocn/base64Captcha" //"github.com/mojocn/base64Captcha"
"gopkg.in/mojocn/base64Captcha.v1"
) )
var ( var (
charCaptchaCfg base64Captcha.ConfigCharacter captchaString *base64Captcha.DriverString
driver *base64Captcha.DriverString
) )
type captchaJSON struct { type captchaJSON struct {
@ -21,23 +24,19 @@ type captchaJSON struct {
} }
func initCaptcha() { func initCaptcha() {
charCaptchaCfg = base64Captcha.ConfigCharacter{ if !config.UseCaptcha {
Height: config.CaptchaHeight, // originally 60 return
Width: config.CaptchaWidth, // originally 240
Mode: base64Captcha.CaptchaModeNumberAlphabet,
ComplexOfNoiseText: base64Captcha.CaptchaComplexLower,
ComplexOfNoiseDot: base64Captcha.CaptchaComplexLower,
IsUseSimpleFont: true,
IsShowHollowLine: false,
IsShowNoiseDot: true,
IsShowNoiseText: false,
IsShowSlimeLine: true,
IsShowSineLine: false,
CaptchaLen: 8,
} }
driver = base64Captcha.NewDriverString(
config.CaptchaHeight, config.CaptchaWidth, 0, 0, 6,
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
&color.RGBA{0, 0, 0, 0}, nil).ConvertFonts()
} }
func serveCaptcha(writer http.ResponseWriter, request *http.Request) { func serveCaptcha(writer http.ResponseWriter, request *http.Request) {
if !config.UseCaptcha {
return
}
var err error var err error
if err = request.ParseForm(); err != nil { if err = request.ParseForm(); err != nil {
serveErrorPage(writer, err.Error()) serveErrorPage(writer, err.Error())
@ -72,7 +71,7 @@ func serveCaptcha(writer http.ResponseWriter, request *http.Request) {
captchaID := request.FormValue("captchaid") captchaID := request.FormValue("captchaid")
captchaAnswer := request.FormValue("captchaanswer") captchaAnswer := request.FormValue("captchaanswer")
if captchaID != "" && request.FormValue("didreload") != "1" { if captchaID != "" && request.FormValue("didreload") != "1" {
goodAnswer := base64Captcha.VerifyCaptcha(captchaID, captchaAnswer) goodAnswer := base64Captcha.DefaultMemStore.Verify(captchaID, captchaAnswer, true)
if goodAnswer { if goodAnswer {
if tempPostIndex > -1 && tempPostIndex < len(tempPosts) { if tempPostIndex > -1 && tempPostIndex < len(tempPosts) {
// came from a /post redirect, insert the specified temporary post // came from a /post redirect, insert the specified temporary post
@ -100,8 +99,10 @@ func serveCaptcha(writer http.ResponseWriter, request *http.Request) {
} }
func getCaptchaImage() (captchaID string, chaptchaB64 string) { func getCaptchaImage() (captchaID string, chaptchaB64 string) {
var captchaInstance base64Captcha.CaptchaInterface if !config.UseCaptcha {
captchaID, captchaInstance = base64Captcha.GenerateCaptcha("", charCaptchaCfg) return
chaptchaB64 = base64Captcha.CaptchaWriteToBase64Encoding(captchaInstance) }
captcha := base64Captcha.NewCaptcha(driver, base64Captcha.DefaultMemStore)
captchaID, chaptchaB64, _ = captcha.Generate()
return return
} }

View file

@ -6,7 +6,10 @@ import (
) )
func TestGetCaptchaImage(t *testing.T) { func TestGetCaptchaImage(t *testing.T) {
config.UseCaptcha = true
config.CaptchaWidth = 240
config.CaptchaHeight = 80
initCaptcha() initCaptcha()
captchaID, captchaB64 := getCaptchaImage() captchaID, captchaB64 := getCaptchaImage()
fmt.Println("captchaID:", captchaID, "\ncaptchaB64:", captchaB64) fmt.Printf("captchaID: %s\ncaptchaB64: %s\n", captchaID, captchaB64)
} }

View file

@ -618,7 +618,7 @@ func makePost(writer http.ResponseWriter, request *http.Request) {
buildFrontPage() buildFrontPage()
if emailCommand == "noko" { if emailCommand == "noko" {
if post.ParentID == 0 { if post.ParentID < 1 {
http.Redirect(writer, request, config.SiteWebfolder+boards[post.BoardID-1].Dir+"/res/"+strconv.Itoa(post.ID)+".html", http.StatusFound) http.Redirect(writer, request, config.SiteWebfolder+boards[post.BoardID-1].Dir+"/res/"+strconv.Itoa(post.ID)+".html", http.StatusFound)
} else { } else {
http.Redirect(writer, request, config.SiteWebfolder+boards[post.BoardID-1].Dir+"/res/"+strconv.Itoa(post.ParentID)+".html#"+strconv.Itoa(post.ID), http.StatusFound) http.Redirect(writer, request, config.SiteWebfolder+boards[post.BoardID-1].Dir+"/res/"+strconv.Itoa(post.ParentID)+".html#"+strconv.Itoa(post.ID), http.StatusFound)

View file

@ -68,11 +68,17 @@ func connectToSQLServer() {
} }
var sqlVersionStr string var sqlVersionStr string
if err = queryRowSQL("SELECT value FROM "+config.DBprefix+"info WHERE name = 'version'", isNewInstall := false
[]interface{}{}, []interface{}{&sqlVersionStr}); err != nil { if err = queryRowSQL(
"SELECT value FROM "+config.DBprefix+"info WHERE name = 'version'",
[]interface{}{}, []interface{}{&sqlVersionStr},
); err == sql.ErrNoRows {
isNewInstall = true
} else if err != nil {
handleError(0, "failed: %s\n", customError(err)) handleError(0, "failed: %s\n", customError(err))
os.Exit(2) os.Exit(2)
} }
var numBoards, numStaff int var numBoards, numStaff int
rows, err := querySQL("SELECT COUNT(*) FROM " + config.DBprefix + "boards UNION ALL SELECT COUNT(*) FROM " + config.DBprefix + "staff") rows, err := querySQL("SELECT COUNT(*) FROM " + config.DBprefix + "boards UNION ALL SELECT COUNT(*) FROM " + config.DBprefix + "staff")
if err != nil { if err != nil {
@ -108,6 +114,10 @@ func connectToSQLServer() {
buildFrontPage() buildFrontPage()
buildBoardListJSON() buildBoardListJSON()
buildBoards() buildBoards()
if !isNewInstall {
return
}
if _, err = execSQL( if _, err = execSQL(
"INSERT INTO "+config.DBprefix+"info (name,value) VALUES('version',?)", "INSERT INTO "+config.DBprefix+"info (name,value) VALUES('version',?)",
versionStr); err != nil { versionStr); err != nil {
@ -150,8 +160,8 @@ func initDB(initFile string) error {
for _, statement := range sqlArr { for _, statement := range sqlArr {
if statement != "" && statement != " " { if statement != "" && statement != " " {
if _, err := db.Exec(statement + ";"); err != nil { if _, err = db.Exec(statement + ";"); err != nil {
panic("Error with SQL statement:" + statement) return err
} }
} }
} }

View file

@ -250,10 +250,10 @@ func getPostArr(parameterList map[string]interface{}, extra string) (posts []Pos
// TODO: replace where with a map[string]interface{} like getBoardsArr() // TODO: replace where with a map[string]interface{} like getBoardsArr()
func getSectionArr(where string) (sections []BoardSection, err error) { func getSectionArr(where string) (sections []BoardSection, err error) {
if where == "" { if where != "" {
where = "1 = 1" where = "WHERE " + where
} }
rows, err := querySQL("SELECT * FROM " + config.DBprefix + "sections WHERE " + where + " ORDER BY list_order") rows, err := querySQL("SELECT * FROM " + config.DBprefix + "sections " + where + " ORDER BY list_order")
defer closeHandle(rows) defer closeHandle(rows)
if err != nil { if err != nil {
handleError(0, err.Error()) handleError(0, err.Error())

View file

@ -1 +1 @@
2.11.1 2.11.2