Compare commits

...

79 Commits

Author SHA1 Message Date
c13b947628 Merge branch 'devel' 2025-02-03 10:44:19 +01:00
951949f98d Give an article's clone its own uuid. This fixes a bug resulting in an infinite loop of writing stuff to a file. 2025-02-03 10:44:06 +01:00
9b4a8e1890 Add error checking for every occurance of rows.Next() 2025-02-03 10:40:54 +01:00
1cf537662a Check if data is long enough to be decrypted 2025-02-03 10:40:33 +01:00
e0fa31b7a1 Merge branch 'devel' 2025-01-26 08:53:36 +01:00
344864f5b2 Correct version number 2025-01-26 08:53:06 +01:00
09350bab0e Stop trying to use docker, it sucks 2025-01-25 19:47:03 +01:00
722022faec Update atom dependency 2025-01-24 23:19:18 +01:00
586b1cdef0 Update dependencies 2025-01-24 20:26:02 +01:00
1f72891896 Fix mariadb version 2025-01-24 20:24:32 +01:00
11d836dd26 Use DB_PASS for root and regular password 2025-01-24 20:10:32 +01:00
57953b2cfd Fix htmx version 2025-01-24 20:09:58 +01:00
a93603eac0 Use generic /bin/sh in docker-start.sh 2025-01-24 20:09:47 +01:00
1b72f05add Fix golang and tailwind version in Dockerfile 2025-01-24 20:09:23 +01:00
2c6b15bc6d Make docker-start.sh executable 2025-01-24 18:52:00 +01:00
cafb158323 Bug fix 2025-01-24 18:40:58 +01:00
40fbb93732 Add docker-start.sh 2025-01-24 18:28:29 +01:00
b120341d78 Correct docker-compose.yml 2025-01-24 18:28:18 +01:00
095576a234 Add tailwindcss to Dockerfile 2025-01-24 18:13:13 +01:00
9199f202be Check atom feed for nil returns 2025-01-24 17:42:05 +01:00
3d08cc7612 Make background image check way more efficient 2025-01-20 20:25:50 +01:00
a7b6fb9705 Correct probably last occurance of manually set path delimeter 2025-01-19 20:41:48 +01:00
2f4d5d4c7c Correct comment 2025-01-19 20:35:35 +01:00
5b417ef87d Change ValidateSession() to SessionIsActive() which only returns a bool 2025-01-19 20:34:12 +01:00
04283d5917 Restore old way of managing session while keeping slimmed down version 2025-01-19 20:29:10 +01:00
d882daeb01 Correct command line flag for ImgDir 2025-01-19 20:15:56 +01:00
ed614026ec Merge branch 'devel' 2025-01-19 10:16:44 +01:00
87f8786c43 Merge branch 'devel' 2025-01-19 10:04:36 +01:00
acae07b8f3 Merge branch 'devel' 2025-01-17 18:13:12 +01:00
1b100483de Merge branch 'devel' 2025-01-17 17:52:45 +01:00
e03fd78ea9 Merge branch 'devel' 2025-01-12 14:36:01 +01:00
370ef205a9 Merge branch 'devel' 2024-12-27 21:36:02 +01:00
d328ddb749 Merge branch 'devel' 2024-10-30 03:25:18 +01:00
5dc5590da9 Merge branch 'devel' 2024-10-30 02:24:50 +01:00
364112a0a4 Merge branch 'devel' 2024-10-30 02:14:16 +01:00
a38523e933 Merge branch 'devel' 2024-10-30 02:13:03 +01:00
200672dae2 Merge branch 'devel' 2024-10-28 18:28:31 +01:00
3d3aad88c8 Merge branch 'devel' 2024-10-28 18:27:33 +01:00
e4e43d1a83 Merge branch 'devel' 2024-10-28 18:02:56 +01:00
737a9ec314 Merge branch 'devel' 2024-10-27 15:29:50 +01:00
1ebe0380ee Merge branch 'devel' 2024-10-27 15:28:22 +01:00
d62d71b5d1 Merge branch 'devel' 2024-10-27 15:14:11 +01:00
b36e0ea503 Merge branch 'devel' 2024-10-04 16:06:57 +02:00
bc4d8fa37e Merge branch 'devel' 2024-09-28 13:59:34 +02:00
d2b21e7405 Merge branch 'devel' 2024-09-28 12:36:46 +02:00
e3c192359f Merge branch 'devel' 2024-09-11 18:15:31 +02:00
46532e4c85 Merge branch 'devel' 2024-09-11 18:15:07 +02:00
c722135a56 Merge branch 'devel' 2024-09-11 17:18:42 +02:00
887fa863bc Merge branch 'devel' 2024-09-10 19:43:22 +02:00
74d71cfb6a Merge branch 'devel' 2024-09-09 22:03:43 +02:00
ca7e7cddd3 Merge branch 'devel' 2024-09-08 16:22:59 +02:00
94431a2aa9 Merge branch 'devel' 2024-09-08 16:21:38 +02:00
5b1f20c5bc Merge branch 'devel' 2024-09-08 13:36:22 +02:00
d0c566f8df Merge branch 'devel' 2024-09-01 21:14:05 +02:00
5e586aa49a Merge branch 'devel' 2024-09-01 18:51:33 +02:00
66b2743d3d Merge branch 'devel' 2024-09-01 18:48:26 +02:00
3723b2b5e6 Merge branch 'devel' 2024-09-01 18:18:18 +02:00
ce788bfd50 Merge branch 'devel' 2024-09-01 12:54:12 +02:00
230a6278cc Merge branch 'devel' 2024-09-01 12:49:30 +02:00
42d6e0c198 Merge branch 'devel' 2024-08-31 12:17:41 +02:00
e1af2979af Merge branch 'devel' 2024-08-31 11:27:15 +02:00
f6dedc6f10 Merge branch 'devel' 2024-08-31 01:43:53 +02:00
cdf0a49550 Merge branch 'devel' 2024-08-31 01:38:28 +02:00
c3c0650210 Merge branch 'devel' 2024-08-31 01:00:55 +02:00
d077f700d8 Merge branch 'devel' 2024-08-31 00:36:48 +02:00
ec752b1c66 Merge branch 'devel' 2024-08-30 23:43:12 +02:00
46aef4f12f Merge branch 'devel' 2024-08-25 10:51:35 +02:00
1b29e328cf Merge branch 'devel' 2024-08-25 06:38:55 +02:00
e50cb819f3 Merge branch 'devel' 2024-08-23 21:45:30 +02:00
c32e38ca10 Merge branch 'devel' 2024-08-23 20:57:11 +02:00
d7c8c7a43a Merge branch 'devel' 2024-08-18 17:31:00 +02:00
1cd3edc90c Merge branch 'devel' 2024-08-18 12:06:29 +02:00
0e768c9f61 Merge branch 'devel' 2024-08-08 21:27:07 +02:00
1fcd775cc5 Merge branch 'devel' 2024-08-08 21:14:24 +02:00
203a1ed147 Implemented EasyMDE 2024-08-08 21:13:25 +02:00
ef1914ee5c Implemented article preview 2024-08-08 21:13:25 +02:00
084b101e31 Register f.ArticlePreviewHtmlData in init() 2024-08-08 21:13:25 +02:00
b2db128aa9 Shorten lines by referencing frontend as f and backend as b 2024-08-08 21:13:25 +02:00
081e880fb6 Change structure of code tor frontend and backend one 2024-08-08 21:13:25 +02:00
19 changed files with 183 additions and 151 deletions

