aboutsummaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/blacklist.go33
-rw-r--r--util/key.go30
-rw-r--r--util/proxy.go40
-rw-r--r--util/util.go79
-rw-r--r--util/verification.go482
5 files changed, 559 insertions, 105 deletions
diff --git a/util/blacklist.go b/util/blacklist.go
index 5368037..acb0b21 100644
--- a/util/blacklist.go
+++ b/util/blacklist.go
@@ -11,28 +11,28 @@ type PostBlacklist struct {
Regex string
}
-func DeleteRegexBlacklistDB(id int) error {
+func DeleteRegexBlacklist(id int) error {
query := `delete from postblacklist where id=$1`
-
_, err := config.DB.Exec(query, id)
- return err
+
+ return MakeError(err, "DeleteRegexBlacklist")
}
-func GetRegexBlacklistDB() ([]PostBlacklist, error) {
+func GetRegexBlacklist() ([]PostBlacklist, error) {
var list []PostBlacklist
query := `select id, regex from postblacklist`
-
rows, err := config.DB.Query(query)
+
if err != nil {
- return list, err
+ return list, MakeError(err, "GetRegexBlacklist")
}
defer rows.Close()
for rows.Next() {
var temp PostBlacklist
- rows.Scan(&temp.Id, &temp.Regex)
+ rows.Scan(&temp.Id, &temp.Regex)
list = append(list, temp)
}
@@ -40,10 +40,10 @@ func GetRegexBlacklistDB() ([]PostBlacklist, error) {
}
func IsPostBlacklist(comment string) (bool, error) {
- postblacklist, err := GetRegexBlacklistDB()
+ postblacklist, err := GetRegexBlacklist()
if err != nil {
- return false, err
+ return false, MakeError(err, "IsPostBlacklist")
}
for _, e := range postblacklist {
@@ -57,20 +57,15 @@ func IsPostBlacklist(comment string) (bool, error) {
return false, nil
}
-func WriteRegexBlacklistDB(regex string) error {
+func WriteRegexBlacklist(regex string) error {
var re string
query := `select from postblacklist where regex=$1`
if err := config.DB.QueryRow(query, regex).Scan(&re); err != nil {
- return err
- }
-
- if re != "" {
- return nil
+ query = `insert into postblacklist (regex) values ($1)`
+ _, err := config.DB.Exec(query, regex)
+ return MakeError(err, "WriteRegexBlacklist")
}
- query = `insert into postblacklist (regex) values ($1)`
-
- _, err := config.DB.Exec(query, regex)
- return err
+ return nil
}
diff --git a/util/key.go b/util/key.go
index cd8662a..60eeb43 100644
--- a/util/key.go
+++ b/util/key.go
@@ -3,6 +3,7 @@ package util
import (
"crypto/sha512"
"encoding/hex"
+ "errors"
"math/rand"
"os"
"strings"
@@ -13,14 +14,14 @@ import (
const domain = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-func CreateKey(len int) string {
+func CreateKey(len int) (string, error) {
// TODO: provided that CreateTripCode still uses sha512, the max len can be 128 at most.
if len > 128 {
- panic("len is greater than 128") // awful way to do it
+ return "", MakeError(errors.New("len is greater than 128"), "CreateKey")
}
str := CreateTripCode(RandomID(len))
- return str[:len]
+ return str[:len], nil
}
func CreateTripCode(input string) string {
@@ -29,23 +30,13 @@ func CreateTripCode(input string) string {
return hex.EncodeToString(out[:])
}
-func RandomID(size int) string {
- rng := size
- newID := strings.Builder{}
- for i := 0; i < rng; i++ {
- newID.WriteByte(domain[rand.Intn(len(domain))])
- }
-
- return newID.String()
-}
-
func GetCookieKey() (string, error) {
if config.CookieKey == "" {
var file *os.File
var err error
if file, err = os.OpenFile("config/config-init", os.O_APPEND|os.O_WRONLY, 0644); err != nil {
- return "", err
+ return "", MakeError(err, "GetCookieKey")
}
defer file.Close()
@@ -56,3 +47,14 @@ func GetCookieKey() (string, error) {
return config.CookieKey, nil
}
+
+func RandomID(size int) string {
+ rng := size
+ newID := strings.Builder{}
+
+ for i := 0; i < rng; i++ {
+ newID.WriteByte(domain[rand.Intn(len(domain))])
+ }
+
+ return newID.String()
+}
diff --git a/util/proxy.go b/util/proxy.go
index 0f4a648..daa90b5 100644
--- a/util/proxy.go
+++ b/util/proxy.go
@@ -9,27 +9,11 @@ import (
"github.com/FChannel0/FChannel-Server/config"
)
-func RouteProxy(req *http.Request) (*http.Response, error) {
- var proxyType = GetPathProxyType(req.URL.Host)
-
- if proxyType == "tor" {
- proxyUrl, err := url.Parse("socks5://" + config.TorProxy)
- if err != nil {
- return nil, err
- }
-
- proxyTransport := &http.Transport{Proxy: http.ProxyURL(proxyUrl)}
- client := &http.Client{Transport: proxyTransport, Timeout: time.Second * 15}
- return client.Do(req)
- }
-
- return http.DefaultClient.Do(req)
-}
-
func GetPathProxyType(path string) string {
if config.TorProxy != "" {
re := regexp.MustCompile(`(http://|http://)?(www.)?\w+\.onion`)
onion := re.MatchString(path)
+
if onion {
return "tor"
}
@@ -40,17 +24,35 @@ func GetPathProxyType(path string) string {
func MediaProxy(url string) string {
re := regexp.MustCompile("(.+)?" + config.Domain + "(.+)?")
-
if re.MatchString(url) {
return url
}
re = regexp.MustCompile("(.+)?\\.onion(.+)?")
-
if re.MatchString(url) {
return url
}
config.MediaHashs[HashMedia(url)] = url
+
return "/api/media?hash=" + HashMedia(url)
}
+
+func RouteProxy(req *http.Request) (*http.Response, error) {
+ var proxyType = GetPathProxyType(req.URL.Host)
+
+ if proxyType == "tor" {
+ proxyUrl, err := url.Parse("socks5://" + config.TorProxy)
+
+ if err != nil {
+ return nil, MakeError(err, "RouteProxy")
+ }
+
+ proxyTransport := &http.Transport{Proxy: http.ProxyURL(proxyUrl)}
+ client := &http.Client{Transport: proxyTransport, Timeout: time.Second * 15}
+
+ return client.Do(req)
+ }
+
+ return http.DefaultClient.Do(req)
+}
diff --git a/util/util.go b/util/util.go
index 9c1ba97..6d45442 100644
--- a/util/util.go
+++ b/util/util.go
@@ -12,6 +12,7 @@ import (
"os"
"path"
"regexp"
+ "runtime"
"strings"
"github.com/FChannel0/FChannel-Server/config"
@@ -28,34 +29,19 @@ func IsOnion(url string) bool {
func StripTransferProtocol(value string) string {
re := regexp.MustCompile("(http://|https://)?(www.)?")
-
value = re.ReplaceAllString(value, "")
return value
}
-func GetCaptchaCode(captcha string) string {
- re := regexp.MustCompile("\\w+\\.\\w+$")
- code := re.FindString(captcha)
-
- re = regexp.MustCompile("\\w+")
- code = re.FindString(code)
-
- return code
-}
-
func ShortURL(actorName string, url string) string {
+ var reply string
re := regexp.MustCompile(`.+\/`)
-
actor := re.FindString(actorName)
-
urlParts := strings.Split(url, "|")
-
op := urlParts[0]
- var reply string
-
if len(urlParts) > 1 {
reply = urlParts[1]
}
@@ -99,17 +85,11 @@ func LocalShort(url string) string {
func RemoteShort(url string) string {
re := regexp.MustCompile(`\w+$`)
-
id := re.FindString(StripTransferProtocol(url))
-
re = regexp.MustCompile(`.+/.+/`)
-
actorurl := re.FindString(StripTransferProtocol(url))
-
re = regexp.MustCompile(`/.+/`)
-
actorname := re.FindString(actorurl)
-
actorname = strings.Replace(actorname, "/", "", -1)
return "f" + actorname + "-" + id
@@ -117,9 +97,7 @@ func RemoteShort(url string) string {
func ShortImg(url string) string {
nURL := url
-
re := regexp.MustCompile(`(\.\w+$)`)
-
fileName := re.ReplaceAllString(url, "")
if len(fileName) > 26 {
@@ -199,32 +177,19 @@ func HashBytes(media []byte) string {
func EscapeString(text string) string {
// TODO: not enough
-
text = strings.Replace(text, "<", "&lt;", -1)
return text
}
func CreateUniqueID(actor string) (string, error) {
var newID string
- isUnique := false
- for !isUnique {
- newID = RandomID(8)
+ for true {
+ newID = RandomID(8)
query := "select id from activitystream where id=$1"
args := fmt.Sprintf("%s/%s/%s", config.Domain, actor, newID)
- rows, err := config.DB.Query(query, args)
- if err != nil {
- return "", MakeError(err, "CreateUniqueID")
- }
-
- defer rows.Close()
- // reusing a variable here
- // if we encounter a match, it'll get set to false causing the outer for loop to loop and to go through this all over again
- // however if nothing is there, it'll remain true and exit the loop
- isUnique = true
- for rows.Next() {
- isUnique = false
+ if err := config.DB.QueryRow(query, args); err != nil {
break
}
}
@@ -234,14 +199,13 @@ func CreateUniqueID(actor string) (string, error) {
func GetFileContentType(out multipart.File) (string, error) {
buffer := make([]byte, 512)
-
_, err := out.Read(buffer)
+
if err != nil {
return "", MakeError(err, "GetFileContentType")
}
out.Seek(0, 0)
-
contentType := http.DetectContentType(buffer)
return contentType, nil
@@ -249,26 +213,33 @@ func GetFileContentType(out multipart.File) (string, error) {
func GetContentType(location string) string {
elements := strings.Split(location, ";")
+
if len(elements) > 0 {
return elements[0]
- } else {
- return location
}
+
+ return location
}
-func CreatedNeededDirectories() {
+func CreatedNeededDirectories() error {
if _, err := os.Stat("./public"); os.IsNotExist(err) {
- os.Mkdir("./public", 0755)
+ if err = os.Mkdir("./public", 0755); err != nil {
+ return MakeError(err, "CreatedNeededDirectories")
+ }
}
if _, err := os.Stat("./pem/board"); os.IsNotExist(err) {
- os.MkdirAll("./pem/board", 0700)
+ if err = os.MkdirAll("./pem/board", 0700); err != nil {
+ return MakeError(err, "CreatedNeededDirectories")
+ }
}
+
+ return nil
}
-func LoadThemes() {
- // get list of themes
+func LoadThemes() error {
themes, err := ioutil.ReadDir("./static/css/themes")
+
if err != nil {
MakeError(err, "LoadThemes")
}
@@ -278,15 +249,16 @@ func LoadThemes() {
config.Themes = append(config.Themes, strings.TrimSuffix(f.Name(), e))
}
}
+
+ return nil
}
func GetBoardAuth(board string) ([]string, error) {
var auth []string
-
- query := `select type from actorauth where board=$1`
-
var rows *sql.Rows
var err error
+
+ query := `select type from actorauth where board=$1`
if rows, err = config.DB.Query(query, board); err != nil {
return auth, MakeError(err, "GetBoardAuth")
}
@@ -306,7 +278,8 @@ func GetBoardAuth(board string) ([]string, error) {
func MakeError(err error, msg string) error {
if err != nil {
- s := fmt.Sprintf("%s: %s", msg, err.Error())
+ _, _, line, _ := runtime.Caller(1)
+ s := fmt.Sprintf("%s:%d : %s", msg, line, err.Error())
return errors.New(s)
}
diff --git a/util/verification.go b/util/verification.go
new file mode 100644
index 0000000..c64b54d
--- /dev/null
+++ b/util/verification.go
@@ -0,0 +1,482 @@
+package util
+
+import (
+ "fmt"
+ "math/rand"
+ "net/smtp"
+ "os"
+ "os/exec"
+ "strings"
+ "time"
+
+ "github.com/FChannel0/FChannel-Server/config"
+ "github.com/gofiber/fiber/v2"
+ _ "github.com/lib/pq"
+)
+
+type Verify struct {
+ Type string
+ Identifier string
+ Code string
+ Created string
+ Board string
+}
+
+type VerifyCooldown struct {
+ Identifier string
+ Code string
+ Time int
+}
+
+type Signature struct {
+ KeyId string
+ Headers []string
+ Signature string
+ Algorithm string
+}
+
+func (verify Verify) Create() error {
+ query := `insert into verification (type, identifier, code, created) values ($1, $2, $3, $4)`
+ _, err := config.DB.Exec(query, verify.Type, verify.Identifier, verify.Code, time.Now().UTC().Format(time.RFC3339))
+
+ return MakeError(err, "Create")
+}
+
+func (verify Verify) CreateBoardAccess() error {
+ hasAccess, err := verify.HasBoardAccess()
+
+ if err != nil {
+ return MakeError(err, "CreateBoardAccess")
+ }
+
+ if !hasAccess {
+ query := `insert into boardaccess (identifier, board) values($1, $2)`
+ _, err := config.DB.Exec(query, verify.Identifier, verify.Board)
+
+ return MakeError(err, "CreateBoardAccess")
+ }
+
+ return nil
+}
+
+func (verify Verify) CreateBoardMod() error {
+ var pass string
+ var err error
+
+ if pass, err = CreateKey(50); err != nil {
+ return MakeError(err, "CreateBoardMod")
+ }
+
+ var code string
+
+ query := `select code from verification where identifier=$1 and type=$2`
+ if err := config.DB.QueryRow(query, verify.Board, verify.Type).Scan(&code); err != nil {
+ return nil
+ }
+
+ var ident string
+
+ query = `select identifier from boardaccess where identifier=$1 and board=$2`
+ if err := config.DB.QueryRow(query, verify.Identifier, verify.Board).Scan(&ident); err != nil {
+ return nil
+ }
+
+ if ident != verify.Identifier {
+ query := `insert into crossverification (verificationcode, code) values ($1, $2)`
+ if _, err := config.DB.Exec(query, code, pass); err != nil {
+ return MakeError(err, "CreateBoardMod")
+ }
+
+ query = `insert into boardaccess (identifier, code, board, type) values ($1, $2, $3, $4)`
+ if _, err = config.DB.Exec(query, verify.Identifier, pass, verify.Board, verify.Type); err != nil {
+ return MakeError(err, "CreateBoardMod")
+ }
+
+ config.Log.Printf("Board access - Board: %s, Identifier: %s, Code: %s\n", verify.Board, verify.Identifier, pass)
+ }
+
+ return nil
+}
+
+func (verify Verify) DeleteBoardMod() error {
+ var code string
+
+ query := `select code from boardaccess where identifier=$1 and board=$1`
+ if err := config.DB.QueryRow(query, verify.Identifier, verify.Board).Scan(&code); err != nil {
+ return nil
+ }
+
+ query = `delete from crossverification where code=$1`
+ if _, err := config.DB.Exec(query, code); err != nil {
+ return MakeError(err, "DeleteBoardMod")
+ }
+
+ query = `delete from boardaccess where identifier=$1 and board=$2`
+ if _, err := config.DB.Exec(query, verify.Identifier, verify.Board); err != nil {
+ return MakeError(err, "DeleteBoardMod")
+ }
+
+ return nil
+}
+
+func (verify Verify) GetBoardMod() (Verify, error) {
+ var nVerify Verify
+
+ query := `select code, board, type, identifier from boardaccess where identifier=$1`
+ if err := config.DB.QueryRow(query, verify.Identifier).Scan(&nVerify.Code, &nVerify.Board, &nVerify.Type, &nVerify.Identifier); err != nil {
+ return nVerify, MakeError(err, "GetBoardMod")
+ }
+
+ return nVerify, nil
+}
+
+func (verify Verify) GetCode() (Verify, error) {
+ var nVerify Verify
+
+ query := `select type, identifier, code, board from boardaccess where identifier=$1 and board=$2`
+ if err := config.DB.QueryRow(query, verify.Identifier, verify.Board).Scan(&nVerify.Type, &nVerify.Identifier, &nVerify.Code, &nVerify.Board); err != nil {
+ return verify, nil
+ }
+
+ return nVerify, nil
+}
+
+func (verify Verify) HasBoardAccess() (bool, error) {
+ var count int
+
+ query := `select count(*) from boardaccess where identifier=$1 and board=$2`
+ if err := config.DB.QueryRow(query, verify.Identifier, verify.Board).Scan(&count); err != nil {
+ return false, nil
+ }
+
+ return true, nil
+}
+
+func (verify Verify) SendVerification() error {
+ config.Log.Println("sending email")
+
+ from := config.SiteEmail
+ pass := config.SiteEmailPassword
+ to := verify.Identifier
+ body := fmt.Sprintf("You can use either\r\nEmail: %s \r\n Verfication Code: %s\r\n for the board %s", verify.Identifier, verify.Code, verify.Board)
+
+ msg := "From: " + from + "\n" +
+ "To: " + to + "\n" +
+ "Subject: Image Board Verification\n\n" +
+ body
+
+ err := smtp.SendMail(config.SiteEmailServer+":"+config.SiteEmailPort,
+ smtp.PlainAuth("", from, pass, config.SiteEmailServer),
+ from, []string{to}, []byte(msg))
+
+ return MakeError(err, "SendVerification")
+}
+
+func (verify Verify) VerifyCooldownAdd() error {
+ query := `insert into verficationcooldown (identifier, code) values ($1, $2)`
+ _, err := config.DB.Exec(query, verify.Identifier, verify.Code)
+
+ return MakeError(err, "VerifyCooldownAdd")
+}
+
+func BoardHasAuthType(board string, auth string) (bool, error) {
+ authTypes, err := GetBoardAuth(board)
+
+ if err != nil {
+ return false, MakeError(err, "BoardHasAuthType")
+ }
+
+ for _, e := range authTypes {
+ if e == auth {
+ return true, nil
+ }
+ }
+
+ return false, nil
+}
+
+func Captcha() string {
+ rand.Seed(time.Now().UTC().UnixNano())
+ domain := "ABEFHKMNPQRSUVWXYZ#$&"
+ rng := 4
+ newID := ""
+
+ for i := 0; i < rng; i++ {
+ newID += string(domain[rand.Intn(len(domain))])
+ }
+
+ return newID
+}
+
+func CreateNewCaptcha() error {
+ id := RandomID(8)
+ file := "public/" + id + ".png"
+
+ for true {
+ if _, err := os.Stat("./" + file); err == nil {
+ id = RandomID(8)
+ file = "public/" + id + ".png"
+ } else {
+ break
+ }
+ }
+
+ var pattern string
+
+ captcha := Captcha()
+ rnd := fmt.Sprintf("%d", rand.Intn(3))
+ srnd := string(rnd)
+
+ switch srnd {
+ case "0":
+ pattern = "pattern:verticalbricks"
+ break
+
+ case "1":
+ pattern = "pattern:verticalsaw"
+ break
+
+ case "2":
+ pattern = "pattern:hs_cross"
+ break
+
+ }
+
+ cmd := exec.Command("convert", "-size", "200x98", pattern, "-transparent", "white", file)
+ cmd.Stderr = os.Stderr
+
+ if err := cmd.Run(); err != nil {
+ return MakeError(err, "CreateNewCaptcha")
+ }
+
+ cmd = exec.Command("convert", file, "-fill", "blue", "-pointsize", "62", "-annotate", "+0+70", captcha, "-tile", "pattern:left30", "-gravity", "center", "-transparent", "white", file)
+ cmd.Stderr = os.Stderr
+
+ if err := cmd.Run(); err != nil {
+ return MakeError(err, "CreateNewCaptcha")
+ }
+
+ rnd = fmt.Sprintf("%d", rand.Intn(24)-12)
+ cmd = exec.Command("convert", file, "-rotate", rnd, "-wave", "5x35", "-distort", "Arc", "20", "-wave", "2x35", "-transparent", "white", file)
+ cmd.Stderr = os.Stderr
+
+ if err := cmd.Run(); err != nil {
+ return MakeError(err, "CreateNewCaptcha")
+ }
+
+ var verification Verify
+
+ verification.Type = "captcha"
+ verification.Code = captcha
+ verification.Identifier = file
+
+ return verification.Create()
+}
+
+func GetRandomCaptcha() (string, error) {
+ var verify string
+
+ query := `select identifier from verification where type='captcha' order by random() limit 1`
+ if err := config.DB.QueryRow(query).Scan(&verify); err != nil {
+ return verify, MakeError(err, "GetRandomCaptcha")
+ }
+
+ return verify, nil
+}
+
+func GetCaptchaTotal() (int, error) {
+ var count int
+
+ query := `select count(*) from verification where type='captcha'`
+ if err := config.DB.QueryRow(query).Scan(&count); err != nil {
+ return count, MakeError(err, "GetCaptchaTotal")
+ }
+
+ return count, nil
+}
+
+func GetCaptchaCode(verify string) (string, error) {
+ var code string
+
+ query := `select code from verification where identifier=$1 limit 1`
+ if err := config.DB.QueryRow(query, verify).Scan(&code); err != nil {
+ return code, MakeError(err, "GetCaptchaCodeDB")
+ }
+
+ return code, nil
+}
+
+func DeleteCaptchaCode(verify string) error {
+ query := `delete from verification where identifier=$1`
+ _, err := config.DB.Exec(query, verify)
+
+ if err != nil {
+ return MakeError(err, "DeleteCaptchaCode")
+ }
+
+ err = os.Remove("./" + verify)
+ return MakeError(err, "DeleteCaptchaCode")
+}
+
+func GetVerificationByCode(code string) (Verify, error) {
+ // TODO: this only needs to select one row.
+
+ var verify Verify
+
+ query := `select type, identifier, code, board from boardaccess where code=$1`
+
+ rows, err := config.DB.Query(query, code)
+ if err != nil {
+ return verify, MakeError(err, "GetVerificationByCode")
+ }
+
+ defer rows.Close()
+
+ for rows.Next() {
+ if err := rows.Scan(&verify.Type, &verify.Identifier, &verify.Code, &verify.Board); err != nil {
+ return verify, MakeError(err, "GetVerificationByCode")
+ }
+ }
+
+ return verify, nil
+}
+
+func GetVerificationByEmail(email string) (Verify, error) {
+ var verify Verify
+
+ query := `select type, identifier, code, board from boardaccess where identifier=$1`
+ if err := config.DB.QueryRow(query, email).Scan(&verify.Type, &verify.Identifier, &verify.Code, &verify.Board); err != nil {
+ return verify, nil
+ }
+
+ return verify, nil
+}
+
+func GetVerify(access string) (Verify, error) {
+ verify, err := GetVerificationByCode(access)
+
+ if err != nil {
+ return verify, MakeError(err, "GetVerify")
+ }
+
+ if verify.Identifier == "" {
+ verify, err = GetVerificationByEmail(access)
+ }
+
+ return verify, MakeError(err, "GetVerify")
+}
+
+func HasAuthCooldown(auth string) (bool, error) {
+ var current VerifyCooldown
+ var err error
+
+ if current, err = VerifyCooldownCurrent(auth); err != nil {
+ return false, MakeError(err, "HasAuthCooldown")
+ }
+
+ if current.Time > 0 {
+ return true, nil
+ }
+
+ return false, nil
+}
+
+func HasAuth(code string, board string) (bool, error) {
+ verify, err := GetVerificationByCode(code)
+ if err != nil {
+ return false, MakeError(err, "HasAuth")
+ }
+
+ if res, err := verify.HasBoardAccess(); err == nil && (verify.Board == config.Domain || (res && verify.Board == board)) {
+ return true, nil
+ } else {
+ return false, MakeError(err, "HasAuth")
+ }
+
+ return false, nil
+}
+
+func IsEmailSetup() bool {
+ return config.SiteEmail != "" || config.SiteEmailPassword != "" || config.SiteEmailServer != "" || config.SiteEmailPort != ""
+}
+
+func VerficationCooldown() error {
+ query := `select identifier, code, time from verificationcooldown`
+ rows, err := config.DB.Query(query)
+
+ if err != nil {
+ return MakeError(err, "VerficationCooldown")
+ }
+
+ defer rows.Close()
+ for rows.Next() {
+ var verify VerifyCooldown
+
+ if err := rows.Scan(&verify.Identifier, &verify.Code, &verify.Time); err != nil {
+ return MakeError(err, "VerficationCooldown")
+ }
+
+ nTime := verify.Time - 1
+ query = `update set time=$1 where identifier=$2`
+
+ if _, err := config.DB.Exec(query, nTime, verify.Identifier); err != nil {
+ return MakeError(err, "VerficationCooldown")
+ }
+
+ VerficationCooldownRemove()
+ }
+
+ return nil
+}
+
+func VerficationCooldownRemove() error {
+ query := `delete from verificationcooldown where time < 1`
+ _, err := config.DB.Exec(query)
+
+ return MakeError(err, "VerficationCooldownRemove")
+}
+
+func VerifyCooldownCurrent(auth string) (VerifyCooldown, error) {
+ var current VerifyCooldown
+
+ query := `select identifier, code, time from verificationcooldown where code=$1`
+ if err := config.DB.QueryRow(query, auth).Scan(&current.Identifier, &current.Code, &current.Time); err != nil {
+ query := `select identifier, code, time from verificationcooldown where identifier=$1`
+ if err := config.DB.QueryRow(query, auth).Scan(&current.Identifier, &current.Code, &current.Time); err != nil {
+ return current, nil
+ }
+
+ return current, nil
+ }
+
+ return current, nil
+}
+
+func GetPasswordFromSession(ctx *fiber.Ctx) (string, string) {
+ cookie := ctx.Cookies("session_token")
+ parts := strings.Split(cookie, "|")
+
+ if len(parts) > 1 {
+ return parts[0], parts[1]
+ }
+
+ return "", ""
+}
+
+func MakeCaptchas(total int) error {
+ dbtotal, err := GetCaptchaTotal()
+
+ if err != nil {
+ return MakeError(err, "MakeCaptchas")
+ }
+
+ difference := total - dbtotal
+
+ for i := 0; i < difference; i++ {
+ if err := CreateNewCaptcha(); err != nil {
+ return MakeError(err, "MakeCaptchas")
+ }
+ }
+
+ return nil
+}