apifiber/utils/utils.go

273 lines
7.1 KiB
Go

package utils
import (
"api/globals"
"api/models"
"crypto/rand"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
"math/big"
"net/http"
"strconv"
"strings"
"gopkg.in/gomail.v2"
"golang.org/x/crypto/bcrypt"
)
type Charset string
const (
Alphanumeric = Charset("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
Lowercase = Charset("abcdefghijklmnopqrstuvwxyz")
Uppercase = Charset("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
Numeric = Charset("0123456789")
SpecialCharacters = Charset("!@#$%^&*()-_=+[]{}|;:'<>,.?/~")
)
var (
GenerateString = generateString
)
type GenerationOptions struct {
Length int
DisableNumeric bool
DisableLowercase bool
DisableUppercase bool
EnableSpecialCharacter bool
CustomCharset Charset
}
// generateStringFromCharset generates a random string from a given charset
func generateStringFromCharset(charset Charset, length int) (string, error) {
if len(charset) == 0 || length <= 0 {
return "", errors.New("invalid charset or length")
}
result := make([]byte, length)
charsetLen := big.NewInt(int64(len(charset)))
for i := 0; i < length; i++ {
randomIndex, err := rand.Int(rand.Reader, charsetLen)
if err != nil {
return "", err
}
result[i] = charset[randomIndex.Int64()]
}
return string(result), nil
}
// modifyCharset modifies the charset based on the options
func modifyCharset(opts GenerationOptions, charsetMappings map[string]Charset, charset Charset) Charset {
if opts.DisableNumeric {
charset = Charset(strings.ReplaceAll(string(charset), string(charsetMappings["numeric"]), ""))
}
if opts.DisableLowercase {
charset = Charset(strings.ReplaceAll(string(charset), string(charsetMappings["lowercase"]), ""))
}
if opts.DisableUppercase {
charset = Charset(strings.ReplaceAll(string(charset), string(charsetMappings["uppercase"]), ""))
}
if opts.EnableSpecialCharacter {
charset += charsetMappings["specialCharater"]
}
return charset
}
// generateString generates a random string based on the options
func generateString(opts GenerationOptions) (string, error) {
charsetMappings := map[string]Charset{
"numeric": Numeric,
"lowercase": Lowercase,
"uppercase": Uppercase,
"specialCharater": SpecialCharacters,
}
charset := Alphanumeric
if opts.CustomCharset != "" {
charset = opts.CustomCharset
} else {
charset = modifyCharset(opts, charsetMappings, charset)
}
if len(charset) == 0 {
return "", errors.New("resulting charset is empty. adjust your options")
}
return generateStringFromCharset(charset, opts.Length)
}
func HashPassword(password string) ([]byte, error) {
return bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
}
func PrettyPrintJson(data interface{}) {
b, err := json.MarshalIndent(data, "", " ")
if err != nil {
fmt.Println("error:", err)
}
log.Println(string(b))
}
// IsValid checks if a CNPJ is valid
func IsValid(cnpj string) bool {
// Remove non-numeric characters
cnpj = removeNonDigits(cnpj)
if len(cnpj) != 14 || allDigitsEqual(cnpj) {
return false
}
// Validate check digits
return checkCNPJCheckDigits(cnpj)
}
// removeNonDigits removes all non-numeric characters from a string
func removeNonDigits(input string) string {
var result strings.Builder
for _, r := range input {
if r >= '0' && r <= '9' {
result.WriteRune(r)
}
}
return result.String()
}
// allDigitsEqual checks if all characters in a string are the same
func allDigitsEqual(cnpj string) bool {
for i := 1; i < len(cnpj); i++ {
if cnpj[i] != cnpj[0] {
return false
}
}
return true
}
// checkCNPJCheckDigits validates the two check digits of a CNPJ
func checkCNPJCheckDigits(cnpj string) bool {
weights1 := []int{5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2}
weights2 := []int{6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2}
// Calculate first check digit
digit1 := calculateCheckDigit(cnpj[:12], weights1)
// Calculate second check digit
digit2 := calculateCheckDigit(cnpj[:13], weights2)
// Check if the calculated digits match the actual ones
return cnpj[12] == digit1 && cnpj[13] == digit2
}
// calculateCheckDigit calculates a single check digit for a given CNPJ slice and weight array
func calculateCheckDigit(numbers string, weights []int) byte {
sum := 0
for i, weight := range weights {
num, _ := strconv.Atoi(string(numbers[i]))
sum += num * weight
}
remainder := sum % 11
if remainder < 2 {
return '0'
}
return byte('0' + (11 - remainder))
}
func GetEmpresa(cnpj string) models.Empresa {
url := "https://receitaws.com.br/v1/cnpj/" + cnpj
// Call the external URL
resp, err := http.Get(url)
if err != nil {
fmt.Println("Error fetching data:", err)
return models.Empresa{}
}
defer resp.Body.Close()
// Read the response body
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error reading response:", err)
return models.Empresa{}
}
// Parse the JSON response into the struct
var response models.Empresa
err = json.Unmarshal(body, &response)
if err != nil {
fmt.Println("Error parsing JSON:", err)
return models.Empresa{}
}
// Print the parsed response
return response
}
func SendTestEmail(email, name, message string) {
var emaildb models.Email
globals.DB.First(&emaildb, "name = ?", "TESTE-ERRO")
errText := emaildb.EmailText
errText = strings.Replace(errText, "[[ERRO]]", message, -1)
errText = strings.Replace(errText, "[[NOME]]", name, -1)
m := gomail.NewMessage()
m.SetHeader("From", "suporte@pcastlive.com")
m.SetHeader("To", email)
m.SetHeader("Subject", "Solicitação de teste da plataforma PCastLive")
m.SetBody("text/html", errText)
d := gomail.NewDialer("smtp.kinghost.net", 465, "suporte@pcastlive.com", "@407Smc837")
if err := d.DialAndSend(m); err != nil {
panic(err)
}
}
func SendTestEmailApproval(email, name, transmkey, url string) {
var emaildb models.Email
globals.DB.First(&emaildb, "name = ?", "TESTE-APROVADO")
errText := emaildb.EmailText
errText = strings.Replace(errText, "[[NOME]]", name, -1)
errText = strings.Replace(errText, "[[TRANSMKEY]]", transmkey, -1)
errText = strings.Replace(errText, "[[URL]]", url, -1)
m := gomail.NewMessage()
m.SetHeader("From", "suporte@pcastlive.com")
m.SetHeader("To", email)
m.SetHeader("Subject", "Solicitação de teste da plataforma PCastLive")
m.SetBody("text/html", errText)
d := gomail.NewDialer("smtp.kinghost.net", 465, "suporte@pcastlive.com", "@407Smc837")
if err := d.DialAndSend(m); err != nil {
panic(err)
}
}
func ParseTransmissionString(input string) (transmissionKey, password string) {
// Check if the string contains "&"
parts := strings.SplitN(input, "&", 2)
// The first part is always the transmission key
transmissionKey = parts[0]
// If there's a second part after "&", it's the password
if len(parts) > 1 {
password = parts[1]
}
return transmissionKey, password
}