View File

@ -12,11 +12,11 @@ args_bin = [
"-domain localhost", "-domain localhost",
"-feed tmp/cpolis.atom", "-feed tmp/cpolis.atom",
"-firebase tmp/firebase.json", "-firebase tmp/firebase.json",
"-images tmp/pics",
"-img-width 256", "-img-width 256",
"-link https://distrikt-ni-st.de", "-link https://distrikt-ni-st.de",
"-log tmp/cpolis.log", "-log tmp/cpolis.log",
"-pdfs tmp/pdfs", "-pdfs tmp/pdfs",
"-pics tmp/pics",
"-port 8080", "-port 8080",
"-title 'Freimaurer Distrikt Niedersachsen und Sachsen-Anhalt'", "-title 'Freimaurer Distrikt Niedersachsen und Sachsen-Anhalt'",
"-web web", "-web web",

View File

@ -1,11 +0,0 @@
FROM golang:latest
RUN apk add --no-cache pandoc
WORKDIR /var/www/cpolis
COPY . .
RUN go build -o cpolis cmd/main.go
CMD ["./cpolis"]

View File

@ -175,6 +175,10 @@ func (db *DB) GetCertainArticles(attribute string, value bool) ([]*Article, erro
articleList = append(articleList, article) articleList = append(articleList, article)
} }
if err = rows.Err(); err != nil {
return nil, fmt.Errorf("error iterating over rows: %v", err)
}
return articleList, nil return articleList, nil
} }
@ -243,6 +247,13 @@ func (db *DB) GetCurrentIssueArticles() ([]*Article, error) {
articleList = append(articleList, article) articleList = append(articleList, article)
} }
if err = rows.Err(); err != nil {
if rollbackErr := tx.Rollback(); rollbackErr != nil {
log.Fatalf("transaction error: %v, rollback error: %v", err, rollbackErr)
}
return nil, fmt.Errorf("error iterating over rows: %v", err)
}
if err = tx.Commit(); err != nil { if err = tx.Commit(); err != nil {
return nil, fmt.Errorf("error committing transaction when getting articles of issue %v: %v", issueID, err) return nil, fmt.Errorf("error committing transaction when getting articles of issue %v: %v", issueID, err)
} }

View File

@ -68,6 +68,10 @@ func (db *DB) GetArticleAuthors(c *Config, articleID int64) ([]*User, error) {
authors = append(authors, author) authors = append(authors, author)
} }
if err = rows.Err(); err != nil {
return nil, fmt.Errorf("error iterating over rows: %v", err)
}
return authors, nil return authors, nil
} }

View File

@ -68,6 +68,10 @@ func (db *DB) GetArticleContributors(c *Config, articleID int64) ([]*User, error
contributors = append(contributors, contributor) contributors = append(contributors, contributor)
} }
if err = rows.Err(); err != nil {
return nil, fmt.Errorf("error iterating over rows: %v", err)
}
return contributors, nil return contributors, nil
} }

