mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-08-17 16:07:18 +02:00
Initial open source release
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/phishingclub/phishingclub/errs"
|
||||
)
|
||||
|
||||
func Encrypt(s string, secret string) (string, error) {
|
||||
block, err := aes.NewCipher([]byte(secret))
|
||||
if err != nil {
|
||||
return "", errs.Wrap(err)
|
||||
}
|
||||
|
||||
gcm, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
return "", errs.Wrap(err)
|
||||
}
|
||||
|
||||
nonce := make([]byte, gcm.NonceSize())
|
||||
if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
|
||||
return "", errs.Wrap(err)
|
||||
}
|
||||
|
||||
ciphertext := gcm.Seal(nonce, nonce, []byte(s), nil)
|
||||
return base64.URLEncoding.EncodeToString(ciphertext), nil
|
||||
}
|
||||
|
||||
func Decrypt(s string, secret string) (string, error) {
|
||||
block, err := aes.NewCipher([]byte(secret))
|
||||
if err != nil {
|
||||
return "", errs.Wrap(err)
|
||||
}
|
||||
|
||||
gcm, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
return "", errs.Wrap(err)
|
||||
}
|
||||
|
||||
data, err := base64.URLEncoding.DecodeString(s)
|
||||
if err != nil {
|
||||
return "", errs.Wrap(err)
|
||||
}
|
||||
|
||||
nonceSize := gcm.NonceSize()
|
||||
if len(data) < nonceSize {
|
||||
return "", errs.Wrap(err)
|
||||
}
|
||||
|
||||
nonce, ciphertext := data[:nonceSize], data[nonceSize:]
|
||||
plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
|
||||
if err != nil {
|
||||
return "", errs.Wrap(err)
|
||||
}
|
||||
|
||||
return string(plaintext), nil
|
||||
}
|
||||
|
||||
// UUIDToSecret converts a UUIDv4 to a 32 char secret string by
|
||||
// removing the '-' between the UUID parts
|
||||
func UUIDToSecret(id *uuid.UUID) string {
|
||||
return strings.ReplaceAll(id.String(), "-", "")
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func CSVRemoveFormulaStart(input string) string {
|
||||
if input == "" {
|
||||
return input
|
||||
}
|
||||
if len(input) > 0 && strings.ContainsAny(input[0:1], "=@+-") {
|
||||
return "'" + input
|
||||
}
|
||||
return input
|
||||
}
|
||||
|
||||
func CSVFromDate(d *time.Time) string {
|
||||
if d == nil {
|
||||
return ""
|
||||
}
|
||||
return CSVRemoveFormulaStart(d.Format(time.RFC3339))
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
package utils
|
||||
|
||||
// getMapKeys returns the keys of a map
|
||||
func MapKeys[T any](m map[string]T) []string {
|
||||
keys := make([]string, 0, len(m))
|
||||
for key := range m {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
return keys
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/oapi-codegen/nullable"
|
||||
)
|
||||
|
||||
// NullableToString converts a nullable stringer to a string
|
||||
func NullableToString[T fmt.Stringer](x nullable.Nullable[T]) string {
|
||||
if !x.IsSpecified() || x.IsNull() {
|
||||
return ""
|
||||
}
|
||||
return x.MustGet().String()
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{{ range . }}
|
||||
## {{ .Name }}
|
||||
|
||||
* Name: {{ .Name }}
|
||||
* Version: {{ .Version }}
|
||||
* License: [{{ .LicenseName }}]
|
||||
|
||||
```
|
||||
{{ .LicenseText }}
|
||||
```
|
||||
{{ end }}
|
||||
@@ -0,0 +1,11 @@
|
||||
package utils
|
||||
|
||||
import "path/filepath"
|
||||
|
||||
// GetSafePathWithinRoot returns a safe path within a root
|
||||
// safeRootPath is the root directory and must be a SAFE string
|
||||
// unsafePath is the path to be joined to the root and can be UNSAFE string
|
||||
// example: GetSafePathWithinRoot("/home/user", "../etc/passwd") returns "/home/user/etc/passwd"
|
||||
func GetSafePathWithinRoot(safeRootPath, unsafePath string) string {
|
||||
return filepath.Join(safeRootPath, filepath.Clean("/"+unsafePath))
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package utils
|
||||
|
||||
func SliceRemoveInt(intSlice []int, target int) []int {
|
||||
result := []int{}
|
||||
for _, num := range intSlice {
|
||||
if num != target {
|
||||
result = append(result, num)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"path"
|
||||
"strconv"
|
||||
|
||||
"github.com/phishingclub/phishingclub/errs"
|
||||
)
|
||||
|
||||
// Substring returns a substring of the input text from the start index to the end index.
|
||||
// If the start index is less than 0, it is set to 0.
|
||||
// If the end index is greater than the length of the text, it is set to the length of the text.
|
||||
func Substring(text string, start int, end int) string {
|
||||
// Validate start and end indexes (within 0 to string length)
|
||||
if start < 0 {
|
||||
start = 0
|
||||
} else if start > len(text) {
|
||||
start = len(text)
|
||||
}
|
||||
if end < 0 {
|
||||
end = 0
|
||||
} else if end > len(text) {
|
||||
end = len(text)
|
||||
}
|
||||
if start > end {
|
||||
return ""
|
||||
}
|
||||
return text[start:end]
|
||||
}
|
||||
|
||||
// MergeStringMaps merges multiple string maps into a single map by copying all key-value pairs.
|
||||
// If the same key exists in multiple maps, the last map's value will overwrite previous values.
|
||||
func MergeStringMaps(maps ...map[string]string) map[string]string {
|
||||
result := make(map[string]string)
|
||||
for _, m := range maps {
|
||||
for k, v := range m {
|
||||
result[k] = v
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// MergeStringSlices merges multiple string slices into a single slice by copying all elements.
|
||||
func MergeStringSlices(slices ...[]string) []string {
|
||||
var total int
|
||||
for _, s := range slices {
|
||||
total += len(s)
|
||||
}
|
||||
result := make([]string, 0, total)
|
||||
for _, s := range slices {
|
||||
result = append(result, s...)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// TODO maybe move this to a file utils file
|
||||
func CompareFileSizeFromString(fileSize int64, maxSizeInMB string) (bool, error) {
|
||||
maxFileSizeMB, err := strconv.Atoi(maxSizeInMB)
|
||||
if err != nil {
|
||||
return false, errs.Wrap(err)
|
||||
}
|
||||
maxSizeBytes := maxFileSizeMB * 1024 * 1024
|
||||
if fileSize > int64(maxSizeBytes) {
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// TODO maybe move this to a file utils file
|
||||
func ReadableFileName(filename string) string {
|
||||
maxLength := 24
|
||||
name := path.Base(filename)
|
||||
if len(name) <= maxLength {
|
||||
return name
|
||||
}
|
||||
|
||||
// Keep equal parts from start and end
|
||||
// Example: "very-long-filename-123.pdf" -> "very-l...123.pdf"
|
||||
ext := path.Ext(name) // gets ".pdf"
|
||||
basename := name[:len(name)-len(ext)] // removes extension
|
||||
|
||||
// Calculate how many chars to keep on each end
|
||||
// -3 for "..." and divide remaining space by 2
|
||||
keepLength := (maxLength - 3 - len(ext)) / 2
|
||||
|
||||
return basename[:keepLength] + "..." + basename[len(basename)-keepLength:] + ext
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package utils
|
||||
|
||||
import "time"
|
||||
|
||||
func RFC3339UTC(t time.Time) string {
|
||||
return t.UTC().Format(time.RFC3339Nano)
|
||||
}
|
||||
|
||||
func NowRFC3339UTC() string {
|
||||
return RFC3339UTC(time.Now())
|
||||
}
|
||||
Reference in New Issue
Block a user