Upgrade JS and Go deps versions (#517)

This commit is contained in:
Thomas Miceli
2025-10-07 16:59:37 +02:00
committed by GitHub
parent f0a596aed0
commit f653179cbf
81 changed files with 2487 additions and 6227 deletions

View File

@@ -19,7 +19,8 @@ func AESEncrypt(key, text []byte) ([]byte, error) {
if _, err = io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
}
// TODO: remove deprecated
//nolint:staticcheck
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(ciphertext[aes.BlockSize:], text)
@@ -38,7 +39,8 @@ func AESDecrypt(key, ciphertext []byte) ([]byte, error) {
iv := ciphertext[:aes.BlockSize]
ciphertext = ciphertext[aes.BlockSize:]
// TODO: remove deprecated
//nolint:staticcheck
stream := cipher.NewCFBDecrypter(block, iv)
stream.XORKeyStream(ciphertext, ciphertext)

View File

@@ -4,20 +4,21 @@ import (
"bytes"
"crypto/rand"
"encoding/base64"
"github.com/pquerna/otp/totp"
"html/template"
"image/png"
"strings"
"github.com/pquerna/otp/totp"
)
const secretSize = 16
func GenerateQRCode(username, siteUrl string, secret []byte) (string, template.URL, error, []byte) {
func GenerateQRCode(username, siteUrl string, secret []byte) (string, template.URL, []byte, error) {
var err error
if secret == nil {
secret, err = generateSecret()
if err != nil {
return "", "", err, nil
return "", "", nil, err
}
}
@@ -28,22 +29,22 @@ func GenerateQRCode(username, siteUrl string, secret []byte) (string, template.U
Secret: secret,
})
if err != nil {
return "", "", err, nil
return "", "", nil, err
}
qrcode, err := otpKey.Image(320, 240)
if err != nil {
return "", "", err, nil
return "", "", nil, err
}
var imgBytes bytes.Buffer
if err = png.Encode(&imgBytes, qrcode); err != nil {
return "", "", err, nil
return "", "", nil, err
}
qrcodeImage := template.URL("data:image/png;base64," + base64.StdEncoding.EncodeToString(imgBytes.Bytes()))
return otpKey.Secret(), qrcodeImage, nil, secret
return otpKey.Secret(), qrcodeImage, secret, nil
}
func Validate(passcode, secret string) bool {

View File

@@ -2,13 +2,14 @@ package webauthn
import (
"encoding/json"
"net/http"
"net/url"
"github.com/go-webauthn/webauthn/protocol"
"github.com/go-webauthn/webauthn/webauthn"
"github.com/rs/zerolog/log"
"github.com/thomiceli/opengist/internal/config"
"github.com/thomiceli/opengist/internal/db"
"net/http"
"net/url"
)
var webAuthn *webauthn.WebAuthn
@@ -101,7 +102,7 @@ func FinishDiscoverableLogin(jsonSession []byte, response *http.Request) (uint,
return 0, err
}
return waUser.(*user).User.ID, nil
return waUser.(*user).ID, nil
}
func BeginLogin(dbUser *db.User) (credCreation *protocol.CredentialAssertion, jsonSession []byte, err error) {

View File

@@ -20,7 +20,7 @@ const (
func GetSetting(key string) (string, error) {
var setting AdminSetting
var err error
switch db.Dialector.Name() {
switch db.Name() {
case "mysql", "sqlite":
err = db.Where("`key` = ?", key).First(&setting).Error
case "postgres":

View File

@@ -395,7 +395,7 @@ func (gist *Gist) GetForks(currentUserId uint, offset int) ([]*Gist, error) {
}
func (gist *Gist) CanWrite(user *User) bool {
return !(user == nil) && (gist.UserID == user.ID)
return user != nil && gist.UserID == user.ID
}
func (gist *Gist) InitRepository() error {

View File

@@ -16,7 +16,7 @@ type Invitation struct {
func GetAllInvitations() ([]*Invitation, error) {
var invitations []*Invitation
dialect := db.Dialector.Name()
dialect := db.Name()
query := db.Model(&Invitation{})
switch dialect {

View File

@@ -5,6 +5,7 @@ import (
"encoding/json"
"errors"
"fmt"
"gorm.io/gorm"
"gorm.io/gorm/schema"
)
@@ -29,7 +30,7 @@ func (*binaryData) GormDataType() string {
}
func (*binaryData) GormDBDataType(db *gorm.DB, _ *schema.Field) string {
switch db.Dialector.Name() {
switch db.Name() {
case "sqlite":
return "BLOB"
case "mysql":
@@ -67,7 +68,7 @@ func (*jsonData) GormDataType() string {
}
func (*jsonData) GormDBDataType(db *gorm.DB, _ *schema.Field) string {
switch db.Dialector.Name() {
switch db.Name() {
case "mysql", "sqlite":
return "JSON"
case "postgres":

View File

@@ -268,6 +268,7 @@ type UserStyleDTO struct {
RemovedLineColor string `form:"removedlinecolor" json:"removed_line_color" validate:"min=0,max=7"`
AddedLineColor string `form:"addedlinecolor" json:"added_line_color" validate:"min=0,max=7"`
GitLineColor string `form:"gitlinecolor" json:"git_line_color" validate:"min=0,max=7"`
Theme string `form:"theme" json:"theme" validate:"oneof=light dark auto"`
}
func (dto *UserStyleDTO) ToJson() string {

View File

@@ -2,8 +2,9 @@ package db
import (
"encoding/hex"
"github.com/go-webauthn/webauthn/webauthn"
"time"
"github.com/go-webauthn/webauthn/webauthn"
)
type WebAuthnCredential struct {
@@ -67,7 +68,7 @@ func GetUserByCredentialID(credID binaryData) (*User, error) {
var credential WebAuthnCredential
var err error
switch db.Dialector.Name() {
switch db.Name() {
case "postgres":
hexCredID := hex.EncodeToString(credID)
if err = db.Preload("User").Where("credential_id = decode(?, 'hex')", hexCredID).First(&credential).Error; err != nil {
@@ -93,7 +94,7 @@ func GetCredentialByID(id binaryData) (*WebAuthnCredential, error) {
var cred WebAuthnCredential
var err error
switch db.Dialector.Name() {
switch db.Name() {
case "postgres":
hexCredID := hex.EncodeToString(id)
if err = db.Where("credential_id = decode(?, 'hex')", hexCredID).First(&cred).Error; err != nil {

View File

@@ -50,9 +50,10 @@ func (store *LocaleStore) loadLocaleFromYAML(localeCode, path string) error {
}
name := display.Self.Name(tag)
if tag == language.AmericanEnglish {
switch tag {
case language.AmericanEnglish:
name = "English"
} else if tag == language.EuropeanSpanish {
case language.EuropeanSpanish:
name = "Español"
}

View File

@@ -165,6 +165,10 @@ settings.style.removed-lines-color: Removed lines color
settings.style.added-lines-color: Added lines color
settings.style.git-lines-color: Git lines color
settings.style.save-style: Save style
settings.style.theme: Theme
settings.style.theme-light: Light
settings.style.theme-dark: Dark
settings.style.theme-auto: Auto
auth.signup-disabled: Administrator has disabled signing up
auth.login: Login

View File

@@ -1,12 +1,14 @@
package index
import (
"encoding/json"
"errors"
"fmt"
"github.com/meilisearch/meilisearch-go"
"github.com/rs/zerolog/log"
"strconv"
"strings"
"github.com/meilisearch/meilisearch-go"
"github.com/rs/zerolog/log"
)
type MeiliIndexer struct {
@@ -82,7 +84,8 @@ func (i *MeiliIndexer) Add(gist *Gist) error {
if gist == nil {
return errors.New("failed to add nil gist to index")
}
_, err := (*atomicIndexer.Load()).(*MeiliIndexer).index.AddDocuments(gist, "GistID")
primaryKey := "GistID"
_, err := (*atomicIndexer.Load()).(*MeiliIndexer).index.AddDocuments(gist, &primaryKey)
return err
}
@@ -127,16 +130,20 @@ func (i *MeiliIndexer) Search(queryStr string, queryMetadata SearchGistMetadata,
gistIds := make([]uint, 0, len(response.Hits))
for _, hit := range response.Hits {
if gistID, ok := hit.(map[string]interface{})["GistID"].(float64); ok {
gistIds = append(gistIds, uint(gistID))
if gistIDRaw, ok := hit["GistID"]; ok {
var gistID float64
if err := json.Unmarshal(gistIDRaw, &gistID); err == nil {
gistIds = append(gistIds, uint(gistID))
}
}
}
languageCounts := make(map[string]int)
if facets, ok := response.FacetDistribution.(map[string]interface{})["Languages"]; ok {
for language, count := range facets.(map[string]interface{}) {
if countValue, ok := count.(float64); ok {
languageCounts[language] = int(countValue)
if len(response.FacetDistribution) > 0 {
var facetDist map[string]map[string]int
if err := json.Unmarshal(response.FacetDistribution, &facetDist); err == nil {
if facets, ok := facetDist["Languages"]; ok {
languageCounts = facets
}
}
}

View File

@@ -69,7 +69,7 @@ func (ctx *Context) ErrorRes(code int, message string, err error) error {
}
func (ctx *Context) RedirectTo(location string) error {
return ctx.Context.Redirect(302, config.C.ExternalUrl+location)
return ctx.Redirect(302, config.C.ExternalUrl+location)
}
func (ctx *Context) Html(template string) error {
@@ -145,5 +145,6 @@ func (ctx *Context) Tr(key string, args ...any) string {
var ManifestEntries map[string]Asset
type Asset struct {
File string `json:"file"`
File string `json:"file"`
Css []string `json:"css"`
}

View File

@@ -1,10 +1,11 @@
package auth
import (
"net/url"
"github.com/thomiceli/opengist/internal/auth/totp"
"github.com/thomiceli/opengist/internal/db"
"github.com/thomiceli/opengist/internal/web/context"
"net/url"
)
func BeginTotp(ctx *context.Context) error {
@@ -25,7 +26,7 @@ func BeginTotp(ctx *context.Context) error {
sess := ctx.GetSession()
generatedSecret, _ := sess.Values["generatedSecret"].([]byte)
totpSecret, qrcode, err, generatedSecret := totp.GenerateQRCode(ctx.User.Username, ogUrl.Hostname(), generatedSecret)
totpSecret, qrcode, generatedSecret, err := totp.GenerateQRCode(ctx.User.Username, ogUrl.Hostname(), generatedSecret)
if err != nil {
return ctx.ErrorRes(500, "Cannot generate TOTP QR code", err)
}

View File

@@ -54,18 +54,19 @@ func AllGists(ctx *context.Context) error {
mode := ctx.GetData("mode")
if fromUserStr == "" {
if mode == "search" {
switch mode {
case "search":
ctx.SetData("htmlTitle", ctx.TrH("gist.list.search-results"))
ctx.SetData("searchQuery", ctx.QueryParam("q"))
pagination.Query = ctx.QueryParam("q")
urlPage = "search"
gists, err = db.GetAllGistsFromSearch(currentUserId, ctx.QueryParam("q"), pageInt-1, sort, order, "")
} else if mode == "topics" {
case "topics":
ctx.SetData("htmlTitle", ctx.TrH("gist.list.topic-results-topic", ctx.Param("topic")))
ctx.SetData("topic", ctx.Param("topic"))
urlPage = "topics/" + ctx.Param("topic")
gists, err = db.GetAllGistsFromSearch(currentUserId, "", pageInt-1, sort, order, ctx.Param("topic"))
} else if mode == "all" {
case "all":
ctx.SetData("htmlTitle", ctx.TrH("gist.list.all"))
urlPage = "all"
gists, err = db.GetAllGistsForCurrentUser(currentUserId, pageInt-1, sort, order)
@@ -101,15 +102,16 @@ func AllGists(ctx *context.Context) error {
ctx.SetData("countForked", countForked)
}
if mode == "liked" {
switch mode {
case "liked":
urlPage = fromUserStr + "/liked"
ctx.SetData("htmlTitle", ctx.TrH("gist.list.all-liked-by", fromUserStr))
gists, err = db.GetAllGistsLikedByUser(fromUser.ID, currentUserId, pageInt-1, sort, order)
} else if mode == "forked" {
case "forked":
urlPage = fromUserStr + "/forked"
ctx.SetData("htmlTitle", ctx.TrH("gist.list.all-forked-by", fromUserStr))
gists, err = db.GetAllGistsForkedByUser(fromUser.ID, currentUserId, pageInt-1, sort, order)
} else if mode == "fromUser" {
case "fromUser":
urlPage = fromUserStr
if languages, err := db.GetGistLanguagesForUser(fromUser.ID, currentUserId); err != nil {

View File

@@ -22,10 +22,7 @@ func Create(ctx *context.Context) error {
}
func ProcessCreate(ctx *context.Context) error {
isCreate := false
if ctx.Request().URL.Path == "/" {
isCreate = true
}
isCreate := ctx.Request().URL.Path == "/"
err := ctx.Request().ParseForm()
if err != nil {
@@ -151,7 +148,7 @@ func ProcessCreate(ctx *context.Context) error {
if err != nil {
return ctx.ErrorRes(500, "Error creating an UUID", err)
}
gist.Uuid = strings.Replace(uuidGist.String(), "-", "", -1)
gist.Uuid = strings.ReplaceAll(uuidGist.String(), "-", "")
gist.UserID = user.ID
gist.User = *user

View File

@@ -2,12 +2,13 @@ package gist
import (
"errors"
"strings"
"github.com/google/uuid"
"github.com/thomiceli/opengist/internal/db"
"github.com/thomiceli/opengist/internal/web/context"
"github.com/thomiceli/opengist/internal/web/handlers"
"gorm.io/gorm"
"strings"
)
func Fork(ctx *context.Context) error {
@@ -34,7 +35,7 @@ func Fork(ctx *context.Context) error {
}
newGist := &db.Gist{
Uuid: strings.Replace(uuidGist.String(), "-", "", -1),
Uuid: strings.ReplaceAll(uuidGist.String(), "-", ""),
Title: gist.Title,
Preview: gist.Preview,
PreviewFilename: gist.PreviewFilename,

View File

@@ -97,8 +97,10 @@ func GistJson(ctx *context.Context) error {
}
func GistJs(ctx *context.Context) error {
theme := "light"
if _, exists := ctx.QueryParams()["dark"]; exists {
ctx.SetData("dark", "dark")
theme = "dark"
}
gist := ctx.GetData("gist").(*db.Gist)
@@ -117,16 +119,21 @@ func GistJs(ctx *context.Context) error {
}
_ = w.Flush()
cssUrl, err := url.JoinPath(ctx.GetData("baseHttpUrl").(string), context.ManifestEntries["embed.css"].File)
cssUrl, err := url.JoinPath(ctx.GetData("baseHttpUrl").(string), context.ManifestEntries["ts/embed.ts"].Css[0])
if err != nil {
return ctx.ErrorRes(500, "Error joining css url", err)
}
js, err := escapeJavaScriptContent(htmlbuf.String(), cssUrl)
themeUrl, err := url.JoinPath(ctx.GetData("baseHttpUrl").(string), context.ManifestEntries["ts/"+theme+".ts"].Css[0])
if err != nil {
return ctx.ErrorRes(500, "Error joining theme url", err)
}
js, err := escapeJavaScriptContent(htmlbuf.String(), cssUrl, themeUrl)
if err != nil {
return ctx.ErrorRes(500, "Error escaping JavaScript content", err)
}
ctx.Response().Header().Set("Content-Type", "application/javascript")
ctx.Response().Header().Set("Content-Type", "text/javascript")
return ctx.PlainText(200, js)
}
@@ -141,7 +148,7 @@ func Preview(ctx *context.Context) error {
return ctx.PlainText(200, previewStr)
}
func escapeJavaScriptContent(htmlContent, cssUrl string) (string, error) {
func escapeJavaScriptContent(htmlContent, cssUrl, themeUrl string) (string, error) {
jsonContent, err := gojson.Marshal(htmlContent)
if err != nil {
return "", fmt.Errorf("failed to encode content: %w", err)
@@ -152,11 +159,18 @@ func escapeJavaScriptContent(htmlContent, cssUrl string) (string, error) {
return "", fmt.Errorf("failed to encode CSS URL: %w", err)
}
jsonThemeUrl, err := gojson.Marshal(themeUrl)
if err != nil {
return "", fmt.Errorf("failed to encode Theme URL: %w", err)
}
js := fmt.Sprintf(`
document.write('<link rel="stylesheet" href=%s>');
document.write('<link rel="stylesheet" href=%s>');
document.write(%s);
`,
string(jsonCssUrl),
string(jsonThemeUrl),
string(jsonContent),
)

View File

@@ -231,7 +231,7 @@ func createGist(user *db.User, url string) (*db.Gist, error) {
if err != nil {
return nil, err
}
gist.Uuid = strings.Replace(uuidGist.String(), "-", "", -1)
gist.Uuid = strings.ReplaceAll(uuidGist.String(), "-", "")
gist.Title = "gist:" + gist.Uuid
if url != "" {

View File

@@ -92,6 +92,12 @@ func (s *Server) setFuncMap() {
}
return config.C.ExternalUrl + "/" + context.ManifestEntries[file].File
},
"assetCss": func(file string) string {
if s.dev {
return "http://localhost:16157/" + file
}
return config.C.ExternalUrl + "/" + context.ManifestEntries[file].Css[0]
},
"custom": func(file string) string {
assetpath, err := url.JoinPath("/", "assets", file)
if err != nil {
@@ -186,6 +192,17 @@ func (s *Server) setFuncMap() {
"humanDate": func(t int64) string {
return time.Unix(t, 0).Format("02/01/2006 15:04")
},
"mainTheme": func(theme *db.UserStyleDTO) string {
if theme == nil {
return "auto"
}
if theme.Theme == "" {
return "auto"
}
return theme.Theme
},
}
t := template.Must(template.New("t").Funcs(fm).ParseFS(templates.Files, "*/*.html"))
@@ -206,7 +223,7 @@ func (s *Server) setFuncMap() {
}
func (s *Server) parseManifestEntries() {
file, err := public.Files.Open("manifest.json")
file, err := public.Files.Open(".vite/manifest.json")
if err != nil {
log.Fatal().Err(err).Msg("Failed to open manifest.json")
}