View File

@ -61,6 +61,10 @@ func (db *DB) GetArticleTags(articleID int64) ([]*Tag, error) {
tags = append(tags, tag) tags = append(tags, tag)
} }
if err = rows.Err(); err != nil {
return nil, fmt.Errorf("error iterating over rows: %v", err)
}
return tags, nil return tags, nil
} }

View File

@ -1,6 +1,7 @@
package backend package backend
import ( import (
"errors"
"fmt" "fmt"
"io" "io"
"os" "os"
@ -12,6 +13,9 @@ func GenerateAtomFeed(c *Config, db *DB) (*string, error) {
feed := atom.NewFeed(c.Title) feed := atom.NewFeed(c.Title)
feed.ID = atom.NewID("urn:feed:1") feed.ID = atom.NewID("urn:feed:1")
feed.Subtitle = atom.NewText("text", c.Description) feed.Subtitle = atom.NewText("text", c.Description)
if feed.Subtitle == nil {
return nil, errors.New("feed subtitle was not created")
}
linkID := feed.AddLink(atom.NewLink(c.Link)) linkID := feed.AddLink(atom.NewLink(c.Link))
feed.Links[linkID].Rel = "self" feed.Links[linkID].Rel = "self"
@ -34,15 +38,24 @@ func GenerateAtomFeed(c *Config, db *DB) (*string, error) {
entry.ID = atom.NewID(fmt.Sprint("urn:entry:", article.ID)) entry.ID = atom.NewID(fmt.Sprint("urn:entry:", article.ID))
entry.Published = atom.NewDate(article.Created) entry.Published = atom.NewDate(article.Created)
entry.Content = atom.NewContent(atom.OutOfLine, "text/html", fmt.Sprint(c.Domain, "/article/serve/", article.UUID)) entry.Content = atom.NewContent(atom.OutOfLine, "text/html", fmt.Sprint(c.Domain, "/article/serve/", article.UUID))
if entry.Content == nil {
return nil, errors.New("entry content was not created")
}
if article.AutoGenerated { if article.AutoGenerated {
entry.Summary = atom.NewText("text", "automatically generated") entry.Summary = atom.NewText("text", "automatically generated")
if entry.Summary == nil {
return nil, errors.New("entry summary was not created")
}
} else { } else {
articleSummary, err := ConvertToPlain(article.Summary) articleSummary, err := ConvertToPlain(article.Summary)
if err != nil { if err != nil {
return nil, fmt.Errorf("error converting description to plain text for Atom feed: %v", err) return nil, fmt.Errorf("error converting description to plain text for Atom feed: %v", err)
} }
entry.Summary = atom.NewText("text", articleSummary) entry.Summary = atom.NewText("text", articleSummary)
if entry.Summary == nil {
return nil, errors.New("entry summary was not created")
}
} }
if len(article.BannerLink) > 0 { if len(article.BannerLink) > 0 {

View File

@ -52,7 +52,7 @@ func newConfig() *Config {
MaxImgWidth: 1920, MaxImgWidth: 1920,
PDFDir: "/var/www/cpolis/pdfs", PDFDir: "/var/www/cpolis/pdfs",
Port: ":1664", Port: ":1664",
Version: "v0.16.0", Version: "v0.15.4",
WebDir: "/var/www/cpolis/web", WebDir: "/var/www/cpolis/web",
} }
} }
@ -113,7 +113,7 @@ func (c *Config) handleCliArgs() error {
flag.StringVar(&c.Description, "desc", c.Description, "channel description") flag.StringVar(&c.Description, "desc", c.Description, "channel description")
flag.StringVar(&c.Domain, "domain", c.Domain, "domain name") flag.StringVar(&c.Domain, "domain", c.Domain, "domain name")
flag.StringVar(&c.FirebaseKey, "firebase", c.FirebaseKey, "Firebase service account key file") flag.StringVar(&c.FirebaseKey, "firebase", c.FirebaseKey, "Firebase service account key file")
flag.StringVar(&c.ImgDir, "pics", c.ImgDir, "pictures directory") flag.StringVar(&c.ImgDir, "images", c.ImgDir, "images directory")
flag.StringVar(&c.Link, "link", c.Link, "channel Link") flag.StringVar(&c.Link, "link", c.Link, "channel Link")
flag.StringVar(&c.LogFile, "log", c.LogFile, "log file") flag.StringVar(&c.LogFile, "log", c.LogFile, "log file")
flag.StringVar(&c.PDFDir, "pdfs", c.PDFDir, "pdf directory") flag.StringVar(&c.PDFDir, "pdfs", c.PDFDir, "pdf directory")

View File

@ -33,7 +33,7 @@ func ConvertToMarkdown(c *Config, filename string) ([]byte, error) {
return nil, fmt.Errorf("error reading markdown file: %v", err) return nil, fmt.Errorf("error reading markdown file: %v", err)
} }
imageNames, err := filepath.Glob(filepath.Join(tmpDir, "/media/*")) imageNames, err := filepath.Glob(filepath.Join(tmpDir, "media", "*"))
if err != nil { if err != nil {
return nil, fmt.Errorf("error getting docx images from temporary directory: %v", err) return nil, fmt.Errorf("error getting docx images from temporary directory: %v", err)
} }

View File

@ -17,6 +17,53 @@ import (
var ErrUnsupportedFormat error = image.ErrFormat // used internally by imaging var ErrUnsupportedFormat error = image.ErrFormat // used internally by imaging
func checkImageUsage(c *Config, db *DB, name string) (bool, error) {
imageWasFound := false
if err := filepath.Walk(c.ArticleDir, func(path string, info fs.FileInfo, err error) error {
if err != nil {
return fmt.Errorf("error walking articles filepath: %v", err)
}
if !info.IsDir() {
mdFile, err := os.Open(path)
if err != nil {
return fmt.Errorf("error opening article %v: %v", info.Name(), err)
}
defer mdFile.Close()
scanner := bufio.NewScanner(mdFile)
for scanner.Scan() {
if strings.Contains(scanner.Text(), name) {
imageWasFound = true
return nil
}
}
return scanner.Err()
}
return nil
}); err != nil {
return false, fmt.Errorf("error walking articles filepath: %v", err)
}
if !imageWasFound {
users, err := db.GetAllUsers(c)
if err != nil {
return false, fmt.Errorf("error getting all users: %v", err)
}
for _, user := range users {
if name == user.ProfilePicLink {
return true, nil
}
}
}
return imageWasFound, nil
}
func SaveImage(src io.Reader, maxHeight, maxWidth int, path string) (string, error) { func SaveImage(src io.Reader, maxHeight, maxWidth int, path string) (string, error) {
img, err := imaging.Decode(src, imaging.AutoOrientation(true)) img, err := imaging.Decode(src, imaging.AutoOrientation(true))
if err != nil { if err != nil {
@ -56,45 +103,10 @@ func CleanUpImages(c *Config, db *DB) error {
if !info.IsDir() { if !info.IsDir() {
imageName := info.Name() imageName := info.Name()
imagePath := path imagePath := path
imageWasFound := false
if err = filepath.Walk(c.ArticleDir, func(path string, info fs.FileInfo, err error) error { imageWasFound, err := checkImageUsage(c, db, imageName)
if err != nil {
return fmt.Errorf("error walking articles filepath: %v", err)
}
if !info.IsDir() {
mdFile, err := os.Open(path)
if err != nil {
return fmt.Errorf("error opening article %v: %v", info.Name(), err)
}
defer mdFile.Close()
scanner := bufio.NewScanner(mdFile)
for scanner.Scan() {
if strings.Contains(scanner.Text(), imageName) {
imageWasFound = true
}
}
return scanner.Err()
}
return nil
}); err != nil {
return fmt.Errorf("error walking articles filepath: %v", err)
}
users, err := db.GetAllUsers(c)
if err != nil { if err != nil {
return fmt.Errorf("error getting all users: %v", err) return fmt.Errorf("error checking image usage: %v", err)
}
for _, user := range users {
if imageName == user.ProfilePicLink {
imageWasFound = true
}
} }
if !imageWasFound { if !imageWasFound {

View File

@ -31,5 +31,9 @@ func (db *DB) GetTagList() ([]*Tag, error) {
tagList = append(tagList, tag) tagList = append(tagList, tag)
} }
if err = rows.Err(); err != nil {
return nil, fmt.Errorf("error iterating over rows: %v", err)
}
return tagList, nil return tagList, nil
} }

View File

@ -117,6 +117,9 @@ func aesDecrypt(c *Config, ciphertext string) (string, error) {
} }
nonceSize := gcm.NonceSize() nonceSize := gcm.NonceSize()
if len(data) < nonceSize {
return "", errors.New("ciphertext too short")
}
nonce, cipherText := data[:nonceSize], data[nonceSize:] nonce, cipherText := data[:nonceSize], data[nonceSize:]
plaintext, err := gcm.Open(nil, nonce, cipherText, nil) plaintext, err := gcm.Open(nil, nonce, cipherText, nil)
@ -450,8 +453,6 @@ func (db *DB) AddFirstUser(c *Config, u *User, pass string) (int64, error) {
func (db *DB) GetAllUsers(c *Config) ([]*User, error) { func (db *DB) GetAllUsers(c *Config) ([]*User, error) {
var aesFirstName, aesLastName, aesEmail string var aesFirstName, aesLastName, aesEmail string
var err error
query := "SELECT id, username, first_name, last_name, email, profile_pic_link, role FROM users" query := "SELECT id, username, first_name, last_name, email, profile_pic_link, role FROM users"
rows, err := db.Query(query) rows, err := db.Query(query)
@ -484,6 +485,10 @@ func (db *DB) GetAllUsers(c *Config) ([]*User, error) {
users = append(users, user) users = append(users, user)
} }
if err = rows.Err(); err != nil {
return nil, fmt.Errorf("error iterating over rows: %v", err)
}
return users, nil return users, nil
} }
@ -523,6 +528,10 @@ func (db *DB) GetAllUsersMap(c *Config) (map[int64]*User, error) {
users[user.ID] = user users[user.ID] = user
} }
if err = rows.Err(); err != nil {
return nil, fmt.Errorf("error iterating over rows: %v", err)
}
return users, nil return users, nil
} }

View File

@ -10,7 +10,7 @@ import (
func ServeImage(c *b.Config, s map[string]*f.Session) http.HandlerFunc { func ServeImage(c *b.Config, s map[string]*f.Session) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
if _, err := f.ValidateSession(w, r, c, s); err != nil { if !f.SessionIsActive(r, s) {
if !tokenIsVerified(w, r, c) { if !tokenIsVerified(w, r, c) {
return return
} }

View File

@ -901,6 +901,7 @@ func AllowEditArticle(c *b.Config, db *b.DB, s map[string]*Session) http.Handler
} }
newArticle := *oldArticle newArticle := *oldArticle
newArticle.UUID = uuid.New()
newArticle.Published = false newArticle.Published = false
newArticle.Rejected = true newArticle.Rejected = true
newArticle.EditedID = oldArticle.ID newArticle.EditedID = oldArticle.ID

View File

@ -64,39 +64,43 @@ func StartSessions() (map[string]*Session, chan string) {
return sessions, sessionExpiryChan return sessions, sessionExpiryChan
} }
// ValidateSession is used for verifying that the user is logged in and returns // SessionIsActive is used for verifying that the user is logged in and returns
// their session and an error. // a bool.
func ValidateSession(w http.ResponseWriter, r *http.Request, c *b.Config, s map[string]*Session) (*Session, error) { func SessionIsActive(r *http.Request, s map[string]*Session) bool {
cookie, err := r.Cookie("cpolis_session") cookie, err := r.Cookie("cpolis_session")
if err != nil { if err != nil {
return nil, errors.New("no cookie set") return false
} }
session, ok := s[cookie.Value] _, ok := s[cookie.Value]
if !ok { return ok
return nil, errors.New("session does not exist")
}
return session, nil
} }
// ManageSession is used for verifying that the user is logged in and returns // ManageSession is used for verifying that the user is logged in and returns
// their session and an error. It also handles cases where the user is not // their session and an error. It also handles cases where the user is not
// logged in. // logged in.
func ManageSession(w http.ResponseWriter, r *http.Request, c *b.Config, s map[string]*Session) (*Session, error) { func ManageSession(w http.ResponseWriter, r *http.Request, c *b.Config, s map[string]*Session) (*Session, error) {
session, err := ValidateSession(w, r, c, s) tmpl, tmplErr := template.ParseFiles(filepath.Join(c.WebDir, "templates", "index.html"), filepath.Join(c.WebDir, "templates", "login.html"))
if err != nil {
if session.cookie != nil {
session.cookie.Expires = time.Now()
http.SetCookie(w, session.cookie)
}
tmpl, tmplErr := template.ParseFiles(filepath.Join(c.WebDir, "templates", "index.html"), filepath.Join(c.WebDir, "templates", "login.html")) cookie, err := r.Cookie("cpolis_session")
if err != nil {
if err = template.Must(tmpl, tmplErr).ExecuteTemplate(w, "page-content", nil); err != nil { if err = template.Must(tmpl, tmplErr).ExecuteTemplate(w, "page-content", nil); err != nil {
return nil, fmt.Errorf("error executing template: %v", err) return nil, fmt.Errorf("error executing template: %v", err)
} }
return nil, err return nil, errors.New("no cookie set")
}
session, ok := s[cookie.Value]
if !ok {
cookie.Expires = time.Now()
http.SetCookie(w, cookie)
if err = template.Must(tmpl, tmplErr).ExecuteTemplate(w, "page-content", nil); err != nil {
return nil, fmt.Errorf("error executing template: %v", err)
}
return nil, errors.New("session does not exist")
} }
session.cookie.Expires = time.Now().Add(time.Hour * time.Duration(c.CookieExpiryHours)) session.cookie.Expires = time.Now().Add(time.Hour * time.Duration(c.CookieExpiryHours))

View File

@ -1,23 +0,0 @@
services:
app:
build: .
ports:
- "1664:1664"
volumes:
- /etc/cpolis/config.toml:/etc/cpolis/config.toml
- /etc/cpolis/serviceAccountKey.json:/etc/cpolis/serviceAccountKey.json
- /var/log/cpolis.log:/var/log/cpolis.log
depends_on:
- db
db:
image: mariadb:latest
environment:
MYSQL_ROOT_PASSWORD: example
MYSQL_DATABASE: cpolis
MYSQL_USER: exampleuser
MYSQL_PASSWORD: examplepass
ports:
- "3306:3306"
volumes:
- ./create_db.sql:/docker-entrypoint-initdb.d/create_db.sql

36
go.mod
View File

@ -4,7 +4,7 @@ go 1.23.2
require ( require (
firebase.google.com/go/v4 v4.15.1 firebase.google.com/go/v4 v4.15.1
git.streifling.com/jason/atom v1.0.0 git.streifling.com/jason/atom v1.0.1
github.com/BurntSushi/toml v1.4.0 github.com/BurntSushi/toml v1.4.0
github.com/chai2010/webp v1.1.1 github.com/chai2010/webp v1.1.1
github.com/disintegration/imaging v1.6.2 github.com/disintegration/imaging v1.6.2
@ -15,7 +15,7 @@ require (
github.com/yuin/goldmark v1.7.8 github.com/yuin/goldmark v1.7.8
golang.org/x/crypto v0.32.0 golang.org/x/crypto v0.32.0
golang.org/x/term v0.28.0 golang.org/x/term v0.28.0
google.golang.org/api v0.216.0 google.golang.org/api v0.218.0
) )
require ( require (
@ -27,7 +27,7 @@ require (
cloud.google.com/go/firestore v1.18.0 // indirect cloud.google.com/go/firestore v1.18.0 // indirect
cloud.google.com/go/iam v1.3.1 // indirect cloud.google.com/go/iam v1.3.1 // indirect
cloud.google.com/go/longrunning v0.6.4 // indirect cloud.google.com/go/longrunning v0.6.4 // indirect
cloud.google.com/go/monitoring v1.22.1 // indirect cloud.google.com/go/monitoring v1.23.0 // indirect
cloud.google.com/go/storage v1.50.0 // indirect cloud.google.com/go/storage v1.50.0 // indirect
filippo.io/edwards25519 v1.1.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 // indirect
@ -36,9 +36,9 @@ require (
github.com/MicahParks/keyfunc v1.9.0 // indirect github.com/MicahParks/keyfunc v1.9.0 // indirect
github.com/aymerick/douceur v0.2.0 // indirect github.com/aymerick/douceur v0.2.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 // indirect github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42 // indirect
github.com/envoyproxy/go-control-plane/envoy v1.32.3 // indirect github.com/envoyproxy/go-control-plane/envoy v1.32.3 // indirect
github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
@ -51,14 +51,14 @@ require (
github.com/gorilla/css v1.0.1 // indirect github.com/gorilla/css v1.0.1 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/detectors/gcp v1.33.0 // indirect go.opentelemetry.io/contrib/detectors/gcp v1.34.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect
go.opentelemetry.io/otel v1.33.0 // indirect go.opentelemetry.io/otel v1.34.0 // indirect
go.opentelemetry.io/otel/metric v1.33.0 // indirect go.opentelemetry.io/otel/metric v1.34.0 // indirect
go.opentelemetry.io/otel/sdk v1.33.0 // indirect go.opentelemetry.io/otel/sdk v1.34.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.33.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.34.0 // indirect
go.opentelemetry.io/otel/trace v1.33.0 // indirect go.opentelemetry.io/otel/trace v1.34.0 // indirect
golang.org/x/image v0.23.0 // indirect golang.org/x/image v0.23.0 // indirect
golang.org/x/net v0.34.0 // indirect golang.org/x/net v0.34.0 // indirect
golang.org/x/oauth2 v0.25.0 // indirect golang.org/x/oauth2 v0.25.0 // indirect
@ -67,9 +67,9 @@ require (
golang.org/x/text v0.21.0 // indirect golang.org/x/text v0.21.0 // indirect
golang.org/x/time v0.9.0 // indirect golang.org/x/time v0.9.0 // indirect
google.golang.org/appengine/v2 v2.0.6 // indirect google.golang.org/appengine/v2 v2.0.6 // indirect
google.golang.org/genproto v0.0.0-20250106144421-5f5ef82da422 // indirect google.golang.org/genproto v0.0.0-20250124145028-65684f501c47 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250124145028-65684f501c47 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250106144421-5f5ef82da422 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250124145028-65684f501c47 // indirect
google.golang.org/grpc v1.69.2 // indirect google.golang.org/grpc v1.70.0 // indirect
google.golang.org/protobuf v1.36.2 // indirect google.golang.org/protobuf v1.36.4 // indirect
) )

72
go.sum
View File

@ -16,8 +16,8 @@ cloud.google.com/go/logging v1.13.0 h1:7j0HgAp0B94o1YRDqiqm26w4q1rDMH7XNRU34lJXH
cloud.google.com/go/logging v1.13.0/go.mod h1:36CoKh6KA/M0PbhPKMq6/qety2DCAErbhXT62TuXALA= cloud.google.com/go/logging v1.13.0/go.mod h1:36CoKh6KA/M0PbhPKMq6/qety2DCAErbhXT62TuXALA=
cloud.google.com/go/longrunning v0.6.4 h1:3tyw9rO3E2XVXzSApn1gyEEnH2K9SynNQjMlBi3uHLg= cloud.google.com/go/longrunning v0.6.4 h1:3tyw9rO3E2XVXzSApn1gyEEnH2K9SynNQjMlBi3uHLg=
cloud.google.com/go/longrunning v0.6.4/go.mod h1:ttZpLCe6e7EXvn9OxpBRx7kZEB0efv8yBO6YnVMfhJs= cloud.google.com/go/longrunning v0.6.4/go.mod h1:ttZpLCe6e7EXvn9OxpBRx7kZEB0efv8yBO6YnVMfhJs=
cloud.google.com/go/monitoring v1.22.1 h1:KQbnAC4IAH+5x3iWuPZT5iN9VXqKMzzOgqcYB6fqPDE= cloud.google.com/go/monitoring v1.23.0 h1:M3nXww2gn9oZ/qWN2bZ35CjolnVHM3qnSbu6srCPgjk=
cloud.google.com/go/monitoring v1.22.1/go.mod h1:AuZZXAoN0WWWfsSvET1Cpc4/1D8LXq8KRDU87fMS6XY= cloud.google.com/go/monitoring v1.23.0/go.mod h1:034NnlQPDzrQ64G2Gavhl0LUHZs9H3rRmhtnp7jiJgg=
cloud.google.com/go/storage v1.50.0 h1:3TbVkzTooBvnZsk7WaAQfOsNrdoM8QHusXA1cpk6QJs= cloud.google.com/go/storage v1.50.0 h1:3TbVkzTooBvnZsk7WaAQfOsNrdoM8QHusXA1cpk6QJs=
cloud.google.com/go/storage v1.50.0/go.mod h1:l7XeiD//vx5lfqE3RavfmU9yvk5Pp0Zhcv482poyafY= cloud.google.com/go/storage v1.50.0/go.mod h1:l7XeiD//vx5lfqE3RavfmU9yvk5Pp0Zhcv482poyafY=
cloud.google.com/go/trace v1.11.3 h1:c+I4YFjxRQjvAhRmSsmjpASUKq88chOX854ied0K/pE= cloud.google.com/go/trace v1.11.3 h1:c+I4YFjxRQjvAhRmSsmjpASUKq88chOX854ied0K/pE=
@ -26,8 +26,8 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
firebase.google.com/go/v4 v4.15.1 h1:tR2dzKw1MIfCfG2bhAyxa5KQ57zcE7iFKmeYClET6ZM= firebase.google.com/go/v4 v4.15.1 h1:tR2dzKw1MIfCfG2bhAyxa5KQ57zcE7iFKmeYClET6ZM=
firebase.google.com/go/v4 v4.15.1/go.mod h1:eunxbsh4UXI2rA8po3sOiebvWYuW0DVxAdZFO0I6wdY= firebase.google.com/go/v4 v4.15.1/go.mod h1:eunxbsh4UXI2rA8po3sOiebvWYuW0DVxAdZFO0I6wdY=
git.streifling.com/jason/atom v1.0.0 h1:E88z4S7JeT6T+WuAaJWnGwCWTx+vzSJ6giUL51MdptI= git.streifling.com/jason/atom v1.0.1 h1:G1PtNt1+qlzxpwjlD6iDeseFmzoac1IYxdq9twofTFY=
git.streifling.com/jason/atom v1.0.0/go.mod h1:FNTYJfatYaIOQn4OKy8y+Mtohqm3MeyEGZUu4bMtZ9E= git.streifling.com/jason/atom v1.0.1/go.mod h1:FNTYJfatYaIOQn4OKy8y+Mtohqm3MeyEGZUu4bMtZ9E=
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 h1:3c8yed4lgqTt+oTQ+JNMDo+F4xprBf+O/il4ZC0nRLw= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 h1:3c8yed4lgqTt+oTQ+JNMDo+F4xprBf+O/il4ZC0nRLw=
@ -46,8 +46,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chai2010/webp v1.1.1 h1:jTRmEccAJ4MGrhFOrPMpNGIJ/eybIgwKpcACsrTEapk= github.com/chai2010/webp v1.1.1 h1:jTRmEccAJ4MGrhFOrPMpNGIJ/eybIgwKpcACsrTEapk=
github.com/chai2010/webp v1.1.1/go.mod h1:0XVwvZWdjjdxpUEIf7b9g9VkHFnInUSYujwqTLEuldU= github.com/chai2010/webp v1.1.1/go.mod h1:0XVwvZWdjjdxpUEIf7b9g9VkHFnInUSYujwqTLEuldU=
github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 h1:boJj011Hh+874zpIySeApCX4GeOjPl9qhRF3QuIZq+Q= github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42 h1:Om6kYQYDUk5wWbT0t0q6pvyM49i9XZAv9dDrkDA7gjk=
github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
@ -58,8 +58,8 @@ github.com/envoyproxy/go-control-plane/envoy v1.32.3 h1:hVEaommgvzTjTd4xCaFd+kEQ
github.com/envoyproxy/go-control-plane/envoy v1.32.3/go.mod h1:F6hWupPfh75TBXGKA++MCT/CZHFq5r9/uwt/kQYkZfE= github.com/envoyproxy/go-control-plane/envoy v1.32.3/go.mod h1:F6hWupPfh75TBXGKA++MCT/CZHFq5r9/uwt/kQYkZfE=
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI= github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI=
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4=
github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM= github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4= github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
@ -109,24 +109,24 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/contrib/detectors/gcp v1.33.0 h1:FVPoXEoILwgbZUu4X7YSgsESsAmGRgoYcnXkzgQPhP4= go.opentelemetry.io/contrib/detectors/gcp v1.34.0 h1:JRxssobiPg23otYU5SbWtQC//snGVIM3Tx6QRzlQBao=
go.opentelemetry.io/contrib/detectors/gcp v1.33.0/go.mod h1:ZHrLmr4ikK2AwRj9QL+c9s2SOlgoSRyMpNVzUj2fZqI= go.opentelemetry.io/contrib/detectors/gcp v1.34.0/go.mod h1:cV4BMFcscUR/ckqLkbfQmF0PRsq8w/lMGzdbCSveBHo=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 h1:PS8wXpbyaDJQ2VDHHncMe9Vct0Zn1fEjpsjrLxGJoSc= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0/go.mod h1:HDBUsEjOuRC0EzKZ1bSaRGZWUBAzo+MhAcUUORSr4D0= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I=
go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw= go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0 h1:WDdP9acbMYjbKIyJUhTvtzj601sVJOqgWdUxSdR/Ysc= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0 h1:WDdP9acbMYjbKIyJUhTvtzj601sVJOqgWdUxSdR/Ysc=
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I=
go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ= go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M= go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM= go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM= go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
go.opentelemetry.io/otel/sdk/metric v1.33.0 h1:Gs5VK9/WUJhNXZgn8MR6ITatvAmKeIuCtNbsP3JkNqU= go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
go.opentelemetry.io/otel/sdk/metric v1.33.0/go.mod h1:dL5ykHZmm1B1nVRk9dDjChwDmt81MjVp3gLkQRwKf/Q= go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
@ -170,21 +170,21 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.216.0 h1:xnEHy+xWFrtYInWPy8OdGFsyIfWJjtVnO39g7pz2BFY= google.golang.org/api v0.218.0 h1:x6JCjEWeZ9PFCRe9z0FBrNwj7pB7DOAqT35N+IPnAUA=
google.golang.org/api v0.216.0/go.mod h1:K9wzQMvWi47Z9IU7OgdOofvZuw75Ge3PPITImZR/UyI= google.golang.org/api v0.218.0/go.mod h1:5VGHBAkxrA/8EFjLVEYmMUJ8/8+gWWQ3s4cFH0FxG2M=
google.golang.org/appengine/v2 v2.0.6 h1:LvPZLGuchSBslPBp+LAhihBeGSiRh1myRoYK4NtuBIw= google.golang.org/appengine/v2 v2.0.6 h1:LvPZLGuchSBslPBp+LAhihBeGSiRh1myRoYK4NtuBIw=
google.golang.org/appengine/v2 v2.0.6/go.mod h1:WoEXGoXNfa0mLvaH5sV3ZSGXwVmy8yf7Z1JKf3J3wLI= google.golang.org/appengine/v2 v2.0.6/go.mod h1:WoEXGoXNfa0mLvaH5sV3ZSGXwVmy8yf7Z1JKf3J3wLI=
google.golang.org/genproto v0.0.0-20250106144421-5f5ef82da422 h1:6GUHKGv2huWOHKmDXLMNE94q3fBDlEHI+oTRIZSebK0= google.golang.org/genproto v0.0.0-20250124145028-65684f501c47 h1:SI8Hf7K4+uVYchXqZiMfP44PZ83xomMWovbcFfm0P8Q=
google.golang.org/genproto v0.0.0-20250106144421-5f5ef82da422/go.mod h1:1NPAxoesyw/SgLPqaUp9u1f9PWCLAk/jVmhx7gJZStg= google.golang.org/genproto v0.0.0-20250124145028-65684f501c47/go.mod h1:qbZzneIOXSq+KFAFut9krLfRLZiFLzZL5u2t8SV83EE=
google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 h1:GVIKPyP/kLIyVOgOnTwFOrvQaQUzOzGMCxgFUOEmm24= google.golang.org/genproto/googleapis/api v0.0.0-20250124145028-65684f501c47 h1:5iw9XJTD4thFidQmFVvx0wi4g5yOHk76rNRUxz1ZG5g=
google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422/go.mod h1:b6h1vNKhxaSoEI+5jc3PJUCustfli/mRab7295pY7rw= google.golang.org/genproto/googleapis/api v0.0.0-20250124145028-65684f501c47/go.mod h1:AfA77qWLcidQWywD0YgqfpJzf50w2VjzBml3TybHeJU=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250106144421-5f5ef82da422 h1:3UsHvIr4Wc2aW4brOaSCmcxh9ksica6fHEr8P1XhkYw= google.golang.org/genproto/googleapis/rpc v0.0.0-20250124145028-65684f501c47 h1:91mG8dNTpkC0uChJUQ9zCiRqx3GEEFOWaRZ0mI6Oj2I=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250106144421-5f5ef82da422/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4= google.golang.org/genproto/googleapis/rpc v0.0.0-20250124145028-65684f501c47/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU= google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU= google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -42,7 +42,7 @@
<p>{{.Version}} - <strong>Alpha: Drastische Änderungen und Fehler vorbehalten.</strong></p> <p>{{.Version}} - <strong>Alpha: Drastische Änderungen und Fehler vorbehalten.</strong></p>
</footer> </footer>
<script src="https://unpkg.com/htmx.org@latest"></script> <script src="https://unpkg.com/htmx.org@2.0.4"></script>
<script src="https://unpkg.com/easymde/dist/easymde.min.js"></script> <script src="https://unpkg.com/easymde/dist/easymde.min.js"></script>
<script> <script>
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {