diff --git a/.eslintrc.yaml b/.eslintrc.yaml
index 5fd0a245f2..3e4c6ea50b 100644
--- a/.eslintrc.yaml
+++ b/.eslintrc.yaml
@@ -318,7 +318,7 @@ rules:
jquery/no-serialize: [2]
jquery/no-show: [2]
jquery/no-size: [2]
- jquery/no-sizzle: [0]
+ jquery/no-sizzle: [2]
jquery/no-slide: [0]
jquery/no-submit: [0]
jquery/no-text: [0]
@@ -470,7 +470,7 @@ rules:
no-jquery/no-selector-prop: [2]
no-jquery/no-serialize: [2]
no-jquery/no-size: [2]
- no-jquery/no-sizzle: [0]
+ no-jquery/no-sizzle: [2]
no-jquery/no-slide: [2]
no-jquery/no-sub: [2]
no-jquery/no-support: [2]
diff --git a/.gitattributes b/.gitattributes
index 467b8a47b5..9fb4a4e83d 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,5 +1,6 @@
* text=auto eol=lf
*.tmpl linguist-language=Handlebars
+*.pb.go linguist-generated
/assets/*.json linguist-generated
/public/assets/img/svg/*.svg linguist-generated
/templates/swagger/v1_json.tmpl linguist-generated
diff --git a/.golangci.yml b/.golangci.yml
index 5be2cefe44..27fee20f75 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -86,6 +86,8 @@ linters-settings:
desc: do not use the internal package, use AddXxx function instead
- pkg: gopkg.in/ini.v1
desc: do not use the ini package, use gitea's config system instead
+ - pkg: gitea.com/go-chi/cache
+ desc: do not use the go-chi cache package, use gitea's cache system
issues:
max-issues-per-linter: 0
diff --git a/Makefile b/Makefile
index f1acfbc81e..594f13ead8 100644
--- a/Makefile
+++ b/Makefile
@@ -295,7 +295,7 @@ clean:
.PHONY: fmt
fmt:
- GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -w '{file-list}'
+ @GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -w '{file-list}'
$(eval TEMPLATES := $(shell find templates -type f -name '*.tmpl'))
@# strip whitespace after '{{' or '(' and before '}}' or ')' unless there is only
@# whitespace before it
diff --git a/build/code-batch-process.go b/build/code-batch-process.go
index b3ee399420..cc2ab68026 100644
--- a/build/code-batch-process.go
+++ b/build/code-batch-process.go
@@ -69,6 +69,7 @@ func newFileCollector(fileFilter string, batchSize int) (*fileCollector, error)
co.includePatterns = append(co.includePatterns, regexp.MustCompile(`.*\.go$`))
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`.*\bbindata\.go$`))
+ co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`\.pb\.go$`))
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`tests/gitea-repositories-meta`))
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`tests/integration/migration-test`))
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`modules/git/tests`))
@@ -203,17 +204,6 @@ Example:
`, "file-batch-exec")
}
-func getGoVersion() string {
- goModFile, err := os.ReadFile("go.mod")
- if err != nil {
- log.Fatalf(`Faild to read "go.mod": %v`, err)
- os.Exit(1)
- }
- goModVersionRegex := regexp.MustCompile(`go \d+\.\d+`)
- goModVersionLine := goModVersionRegex.Find(goModFile)
- return string(goModVersionLine[3:])
-}
-
func newFileCollectorFromMainOptions(mainOptions map[string]string) (fc *fileCollector, err error) {
fileFilter := mainOptions["file-filter"]
if fileFilter == "" {
@@ -278,7 +268,8 @@ func main() {
log.Print("the -d option is not supported by gitea-fmt")
}
cmdErrors = append(cmdErrors, giteaFormatGoImports(files, containsString(subArgs, "-w")))
- cmdErrors = append(cmdErrors, passThroughCmd("go", append([]string{"run", os.Getenv("GOFUMPT_PACKAGE"), "-extra", "-lang", getGoVersion()}, substArgs...)))
+ cmdErrors = append(cmdErrors, passThroughCmd("gofmt", append([]string{"-w", "-r", "interface{} -> any"}, substArgs...)))
+ cmdErrors = append(cmdErrors, passThroughCmd("go", append([]string{"run", os.Getenv("GOFUMPT_PACKAGE"), "-extra"}, substArgs...)))
default:
log.Fatalf("unknown cmd: %s %v", subCmd, subArgs)
}
diff --git a/cmd/admin_user_change_password.go b/cmd/admin_user_change_password.go
index 824d66d112..bd9063a8e4 100644
--- a/cmd/admin_user_change_password.go
+++ b/cmd/admin_user_change_password.go
@@ -36,6 +36,7 @@ var microcmdUserChangePassword = &cli.Command{
&cli.BoolFlag{
Name: "must-change-password",
Usage: "User must change password",
+ Value: true,
},
},
}
@@ -57,23 +58,18 @@ func runChangePassword(c *cli.Context) error {
return err
}
- var mustChangePassword optional.Option[bool]
- if c.IsSet("must-change-password") {
- mustChangePassword = optional.Some(c.Bool("must-change-password"))
- }
-
opts := &user_service.UpdateAuthOptions{
Password: optional.Some(c.String("password")),
- MustChangePassword: mustChangePassword,
+ MustChangePassword: optional.Some(c.Bool("must-change-password")),
}
if err := user_service.UpdateAuth(ctx, user, opts); err != nil {
switch {
case errors.Is(err, password.ErrMinLength):
- return fmt.Errorf("Password is not long enough. Needs to be at least %d", setting.MinPasswordLength)
+ return fmt.Errorf("password is not long enough, needs to be at least %d characters", setting.MinPasswordLength)
case errors.Is(err, password.ErrComplexity):
- return errors.New("Password does not meet complexity requirements")
+ return errors.New("password does not meet complexity requirements")
case errors.Is(err, password.ErrIsPwned):
- return errors.New("The password you chose is on a list of stolen passwords previously exposed in public data breaches. Please try again with a different password.\nFor more details, see https://haveibeenpwned.com/Passwords")
+ return errors.New("the password is in a list of stolen passwords previously exposed in public data breaches, please try again with a different password, to see more details: https://haveibeenpwned.com/Passwords")
default:
return err
}
diff --git a/cmd/admin_user_create.go b/cmd/admin_user_create.go
index a257ce21c8..403e3ee8d8 100644
--- a/cmd/admin_user_create.go
+++ b/cmd/admin_user_create.go
@@ -8,6 +8,7 @@ import (
"fmt"
auth_model "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/models/db"
user_model "code.gitea.io/gitea/models/user"
pwd "code.gitea.io/gitea/modules/auth/password"
"code.gitea.io/gitea/modules/optional"
@@ -46,8 +47,9 @@ var microcmdUserCreate = &cli.Command{
Usage: "Generate a random password for the user",
},
&cli.BoolFlag{
- Name: "must-change-password",
- Usage: "Set this option to false to prevent forcing the user to change their password after initial login, (Default: true)",
+ Name: "must-change-password",
+ Usage: "Set to false to prevent forcing the user to change their password after initial login",
+ DisableDefaultText: true,
},
&cli.IntFlag{
Name: "random-password-length",
@@ -71,10 +73,10 @@ func runCreateUser(c *cli.Context) error {
}
if c.IsSet("name") && c.IsSet("username") {
- return errors.New("Cannot set both --name and --username flags")
+ return errors.New("cannot set both --name and --username flags")
}
if !c.IsSet("name") && !c.IsSet("username") {
- return errors.New("One of --name or --username flags must be set")
+ return errors.New("one of --name or --username flags must be set")
}
if c.IsSet("password") && c.IsSet("random-password") {
@@ -110,17 +112,21 @@ func runCreateUser(c *cli.Context) error {
return errors.New("must set either password or random-password flag")
}
- // always default to true
- changePassword := true
-
- // If this is the first user being created.
- // Take it as the admin and don't force a password update.
- if n := user_model.CountUsers(ctx, nil); n == 0 {
- changePassword = false
- }
-
+ isAdmin := c.Bool("admin")
+ mustChangePassword := true // always default to true
if c.IsSet("must-change-password") {
- changePassword = c.Bool("must-change-password")
+ // if the flag is set, use the value provided by the user
+ mustChangePassword = c.Bool("must-change-password")
+ } else {
+ // check whether there are users in the database
+ hasUserRecord, err := db.IsTableNotEmpty(&user_model.User{})
+ if err != nil {
+ return fmt.Errorf("IsTableNotEmpty: %w", err)
+ }
+ if !hasUserRecord && isAdmin {
+ // if this is the first admin being created, don't force to change password (keep the old behavior)
+ mustChangePassword = false
+ }
}
restricted := optional.None[bool]()
@@ -136,8 +142,8 @@ func runCreateUser(c *cli.Context) error {
Name: username,
Email: c.String("email"),
Passwd: password,
- IsAdmin: c.Bool("admin"),
- MustChangePassword: changePassword,
+ IsAdmin: isAdmin,
+ MustChangePassword: mustChangePassword,
Visibility: visibility,
}
diff --git a/docs/content/administration/command-line.en-us.md b/docs/content/administration/command-line.en-us.md
index 5049df35e0..752a8d4c6f 100644
--- a/docs/content/administration/command-line.en-us.md
+++ b/docs/content/administration/command-line.en-us.md
@@ -83,8 +83,7 @@ Admin operations:
- `--email value`: Email. Required.
- `--admin`: If provided, this makes the user an admin. Optional.
- `--access-token`: If provided, an access token will be created for the user. Optional. (default: false).
- - `--must-change-password`: If provided, the created user will be required to choose a newer password after the
- initial login. Optional. (default: true).
+ - `--must-change-password`: The created user will be required to set a new password after the initial login, default: true. It could be disabled by `--must-change-password=false`.
- `--random-password`: If provided, a randomly generated password will be used as the password of the created
user. The value of `--password` will be discarded. Optional.
- `--random-password-length`: If provided, it will be used to configure the length of the randomly generated
@@ -95,7 +94,7 @@ Admin operations:
- Options:
- `--username value`, `-u value`: Username. Required.
- `--password value`, `-p value`: New password. Required.
- - `--must-change-password`: If provided, the user is required to choose a new password after the login. Optional.
+ - `--must-change-password`: The user is required to set a new password after the login, default: true. It could be disabled by `--must-change-password=false`.
- Examples:
- `gitea admin user change-password --username myname --password asecurepassword`
- `must-change-password`:
diff --git a/models/auth/oauth2.go b/models/auth/oauth2.go
index 9d53fffc78..bc1bcaef63 100644
--- a/models/auth/oauth2.go
+++ b/models/auth/oauth2.go
@@ -137,6 +137,11 @@ func (app *OAuth2Application) TableName() string {
// ContainsRedirectURI checks if redirectURI is allowed for app
func (app *OAuth2Application) ContainsRedirectURI(redirectURI string) bool {
+ // OAuth2 requires the redirect URI to be an exact match, no dynamic parts are allowed.
+ // https://stackoverflow.com/questions/55524480/should-dynamic-query-parameters-be-present-in-the-redirection-uri-for-an-oauth2
+ // https://www.rfc-editor.org/rfc/rfc6819#section-5.2.3.3
+ // https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
+ // https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-12#section-3.1
contains := func(s string) bool {
s = strings.TrimSuffix(strings.ToLower(s), "/")
for _, u := range app.RedirectURIs {
diff --git a/models/db/engine.go b/models/db/engine.go
index 8684c4e2f1..26abf0b96c 100755
--- a/models/db/engine.go
+++ b/models/db/engine.go
@@ -284,8 +284,8 @@ func MaxBatchInsertSize(bean any) int {
}
// IsTableNotEmpty returns true if table has at least one record
-func IsTableNotEmpty(tableName string) (bool, error) {
- return x.Table(tableName).Exist()
+func IsTableNotEmpty(beanOrTableName any) (bool, error) {
+ return x.Table(beanOrTableName).Exist()
}
// DeleteAllRecords will delete all the records of this table
diff --git a/models/git/commit_status_summary.go b/models/git/commit_status_summary.go
index 01674e943d..7603e7aa65 100644
--- a/models/git/commit_status_summary.go
+++ b/models/git/commit_status_summary.go
@@ -15,10 +15,11 @@ import (
// CommitStatusSummary holds the latest commit Status of a single Commit
type CommitStatusSummary struct {
- ID int64 `xorm:"pk autoincr"`
- RepoID int64 `xorm:"INDEX UNIQUE(repo_id_sha)"`
- SHA string `xorm:"VARCHAR(64) NOT NULL INDEX UNIQUE(repo_id_sha)"`
- State api.CommitStatusState `xorm:"VARCHAR(7) NOT NULL"`
+ ID int64 `xorm:"pk autoincr"`
+ RepoID int64 `xorm:"INDEX UNIQUE(repo_id_sha)"`
+ SHA string `xorm:"VARCHAR(64) NOT NULL INDEX UNIQUE(repo_id_sha)"`
+ State api.CommitStatusState `xorm:"VARCHAR(7) NOT NULL"`
+ TargetURL string `xorm:"TEXT"`
}
func init() {
@@ -44,9 +45,10 @@ func GetLatestCommitStatusForRepoAndSHAs(ctx context.Context, repoSHAs []RepoSHA
commitStatuses := make([]*CommitStatus, 0, len(repoSHAs))
for _, summary := range summaries {
commitStatuses = append(commitStatuses, &CommitStatus{
- RepoID: summary.RepoID,
- SHA: summary.SHA,
- State: summary.State,
+ RepoID: summary.RepoID,
+ SHA: summary.SHA,
+ State: summary.State,
+ TargetURL: summary.TargetURL,
})
}
return commitStatuses, nil
@@ -61,22 +63,24 @@ func UpdateCommitStatusSummary(ctx context.Context, repoID int64, sha string) er
// mysql will return 0 when update a record which state hasn't been changed which behaviour is different from other database,
// so we need to use insert in on duplicate
if setting.Database.Type.IsMySQL() {
- _, err := db.GetEngine(ctx).Exec("INSERT INTO commit_status_summary (repo_id,sha,state) VALUES (?,?,?) ON DUPLICATE KEY UPDATE state=?",
- repoID, sha, state.State, state.State)
+ _, err := db.GetEngine(ctx).Exec("INSERT INTO commit_status_summary (repo_id,sha,state,target_url) VALUES (?,?,?,?) ON DUPLICATE KEY UPDATE state=?",
+ repoID, sha, state.State, state.TargetURL, state.State)
return err
}
if cnt, err := db.GetEngine(ctx).Where("repo_id=? AND sha=?", repoID, sha).
- Cols("state").
+ Cols("state, target_url").
Update(&CommitStatusSummary{
- State: state.State,
+ State: state.State,
+ TargetURL: state.TargetURL,
}); err != nil {
return err
} else if cnt == 0 {
_, err = db.GetEngine(ctx).Insert(&CommitStatusSummary{
- RepoID: repoID,
- SHA: sha,
- State: state.State,
+ RepoID: repoID,
+ SHA: sha,
+ State: state.State,
+ TargetURL: state.TargetURL,
})
return err
}
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go
index 3ea8f2acbf..5326d48f90 100644
--- a/models/migrations/migrations.go
+++ b/models/migrations/migrations.go
@@ -580,6 +580,8 @@ var migrations = []Migration{
NewMigration("Add unique index for project issue table", v1_23.AddUniqueIndexForProjectIssue),
// v295 -> v296
NewMigration("Add commit status summary table", v1_23.AddCommitStatusSummary),
+ // v296 -> v297
+ NewMigration("Add missing field of commit status summary table", v1_23.AddCommitStatusSummary2),
}
// GetCurrentDBVersion returns the current db version
diff --git a/models/migrations/v1_23/v296.go b/models/migrations/v1_23/v296.go
new file mode 100644
index 0000000000..495ae2ab23
--- /dev/null
+++ b/models/migrations/v1_23/v296.go
@@ -0,0 +1,16 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package v1_23 //nolint
+
+import "xorm.io/xorm"
+
+func AddCommitStatusSummary2(x *xorm.Engine) error {
+ type CommitStatusSummary struct {
+ ID int64 `xorm:"pk autoincr"`
+ TargetURL string `xorm:"TEXT"`
+ }
+ // there is no migrations because if there is no data on this table, it will fall back to get data
+ // from commit status
+ return x.Sync(new(CommitStatusSummary))
+}
diff --git a/modules/cache/cache.go b/modules/cache/cache.go
index 09afc8b7f7..2ca77bdb29 100644
--- a/modules/cache/cache.go
+++ b/modules/cache/cache.go
@@ -4,149 +4,75 @@
package cache
import (
- "fmt"
"strconv"
+ "time"
"code.gitea.io/gitea/modules/setting"
-
- mc "gitea.com/go-chi/cache"
-
- _ "gitea.com/go-chi/cache/memcache" // memcache plugin for cache
)
-var conn mc.Cache
-
-func newCache(cacheConfig setting.Cache) (mc.Cache, error) {
- return mc.NewCacher(mc.Options{
- Adapter: cacheConfig.Adapter,
- AdapterConfig: cacheConfig.Conn,
- Interval: cacheConfig.Interval,
- })
-}
+var defaultCache StringCache
// Init start cache service
func Init() error {
- var err error
-
- if conn == nil {
- if conn, err = newCache(setting.CacheService.Cache); err != nil {
+ if defaultCache == nil {
+ c, err := NewStringCache(setting.CacheService.Cache)
+ if err != nil {
return err
}
- if err = conn.Ping(); err != nil {
+ for i := 0; i < 10; i++ {
+ if err = c.Ping(); err == nil {
+ break
+ }
+ time.Sleep(time.Second)
+ }
+ if err != nil {
return err
}
+ defaultCache = c
}
-
- return err
+ return nil
}
// GetCache returns the currently configured cache
-func GetCache() mc.Cache {
- return conn
+func GetCache() StringCache {
+ return defaultCache
}
// GetString returns the key value from cache with callback when no key exists in cache
func GetString(key string, getFunc func() (string, error)) (string, error) {
- if conn == nil || setting.CacheService.TTL == 0 {
+ if defaultCache == nil || setting.CacheService.TTL == 0 {
return getFunc()
}
-
- cached := conn.Get(key)
-
- if cached == nil {
+ cached, exist := defaultCache.Get(key)
+ if !exist {
value, err := getFunc()
if err != nil {
return value, err
}
- return value, conn.Put(key, value, setting.CacheService.TTLSeconds())
- }
-
- if value, ok := cached.(string); ok {
- return value, nil
- }
-
- if stringer, ok := cached.(fmt.Stringer); ok {
- return stringer.String(), nil
- }
-
- return fmt.Sprintf("%s", cached), nil
-}
-
-// GetInt returns key value from cache with callback when no key exists in cache
-func GetInt(key string, getFunc func() (int, error)) (int, error) {
- if conn == nil || setting.CacheService.TTL == 0 {
- return getFunc()
- }
-
- cached := conn.Get(key)
-
- if cached == nil {
- value, err := getFunc()
- if err != nil {
- return value, err
- }
-
- return value, conn.Put(key, value, setting.CacheService.TTLSeconds())
- }
-
- switch v := cached.(type) {
- case int:
- return v, nil
- case string:
- value, err := strconv.Atoi(v)
- if err != nil {
- return 0, err
- }
- return value, nil
- default:
- value, err := getFunc()
- if err != nil {
- return value, err
- }
- return value, conn.Put(key, value, setting.CacheService.TTLSeconds())
+ return value, defaultCache.Put(key, value, setting.CacheService.TTLSeconds())
}
+ return cached, nil
}
// GetInt64 returns key value from cache with callback when no key exists in cache
func GetInt64(key string, getFunc func() (int64, error)) (int64, error) {
- if conn == nil || setting.CacheService.TTL == 0 {
- return getFunc()
+ s, err := GetString(key, func() (string, error) {
+ v, err := getFunc()
+ return strconv.FormatInt(v, 10), err
+ })
+ if err != nil {
+ return 0, err
}
-
- cached := conn.Get(key)
-
- if cached == nil {
- value, err := getFunc()
- if err != nil {
- return value, err
- }
-
- return value, conn.Put(key, value, setting.CacheService.TTLSeconds())
- }
-
- switch v := conn.Get(key).(type) {
- case int64:
- return v, nil
- case string:
- value, err := strconv.ParseInt(v, 10, 64)
- if err != nil {
- return 0, err
- }
- return value, nil
- default:
- value, err := getFunc()
- if err != nil {
- return value, err
- }
-
- return value, conn.Put(key, value, setting.CacheService.TTLSeconds())
+ if s == "" {
+ return 0, nil
}
+ return strconv.ParseInt(s, 10, 64)
}
// Remove key from cache
func Remove(key string) {
- if conn == nil {
+ if defaultCache == nil {
return
}
- _ = conn.Delete(key)
+ _ = defaultCache.Delete(key)
}
diff --git a/modules/cache/cache_redis.go b/modules/cache/cache_redis.go
index 6c358b0a78..c5b52a2086 100644
--- a/modules/cache/cache_redis.go
+++ b/modules/cache/cache_redis.go
@@ -11,7 +11,7 @@ import (
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/nosql"
- "gitea.com/go-chi/cache"
+ "gitea.com/go-chi/cache" //nolint:depguard
"github.com/redis/go-redis/v9"
)
diff --git a/modules/cache/cache_test.go b/modules/cache/cache_test.go
index 3f65040924..0c68cc26ee 100644
--- a/modules/cache/cache_test.go
+++ b/modules/cache/cache_test.go
@@ -14,7 +14,7 @@ import (
)
func createTestCache() {
- conn, _ = newCache(setting.Cache{
+ defaultCache, _ = NewStringCache(setting.Cache{
Adapter: "memory",
TTL: time.Minute,
})
@@ -25,7 +25,7 @@ func TestNewContext(t *testing.T) {
assert.NoError(t, Init())
setting.CacheService.Cache = setting.Cache{Adapter: "redis", Conn: "some random string"}
- con, err := newCache(setting.Cache{
+ con, err := NewStringCache(setting.Cache{
Adapter: "rand",
Conn: "false conf",
Interval: 100,
@@ -76,42 +76,6 @@ func TestGetString(t *testing.T) {
Remove("key")
}
-func TestGetInt(t *testing.T) {
- createTestCache()
-
- data, err := GetInt("key", func() (int, error) {
- return 0, fmt.Errorf("some error")
- })
- assert.Error(t, err)
- assert.Equal(t, 0, data)
-
- data, err = GetInt("key", func() (int, error) {
- return 0, nil
- })
- assert.NoError(t, err)
- assert.Equal(t, 0, data)
-
- data, err = GetInt("key", func() (int, error) {
- return 100, nil
- })
- assert.NoError(t, err)
- assert.Equal(t, 0, data)
- Remove("key")
-
- data, err = GetInt("key", func() (int, error) {
- return 100, nil
- })
- assert.NoError(t, err)
- assert.Equal(t, 100, data)
-
- data, err = GetInt("key", func() (int, error) {
- return 0, fmt.Errorf("some error")
- })
- assert.NoError(t, err)
- assert.Equal(t, 100, data)
- Remove("key")
-}
-
func TestGetInt64(t *testing.T) {
createTestCache()
diff --git a/modules/cache/cache_twoqueue.go b/modules/cache/cache_twoqueue.go
index f9de2563ec..1eda2debc4 100644
--- a/modules/cache/cache_twoqueue.go
+++ b/modules/cache/cache_twoqueue.go
@@ -10,7 +10,7 @@ import (
"code.gitea.io/gitea/modules/json"
- mc "gitea.com/go-chi/cache"
+ mc "gitea.com/go-chi/cache" //nolint:depguard
lru "github.com/hashicorp/golang-lru/v2"
)
diff --git a/modules/cache/string_cache.go b/modules/cache/string_cache.go
new file mode 100644
index 0000000000..4f659616f5
--- /dev/null
+++ b/modules/cache/string_cache.go
@@ -0,0 +1,120 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package cache
+
+import (
+ "errors"
+ "strings"
+
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
+
+ chi_cache "gitea.com/go-chi/cache" //nolint:depguard
+)
+
+type GetJSONError struct {
+ err error
+ cachedError string // Golang error can't be stored in cache, only the string message could be stored
+}
+
+func (e *GetJSONError) ToError() error {
+ if e.err != nil {
+ return e.err
+ }
+ return errors.New("cached error: " + e.cachedError)
+}
+
+type StringCache interface {
+ Ping() error
+
+ Get(key string) (string, bool)
+ Put(key, value string, ttl int64) error
+ Delete(key string) error
+ IsExist(key string) bool
+
+ PutJSON(key string, v any, ttl int64) error
+ GetJSON(key string, ptr any) (exist bool, err *GetJSONError)
+
+ ChiCache() chi_cache.Cache
+}
+
+type stringCache struct {
+ chiCache chi_cache.Cache
+}
+
+func NewStringCache(cacheConfig setting.Cache) (StringCache, error) {
+ adapter := util.IfZero(cacheConfig.Adapter, "memory")
+ interval := util.IfZero(cacheConfig.Interval, 60)
+ cc, err := chi_cache.NewCacher(chi_cache.Options{
+ Adapter: adapter,
+ AdapterConfig: cacheConfig.Conn,
+ Interval: interval,
+ })
+ if err != nil {
+ return nil, err
+ }
+ return &stringCache{chiCache: cc}, nil
+}
+
+func (sc *stringCache) Ping() error {
+ return sc.chiCache.Ping()
+}
+
+func (sc *stringCache) Get(key string) (string, bool) {
+ v := sc.chiCache.Get(key)
+ if v == nil {
+ return "", false
+ }
+ s, ok := v.(string)
+ return s, ok
+}
+
+func (sc *stringCache) Put(key, value string, ttl int64) error {
+ return sc.chiCache.Put(key, value, ttl)
+}
+
+func (sc *stringCache) Delete(key string) error {
+ return sc.chiCache.Delete(key)
+}
+
+func (sc *stringCache) IsExist(key string) bool {
+ return sc.chiCache.IsExist(key)
+}
+
+const cachedErrorPrefix = ":"
+
+func (sc *stringCache) PutJSON(key string, v any, ttl int64) error {
+ var s string
+ switch v := v.(type) {
+ case error:
+ s = cachedErrorPrefix + v.Error()
+ default:
+ b, err := json.Marshal(v)
+ if err != nil {
+ return err
+ }
+ s = util.UnsafeBytesToString(b)
+ }
+ return sc.chiCache.Put(key, s, ttl)
+}
+
+func (sc *stringCache) GetJSON(key string, ptr any) (exist bool, getErr *GetJSONError) {
+ s, ok := sc.Get(key)
+ if !ok || s == "" {
+ return false, nil
+ }
+ s, isCachedError := strings.CutPrefix(s, cachedErrorPrefix)
+ if isCachedError {
+ return true, &GetJSONError{cachedError: s}
+ }
+ if err := json.Unmarshal(util.UnsafeStringToBytes(s), ptr); err != nil {
+ return false, &GetJSONError{err: err}
+ }
+ return true, nil
+}
+
+func (sc *stringCache) ChiCache() chi_cache.Cache {
+ return sc.chiCache
+}
diff --git a/modules/git/last_commit_cache.go b/modules/git/last_commit_cache.go
index 5b62b90b27..cf9c10d7b4 100644
--- a/modules/git/last_commit_cache.go
+++ b/modules/git/last_commit_cache.go
@@ -7,18 +7,11 @@ import (
"crypto/sha256"
"fmt"
+ "code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
)
-// Cache represents a caching interface
-type Cache interface {
- // Put puts value into cache with key and expire time.
- Put(key string, val any, timeout int64) error
- // Get gets cached value by given key.
- Get(key string) any
-}
-
func getCacheKey(repoPath, commitID, entryPath string) string {
hashBytes := sha256.Sum256([]byte(fmt.Sprintf("%s:%s:%s", repoPath, commitID, entryPath)))
return fmt.Sprintf("last_commit:%x", hashBytes)
@@ -30,11 +23,11 @@ type LastCommitCache struct {
ttl func() int64
repo *Repository
commitCache map[string]*Commit
- cache Cache
+ cache cache.StringCache
}
// NewLastCommitCache creates a new last commit cache for repo
-func NewLastCommitCache(count int64, repoPath string, gitRepo *Repository, cache Cache) *LastCommitCache {
+func NewLastCommitCache(count int64, repoPath string, gitRepo *Repository, cache cache.StringCache) *LastCommitCache {
if cache == nil {
return nil
}
@@ -65,7 +58,7 @@ func (c *LastCommitCache) Get(ref, entryPath string) (*Commit, error) {
return nil, nil
}
- commitID, ok := c.cache.Get(getCacheKey(c.repoPath, ref, entryPath)).(string)
+ commitID, ok := c.cache.Get(getCacheKey(c.repoPath, ref, entryPath))
if !ok || commitID == "" {
return nil, nil
}
diff --git a/modules/optional/serialization.go b/modules/optional/serialization.go
index 6688e78cd1..b120a0edf6 100644
--- a/modules/optional/serialization.go
+++ b/modules/optional/serialization.go
@@ -35,7 +35,7 @@ func (o *Option[T]) UnmarshalYAML(value *yaml.Node) error {
return nil
}
-func (o Option[T]) MarshalYAML() (interface{}, error) {
+func (o Option[T]) MarshalYAML() (any, error) {
if !o.Has() {
return nil, nil
}
diff --git a/modules/session/store.go b/modules/session/store.go
index 4fa4d2848f..2f7ab7760b 100644
--- a/modules/session/store.go
+++ b/modules/session/store.go
@@ -6,6 +6,9 @@ package session
import (
"net/http"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/web/middleware"
+
"gitea.com/go-chi/session"
)
@@ -18,6 +21,10 @@ type Store interface {
// RegenerateSession regenerates the underlying session and returns the new store
func RegenerateSession(resp http.ResponseWriter, req *http.Request) (Store, error) {
+ // Ensure that a cookie with a trailing slash does not take precedence over
+ // the cookie written by the middleware.
+ middleware.DeleteLegacySiteCookie(resp, setting.SessionConfig.CookieName)
+
s, err := session.RegenerateSession(resp, req)
return s, err
}
diff --git a/modules/templates/util_misc.go b/modules/templates/util_misc.go
index 6c1b4ab240..774385483b 100644
--- a/modules/templates/util_misc.go
+++ b/modules/templates/util_misc.go
@@ -142,35 +142,39 @@ type remoteAddress struct {
Password string
}
-func mirrorRemoteAddress(ctx context.Context, m *repo_model.Repository, remoteName string, ignoreOriginalURL bool) remoteAddress {
- a := remoteAddress{}
-
- remoteURL := m.OriginalURL
- if ignoreOriginalURL || remoteURL == "" {
- var err error
- remoteURL, err = git.GetRemoteAddress(ctx, m.RepoPath(), remoteName)
- if err != nil {
- log.Error("GetRemoteURL %v", err)
- return a
- }
+func mirrorRemoteAddress(ctx context.Context, m *repo_model.Repository, remoteName string) remoteAddress {
+ ret := remoteAddress{}
+ remoteURL, err := git.GetRemoteAddress(ctx, m.RepoPath(), remoteName)
+ if err != nil {
+ log.Error("GetRemoteURL %v", err)
+ return ret
}
u, err := giturl.Parse(remoteURL)
if err != nil {
log.Error("giturl.Parse %v", err)
- return a
+ return ret
}
if u.Scheme != "ssh" && u.Scheme != "file" {
if u.User != nil {
- a.Username = u.User.Username()
- a.Password, _ = u.User.Password()
+ ret.Username = u.User.Username()
+ ret.Password, _ = u.User.Password()
}
- u.User = nil
}
- a.Address = u.String()
- return a
+ // The URL stored in the git repo could contain authentication,
+ // erase it, or it will be shown in the UI.
+ u.User = nil
+ ret.Address = u.String()
+ // Why not use m.OriginalURL to set ret.Address?
+ // It should be OK to use it, since m.OriginalURL should be the same as the authentication-erased URL from the Git repository.
+ // However, the old code has already stored authentication in m.OriginalURL when updating mirror settings.
+ // That means we need to use "giturl.Parse" for m.OriginalURL again to ensure authentication is erased.
+ // Instead of doing this, why not directly use the authentication-erased URL from the Git repository?
+ // It should be the same as long as there are no bugs.
+
+ return ret
}
func FilenameIsImage(filename string) bool {
diff --git a/modules/templates/util_render.go b/modules/templates/util_render.go
index 0b53965f25..659422aee7 100644
--- a/modules/templates/util_render.go
+++ b/modules/templates/util_render.go
@@ -216,15 +216,16 @@ func RenderMarkdownToHtml(ctx context.Context, input string) template.HTML { //n
return output
}
-func RenderLabels(ctx context.Context, locale translation.Locale, labels []*issues_model.Label, repoLink string) template.HTML {
+func RenderLabels(ctx context.Context, locale translation.Locale, labels []*issues_model.Label, repoLink string, issue *issues_model.Issue) template.HTML {
+ isPullRequest := issue != nil && issue.IsPull
+ baseLink := fmt.Sprintf("%s/%s", repoLink, util.Iif(isPullRequest, "pulls", "issues"))
htmlCode := ``
for _, label := range labels {
// Protect against nil value in labels - shouldn't happen but would cause a panic if so
if label == nil {
continue
}
- htmlCode += fmt.Sprintf("%s ",
- repoLink, label.ID, RenderLabel(ctx, locale, label))
+ htmlCode += fmt.Sprintf(`%s`, baseLink, label.ID, RenderLabel(ctx, locale, label))
}
htmlCode += ""
return template.HTML(htmlCode)
diff --git a/modules/templates/util_render_test.go b/modules/templates/util_render_test.go
index 15aee8912d..47c5da6485 100644
--- a/modules/templates/util_render_test.go
+++ b/modules/templates/util_render_test.go
@@ -7,17 +7,21 @@ import (
"context"
"html/template"
"os"
+ "strings"
"testing"
+ "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup"
+ "code.gitea.io/gitea/modules/translation"
"github.com/stretchr/testify/assert"
)
-const testInput = ` space @mention-user
+func testInput() string {
+ s := ` space @mention-user
/just/a/path.bin
https://example.com/file.bin
[local link](file.bin)
@@ -36,8 +40,10 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
mail@domain.com
@mention-user test
#123
- space
+ space
`
+ return strings.ReplaceAll(s, "", " ")
+}
var testMetas = map[string]string{
"user": "user13",
@@ -121,23 +127,23 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
#123
space`
- assert.EqualValues(t, expected, RenderCommitBody(context.Background(), testInput, testMetas))
+ assert.EqualValues(t, expected, RenderCommitBody(context.Background(), testInput(), testMetas))
}
func TestRenderCommitMessage(t *testing.T) {
expected := `space @mention-user `
- assert.EqualValues(t, expected, RenderCommitMessage(context.Background(), testInput, testMetas))
+ assert.EqualValues(t, expected, RenderCommitMessage(context.Background(), testInput(), testMetas))
}
func TestRenderCommitMessageLinkSubject(t *testing.T) {
expected := `space @mention-user`
- assert.EqualValues(t, expected, RenderCommitMessageLinkSubject(context.Background(), testInput, "https://example.com/link", testMetas))
+ assert.EqualValues(t, expected, RenderCommitMessageLinkSubject(context.Background(), testInput(), "https://example.com/link", testMetas))
}
func TestRenderIssueTitle(t *testing.T) {
- expected := ` space @mention-user
+ expected := ` space @mention-user
/just/a/path.bin
https://example.com/file.bin
[local link](file.bin)
@@ -156,9 +162,10 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
mail@domain.com
@mention-user test
#123
- space
+ space
`
- assert.EqualValues(t, expected, RenderIssueTitle(context.Background(), testInput, testMetas))
+ expected = strings.ReplaceAll(expected, "", " ")
+ assert.EqualValues(t, expected, RenderIssueTitle(context.Background(), testInput(), testMetas))
}
func TestRenderMarkdownToHtml(t *testing.T) {
@@ -183,5 +190,20 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
#123
space
`
- assert.EqualValues(t, expected, RenderMarkdownToHtml(context.Background(), testInput))
+ assert.EqualValues(t, expected, RenderMarkdownToHtml(context.Background(), testInput()))
+}
+
+func TestRenderLabels(t *testing.T) {
+ ctx := context.Background()
+ locale := &translation.MockLocale{}
+
+ label := &issues.Label{ID: 123, Name: "label-name", Color: "label-color"}
+ issue := &issues.Issue{}
+ expected := `/owner/repo/issues?labels=123`
+ assert.Contains(t, RenderLabels(ctx, locale, []*issues.Label{label}, "/owner/repo", issue), expected)
+
+ label = &issues.Label{ID: 123, Name: "label-name", Color: "label-color"}
+ issue = &issues.Issue{IsPull: true}
+ expected = `/owner/repo/pulls?labels=123`
+ assert.Contains(t, RenderLabels(ctx, locale, []*issues.Label{label}, "/owner/repo", issue), expected)
}
diff --git a/modules/web/middleware/cookie.go b/modules/web/middleware/cookie.go
index 621640895b..0bed726793 100644
--- a/modules/web/middleware/cookie.go
+++ b/modules/web/middleware/cookie.go
@@ -45,10 +45,32 @@ func SetSiteCookie(resp http.ResponseWriter, name, value string, maxAge int) {
SameSite: setting.SessionConfig.SameSite,
}
resp.Header().Add("Set-Cookie", cookie.String())
- if maxAge < 0 {
- // There was a bug in "setting.SessionConfig.CookiePath" code, the old default value of it was empty "".
- // So we have to delete the cookie on path="" again, because some old code leaves cookies on path="".
- cookie.Path = strings.TrimSuffix(setting.SessionConfig.CookiePath, "/")
- resp.Header().Add("Set-Cookie", cookie.String())
- }
+ // Previous versions would use a cookie path with a trailing /.
+ // These are more specific than cookies without a trailing /, so
+ // we need to delete these if they exist.
+ DeleteLegacySiteCookie(resp, name)
+}
+
+// DeleteLegacySiteCookie deletes the cookie with the given name at the cookie
+// path with a trailing /, which would unintentionally override the cookie.
+func DeleteLegacySiteCookie(resp http.ResponseWriter, name string) {
+ if setting.SessionConfig.CookiePath == "" || strings.HasSuffix(setting.SessionConfig.CookiePath, "/") {
+ // If the cookie path ends with /, no legacy cookies will take
+ // precedence, so do nothing. The exception is that cookies with no
+ // path could override other cookies, but it's complicated and we don't
+ // currently handle that.
+ return
+ }
+
+ cookie := &http.Cookie{
+ Name: name,
+ Value: "",
+ MaxAge: -1,
+ Path: setting.SessionConfig.CookiePath + "/",
+ Domain: setting.SessionConfig.Domain,
+ Secure: setting.SessionConfig.Secure,
+ HttpOnly: true,
+ SameSite: setting.SessionConfig.SameSite,
+ }
+ resp.Header().Add("Set-Cookie", cookie.String())
}
diff --git a/options/license/BSD-2-clause-first-lines b/options/license/BSD-2-clause-first-lines
new file mode 100644
index 0000000000..3774caf24a
--- /dev/null
+++ b/options/license/BSD-2-clause-first-lines
@@ -0,0 +1,27 @@
+Copyright (C) 2006,2007,2009 NTT (Nippon Telegraph and Telephone
+Corporation). All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer as the first lines of this file unmodified.
+
+2. Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY NTT "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/options/license/Sun-PPP-2000 b/options/license/Sun-PPP-2000
new file mode 100644
index 0000000000..914c19544a
--- /dev/null
+++ b/options/license/Sun-PPP-2000
@@ -0,0 +1,13 @@
+Copyright (c) 2000 by Sun Microsystems, Inc.
+All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation is hereby granted, provided that the above copyright
+notice appears in all copies.
+
+SUN MAKES NO REPRESENTATION OR WARRANTIES ABOUT THE SUITABILITY OF
+THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
+ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES
diff --git a/options/license/pkgconf b/options/license/pkgconf
new file mode 100644
index 0000000000..b8b2ffd996
--- /dev/null
+++ b/options/license/pkgconf
@@ -0,0 +1,7 @@
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+This software is provided 'as is' and without any warranty, express or
+implied. In no event shall the authors be liable for any damages arising
+from the use of this software.
diff --git a/package-lock.json b/package-lock.json
index 35bf886fc8..61d86f6b7c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -21,7 +21,7 @@
"chartjs-adapter-dayjs-4": "1.0.4",
"chartjs-plugin-zoom": "2.0.1",
"clippie": "4.0.7",
- "css-loader": "7.0.0",
+ "css-loader": "7.1.1",
"dayjs": "1.11.10",
"dropzone": "6.0.0-beta.2",
"easymde": "2.18.0",
@@ -44,9 +44,9 @@
"postcss-nesting": "12.1.1",
"pretty-ms": "9.0.0",
"sortablejs": "1.15.2",
- "swagger-ui-dist": "5.13.0",
+ "swagger-ui-dist": "5.15.1",
"tailwindcss": "3.4.3",
- "temporal-polyfill": "0.2.3",
+ "temporal-polyfill": "0.2.4",
"throttle-debounce": "5.0.0",
"tinycolor2": "1.6.0",
"tippy.js": "6.3.7",
@@ -56,7 +56,7 @@
"vanilla-colorful": "0.7.2",
"vue": "3.4.21",
"vue-bar-graph": "2.0.0",
- "vue-chartjs": "5.3.0",
+ "vue-chartjs": "5.3.1",
"vue-loader": "17.4.2",
"vue3-calendar-heatmap": "2.0.5",
"webpack": "5.91.0",
@@ -64,8 +64,8 @@
"wrap-ansi": "9.0.0"
},
"devDependencies": {
- "@eslint-community/eslint-plugin-eslint-comments": "4.1.0",
- "@playwright/test": "1.42.1",
+ "@eslint-community/eslint-plugin-eslint-comments": "4.3.0",
+ "@playwright/test": "1.43.1",
"@stoplight/spectral-cli": "6.11.1",
"@stylistic/eslint-plugin-js": "1.7.0",
"@stylistic/stylelint-plugin": "2.1.1",
@@ -77,15 +77,15 @@
"eslint-plugin-jquery": "1.5.1",
"eslint-plugin-no-jquery": "2.7.0",
"eslint-plugin-no-use-extend-native": "0.5.0",
- "eslint-plugin-regexp": "2.4.0",
+ "eslint-plugin-regexp": "2.5.0",
"eslint-plugin-sonarjs": "0.25.1",
"eslint-plugin-unicorn": "52.0.0",
"eslint-plugin-vitest": "0.4.1",
"eslint-plugin-vitest-globals": "1.5.0",
- "eslint-plugin-vue": "9.24.0",
+ "eslint-plugin-vue": "9.24.1",
"eslint-plugin-vue-scoped-css": "2.8.0",
- "eslint-plugin-wc": "2.0.4",
- "happy-dom": "14.5.0",
+ "eslint-plugin-wc": "2.1.0",
+ "happy-dom": "14.7.1",
"markdownlint-cli": "0.39.0",
"postcss-html": "1.6.0",
"stylelint": "16.3.1",
@@ -93,9 +93,9 @@
"stylelint-declaration-strict-value": "1.10.4",
"stylelint-value-no-unknown-custom-properties": "6.0.1",
"svgo": "3.2.0",
- "updates": "16.0.0",
+ "updates": "16.0.1",
"vite-string-plugin": "1.1.5",
- "vitest": "1.4.0"
+ "vitest": "1.5.0"
},
"engines": {
"node": ">= 18.0.0"
@@ -865,9 +865,9 @@
}
},
"node_modules/@eslint-community/eslint-plugin-eslint-comments": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@eslint-community/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-4.1.0.tgz",
- "integrity": "sha512-B2mwipifrBS5E00vN8vME68laPMZ0h3sNGOEDj5g9iUN9k5EU99Omq0Nc325eKNoFFDnDtiHp3DqIjO+1bstag==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-4.3.0.tgz",
+ "integrity": "sha512-6e93KtgsndNkvwCCa07LOQJSwzzLLxwrFll3+huyFoiiQXWG0KBcmo0Q1bVgYQQDLfWOOZl2VPBsXqZL6vHIBQ==",
"dev": true,
"dependencies": {
"escape-string-regexp": "^4.0.0",
@@ -877,7 +877,7 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"peerDependencies": {
- "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0"
}
},
"node_modules/@eslint-community/eslint-utils": {
@@ -1344,12 +1344,12 @@
}
},
"node_modules/@playwright/test": {
- "version": "1.42.1",
- "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.42.1.tgz",
- "integrity": "sha512-Gq9rmS54mjBL/7/MvBaNOBwbfnh7beHvS6oS4srqXFcQHpQCV1+c8JXWE8VLPyRDhgS3H8x8A7hztqI9VnwrAQ==",
+ "version": "1.43.1",
+ "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.43.1.tgz",
+ "integrity": "sha512-HgtQzFgNEEo4TE22K/X7sYTYNqEMMTZmFS8kTq6m8hXj+m1D8TgwgIbumHddJa9h4yl4GkKb8/bgAl2+g7eDgA==",
"dev": true,
"dependencies": {
- "playwright": "1.42.1"
+ "playwright": "1.43.1"
},
"bin": {
"playwright": "cli.js"
@@ -1420,9 +1420,9 @@
"dev": true
},
"node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.14.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.0.tgz",
- "integrity": "sha512-jwXtxYbRt1V+CdQSy6Z+uZti7JF5irRKF8hlKfEnF/xJpcNGuuiZMBvuoYM+x9sr9iWGnzrlM0+9hvQ1kgkf1w==",
+ "version": "4.14.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.2.tgz",
+ "integrity": "sha512-ahxSgCkAEk+P/AVO0vYr7DxOD3CwAQrT0Go9BJyGQ9Ef0QxVOfjDZMiF4Y2s3mLyPrjonchIMH/tbWHucJMykQ==",
"cpu": [
"arm"
],
@@ -1433,9 +1433,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
- "version": "4.14.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.0.tgz",
- "integrity": "sha512-fI9nduZhCccjzlsA/OuAwtFGWocxA4gqXGTLvOyiF8d+8o0fZUeSztixkYjcGq1fGZY3Tkq4yRvHPFxU+jdZ9Q==",
+ "version": "4.14.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.2.tgz",
+ "integrity": "sha512-lAarIdxZWbFSHFSDao9+I/F5jDaKyCqAPMq5HqnfpBw8dKDiCaaqM0lq5h1pQTLeIqueeay4PieGR5jGZMWprw==",
"cpu": [
"arm64"
],
@@ -1446,9 +1446,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.14.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.0.tgz",
- "integrity": "sha512-BcnSPRM76/cD2gQC+rQNGBN6GStBs2pl/FpweW8JYuz5J/IEa0Fr4AtrPv766DB/6b2MZ/AfSIOSGw3nEIP8SA==",
+ "version": "4.14.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.2.tgz",
+ "integrity": "sha512-SWsr8zEUk82KSqquIMgZEg2GE5mCSfr9sE/thDROkX6pb3QQWPp8Vw8zOq2GyxZ2t0XoSIUlvHDkrf5Gmf7x3Q==",
"cpu": [
"arm64"
],
@@ -1459,9 +1459,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.14.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.0.tgz",
- "integrity": "sha512-LDyFB9GRolGN7XI6955aFeI3wCdCUszFWumWU0deHA8VpR3nWRrjG6GtGjBrQxQKFevnUTHKCfPR4IvrW3kCgQ==",
+ "version": "4.14.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.2.tgz",
+ "integrity": "sha512-o/HAIrQq0jIxJAhgtIvV5FWviYK4WB0WwV91SLUnsliw1lSAoLsmgEEgRWzDguAFeUEUUoIWXiJrPqU7vGiVkA==",
"cpu": [
"x64"
],
@@ -1472,9 +1472,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.14.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.0.tgz",
- "integrity": "sha512-ygrGVhQP47mRh0AAD0zl6QqCbNsf0eTo+vgwkY6LunBcg0f2Jv365GXlDUECIyoXp1kKwL5WW6rsO429DBY/bA==",
+ "version": "4.14.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.2.tgz",
+ "integrity": "sha512-nwlJ65UY9eGq91cBi6VyDfArUJSKOYt5dJQBq8xyLhvS23qO+4Nr/RreibFHjP6t+5ap2ohZrUJcHv5zk5ju/g==",
"cpu": [
"arm"
],
@@ -1485,9 +1485,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.14.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.0.tgz",
- "integrity": "sha512-x+uJ6MAYRlHGe9wi4HQjxpaKHPM3d3JjqqCkeC5gpnnI6OWovLdXTpfa8trjxPLnWKyBsSi5kne+146GAxFt4A==",
+ "version": "4.14.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.2.tgz",
+ "integrity": "sha512-Pg5TxxO2IVlMj79+c/9G0LREC9SY3HM+pfAwX7zj5/cAuwrbfj2Wv9JbMHIdPCfQpYsI4g9mE+2Bw/3aeSs2rQ==",
"cpu": [
"arm64"
],
@@ -1498,9 +1498,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.14.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.0.tgz",
- "integrity": "sha512-nrRw8ZTQKg6+Lttwqo6a2VxR9tOroa2m91XbdQ2sUUzHoedXlsyvY1fN4xWdqz8PKmf4orDwejxXHjh7YBGUCA==",
+ "version": "4.14.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.2.tgz",
+ "integrity": "sha512-cAOTjGNm84gc6tS02D1EXtG7tDRsVSDTBVXOLbj31DkwfZwgTPYZ6aafSU7rD/4R2a34JOwlF9fQayuTSkoclA==",
"cpu": [
"arm64"
],
@@ -1511,11 +1511,11 @@
]
},
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
- "version": "4.14.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.0.tgz",
- "integrity": "sha512-xV0d5jDb4aFu84XKr+lcUJ9y3qpIWhttO3Qev97z8DKLXR62LC3cXT/bMZXrjLF9X+P5oSmJTzAhqwUbY96PnA==",
+ "version": "4.14.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.2.tgz",
+ "integrity": "sha512-4RyT6v1kXb7C0fn6zV33rvaX05P0zHoNzaXI/5oFHklfKm602j+N4mn2YvoezQViRLPnxP8M1NaY4s/5kXO5cw==",
"cpu": [
- "ppc64le"
+ "ppc64"
],
"dev": true,
"optional": true,
@@ -1524,9 +1524,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.14.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.0.tgz",
- "integrity": "sha512-SDDhBQwZX6LPRoPYjAZWyL27LbcBo7WdBFWJi5PI9RPCzU8ijzkQn7tt8NXiXRiFMJCVpkuMkBf4OxSxVMizAw==",
+ "version": "4.14.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.2.tgz",
+ "integrity": "sha512-KNUH6jC/vRGAKSorySTyc/yRYlCwN/5pnMjXylfBniwtJx5O7X17KG/0efj8XM3TZU7raYRXJFFReOzNmL1n1w==",
"cpu": [
"riscv64"
],
@@ -1537,9 +1537,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.14.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.0.tgz",
- "integrity": "sha512-RxB/qez8zIDshNJDufYlTT0ZTVut5eCpAZ3bdXDU9yTxBzui3KhbGjROK2OYTTor7alM7XBhssgoO3CZ0XD3qA==",
+ "version": "4.14.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.2.tgz",
+ "integrity": "sha512-xPV4y73IBEXToNPa3h5lbgXOi/v0NcvKxU0xejiFw6DtIYQqOTMhZ2DN18/HrrP0PmiL3rGtRG9gz1QE8vFKXQ==",
"cpu": [
"s390x"
],
@@ -1550,9 +1550,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.14.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.0.tgz",
- "integrity": "sha512-C6y6z2eCNCfhZxT9u+jAM2Fup89ZjiG5pIzZIDycs1IwESviLxwkQcFRGLjnDrP+PT+v5i4YFvlcfAs+LnreXg==",
+ "version": "4.14.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.2.tgz",
+ "integrity": "sha512-QBhtr07iFGmF9egrPOWyO5wciwgtzKkYPNLVCFZTmr4TWmY0oY2Dm/bmhHjKRwZoGiaKdNcKhFtUMBKvlchH+Q==",
"cpu": [
"x64"
],
@@ -1563,9 +1563,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.14.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.0.tgz",
- "integrity": "sha512-i0QwbHYfnOMYsBEyjxcwGu5SMIi9sImDVjDg087hpzXqhBSosxkE7gyIYFHgfFl4mr7RrXksIBZ4DoLoP4FhJg==",
+ "version": "4.14.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.2.tgz",
+ "integrity": "sha512-8zfsQRQGH23O6qazZSFY5jP5gt4cFvRuKTpuBsC1ZnSWxV8ZKQpPqOZIUtdfMOugCcBvFGRa1pDC/tkf19EgBw==",
"cpu": [
"x64"
],
@@ -1576,9 +1576,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.14.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.0.tgz",
- "integrity": "sha512-Fq52EYb0riNHLBTAcL0cun+rRwyZ10S9vKzhGKKgeD+XbwunszSY0rVMco5KbOsTlwovP2rTOkiII/fQ4ih/zQ==",
+ "version": "4.14.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.2.tgz",
+ "integrity": "sha512-H4s8UjgkPnlChl6JF5empNvFHp77Jx+Wfy2EtmYPe9G22XV+PMuCinZVHurNe8ggtwoaohxARJZbaH/3xjB/FA==",
"cpu": [
"arm64"
],
@@ -1589,9 +1589,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.14.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.0.tgz",
- "integrity": "sha512-e/PBHxPdJ00O9p5Ui43+vixSgVf4NlLsmV6QneGERJ3lnjIua/kim6PRFe3iDueT1rQcgSkYP8ZBBXa/h4iPvw==",
+ "version": "4.14.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.2.tgz",
+ "integrity": "sha512-djqpAjm/i8erWYF0K6UY4kRO3X5+T4TypIqw60Q8MTqSBaQNpNXDhxdjpZ3ikgb+wn99svA7jxcXpiyg9MUsdw==",
"cpu": [
"ia32"
],
@@ -1602,9 +1602,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.14.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.0.tgz",
- "integrity": "sha512-aGg7iToJjdklmxlUlJh/PaPNa4PmqHfyRMLunbL3eaMO0gp656+q1zOKkpJ/CVe9CryJv6tAN1HDoR8cNGzkag==",
+ "version": "4.14.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.2.tgz",
+ "integrity": "sha512-teAqzLT0yTYZa8ZP7zhFKEx4cotS8Tkk5XiqNMJhD4CpaWB1BHARE4Qy+RzwnXvSAYv+Q3jAqCVBS+PS+Yee8Q==",
"cpu": [
"x64"
],
@@ -2217,9 +2217,9 @@
}
},
"node_modules/@types/eslint": {
- "version": "8.56.7",
- "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.7.tgz",
- "integrity": "sha512-SjDvI/x3zsZnOkYZ3lCt9lOZWZLB2jIlNKz+LBgCtDurK0JZcwucxYHn1w2BJkD34dgX9Tjnak0txtq4WTggEA==",
+ "version": "8.56.9",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.9.tgz",
+ "integrity": "sha512-W4W3KcqzjJ0sHg2vAq9vfml6OhsJ53TcUjUqfzzZf/EChUtwspszj/S0pzMxnfRcO55/iGq47dscXw71Fxc4Zg==",
"dependencies": {
"@types/estree": "*",
"@types/json-schema": "*"
@@ -2269,9 +2269,9 @@
"integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g=="
},
"node_modules/@types/node": {
- "version": "20.12.4",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.4.tgz",
- "integrity": "sha512-E+Fa9z3wSQpzgYQdYmme5X3OTuejnnTx88A6p6vkkJosR3KBz+HpE3kqNm98VE6cfLFcISx7zW7MsJkH6KwbTw==",
+ "version": "20.12.7",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz",
+ "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==",
"dependencies": {
"undici-types": "~5.26.4"
}
@@ -2314,22 +2314,22 @@
"dev": true
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "7.5.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.5.0.tgz",
- "integrity": "sha512-HpqNTH8Du34nLxbKgVMGljZMG0rJd2O9ecvr2QLYp+7512ty1j42KnsFwspPXg1Vh8an9YImf6CokUBltisZFQ==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.6.0.tgz",
+ "integrity": "sha512-gKmTNwZnblUdnTIJu3e9kmeRRzV2j1a/LUO27KNNAnIC5zjy1aSvXSRp4rVNlmAoHlQ7HzX42NbKpcSr4jF80A==",
"dev": true,
"dependencies": {
- "@eslint-community/regexpp": "^4.5.1",
- "@typescript-eslint/scope-manager": "7.5.0",
- "@typescript-eslint/type-utils": "7.5.0",
- "@typescript-eslint/utils": "7.5.0",
- "@typescript-eslint/visitor-keys": "7.5.0",
+ "@eslint-community/regexpp": "^4.10.0",
+ "@typescript-eslint/scope-manager": "7.6.0",
+ "@typescript-eslint/type-utils": "7.6.0",
+ "@typescript-eslint/utils": "7.6.0",
+ "@typescript-eslint/visitor-keys": "7.6.0",
"debug": "^4.3.4",
"graphemer": "^1.4.0",
- "ignore": "^5.2.4",
+ "ignore": "^5.3.1",
"natural-compare": "^1.4.0",
- "semver": "^7.5.4",
- "ts-api-utils": "^1.0.1"
+ "semver": "^7.6.0",
+ "ts-api-utils": "^1.3.0"
},
"engines": {
"node": "^18.18.0 || >=20.0.0"
@@ -2349,15 +2349,15 @@
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "7.5.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.5.0.tgz",
- "integrity": "sha512-cj+XGhNujfD2/wzR1tabNsidnYRaFfEkcULdcIyVBYcXjBvBKOes+mpMBP7hMpOyk+gBcfXsrg4NBGAStQyxjQ==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.6.0.tgz",
+ "integrity": "sha512-usPMPHcwX3ZoPWnBnhhorc14NJw9J4HpSXQX4urF2TPKG0au0XhJoZyX62fmvdHONUkmyUe74Hzm1//XA+BoYg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/scope-manager": "7.5.0",
- "@typescript-eslint/types": "7.5.0",
- "@typescript-eslint/typescript-estree": "7.5.0",
- "@typescript-eslint/visitor-keys": "7.5.0",
+ "@typescript-eslint/scope-manager": "7.6.0",
+ "@typescript-eslint/types": "7.6.0",
+ "@typescript-eslint/typescript-estree": "7.6.0",
+ "@typescript-eslint/visitor-keys": "7.6.0",
"debug": "^4.3.4"
},
"engines": {
@@ -2377,13 +2377,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "7.5.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.5.0.tgz",
- "integrity": "sha512-Z1r7uJY0MDeUlql9XJ6kRVgk/sP11sr3HKXn268HZyqL7i4cEfrdFuSSY/0tUqT37l5zT0tJOsuDP16kio85iA==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.6.0.tgz",
+ "integrity": "sha512-ngttyfExA5PsHSx0rdFgnADMYQi+Zkeiv4/ZxGYUWd0nLs63Ha0ksmp8VMxAIC0wtCFxMos7Lt3PszJssG/E6w==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "7.5.0",
- "@typescript-eslint/visitor-keys": "7.5.0"
+ "@typescript-eslint/types": "7.6.0",
+ "@typescript-eslint/visitor-keys": "7.6.0"
},
"engines": {
"node": "^18.18.0 || >=20.0.0"
@@ -2394,15 +2394,15 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "7.5.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.5.0.tgz",
- "integrity": "sha512-A021Rj33+G8mx2Dqh0nMO9GyjjIBK3MqgVgZ2qlKf6CJy51wY/lkkFqq3TqqnH34XyAHUkq27IjlUkWlQRpLHw==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.6.0.tgz",
+ "integrity": "sha512-NxAfqAPNLG6LTmy7uZgpK8KcuiS2NZD/HlThPXQRGwz6u7MDBWRVliEEl1Gj6U7++kVJTpehkhZzCJLMK66Scw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/typescript-estree": "7.5.0",
- "@typescript-eslint/utils": "7.5.0",
+ "@typescript-eslint/typescript-estree": "7.6.0",
+ "@typescript-eslint/utils": "7.6.0",
"debug": "^4.3.4",
- "ts-api-utils": "^1.0.1"
+ "ts-api-utils": "^1.3.0"
},
"engines": {
"node": "^18.18.0 || >=20.0.0"
@@ -2421,9 +2421,9 @@
}
},
"node_modules/@typescript-eslint/types": {
- "version": "7.5.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.5.0.tgz",
- "integrity": "sha512-tv5B4IHeAdhR7uS4+bf8Ov3k793VEVHd45viRRkehIUZxm0WF82VPiLgHzA/Xl4TGPg1ZD49vfxBKFPecD5/mg==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.6.0.tgz",
+ "integrity": "sha512-h02rYQn8J+MureCvHVVzhl69/GAfQGPQZmOMjG1KfCl7o3HtMSlPaPUAPu6lLctXI5ySRGIYk94clD/AUMCUgQ==",
"dev": true,
"engines": {
"node": "^18.18.0 || >=20.0.0"
@@ -2434,19 +2434,19 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "7.5.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.5.0.tgz",
- "integrity": "sha512-YklQQfe0Rv2PZEueLTUffiQGKQneiIEKKnfIqPIOxgM9lKSZFCjT5Ad4VqRKj/U4+kQE3fa8YQpskViL7WjdPQ==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.6.0.tgz",
+ "integrity": "sha512-+7Y/GP9VuYibecrCQWSKgl3GvUM5cILRttpWtnAu8GNL9j11e4tbuGZmZjJ8ejnKYyBRb2ddGQ3rEFCq3QjMJw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "7.5.0",
- "@typescript-eslint/visitor-keys": "7.5.0",
+ "@typescript-eslint/types": "7.6.0",
+ "@typescript-eslint/visitor-keys": "7.6.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
- "minimatch": "9.0.3",
- "semver": "^7.5.4",
- "ts-api-utils": "^1.0.1"
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^1.3.0"
},
"engines": {
"node": "^18.18.0 || >=20.0.0"
@@ -2461,34 +2461,19 @@
}
}
},
- "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
- "version": "9.0.3",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
- "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
- "dev": true,
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/@typescript-eslint/utils": {
- "version": "7.5.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.5.0.tgz",
- "integrity": "sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.6.0.tgz",
+ "integrity": "sha512-x54gaSsRRI+Nwz59TXpCsr6harB98qjXYzsRxGqvA5Ue3kQH+FxS7FYU81g/omn22ML2pZJkisy6Q+ElK8pBCA==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
- "@types/json-schema": "^7.0.12",
- "@types/semver": "^7.5.0",
- "@typescript-eslint/scope-manager": "7.5.0",
- "@typescript-eslint/types": "7.5.0",
- "@typescript-eslint/typescript-estree": "7.5.0",
- "semver": "^7.5.4"
+ "@types/json-schema": "^7.0.15",
+ "@types/semver": "^7.5.8",
+ "@typescript-eslint/scope-manager": "7.6.0",
+ "@typescript-eslint/types": "7.6.0",
+ "@typescript-eslint/typescript-estree": "7.6.0",
+ "semver": "^7.6.0"
},
"engines": {
"node": "^18.18.0 || >=20.0.0"
@@ -2502,13 +2487,13 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "7.5.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.5.0.tgz",
- "integrity": "sha512-mcuHM/QircmA6O7fy6nn2w/3ditQkj+SgtOc8DW3uQ10Yfj42amm2i+6F2K4YAOPNNTmE6iM1ynM6lrSwdendA==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.6.0.tgz",
+ "integrity": "sha512-4eLB7t+LlNUmXzfOu1VAIAdkjbu5xNSerURS9X/S5TUKWFRpXRQZbmtPqgKmYx8bj3J0irtQXSiWAOY82v+cgw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "7.5.0",
- "eslint-visitor-keys": "^3.4.1"
+ "@typescript-eslint/types": "7.6.0",
+ "eslint-visitor-keys": "^3.4.3"
},
"engines": {
"node": "^18.18.0 || >=20.0.0"
@@ -2538,13 +2523,13 @@
}
},
"node_modules/@vitest/expect": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.4.0.tgz",
- "integrity": "sha512-Jths0sWCJZ8BxjKe+p+eKsoqev1/T8lYcrjavEaz8auEJ4jAVY0GwW3JKmdVU4mmNPLPHixh4GNXP7GFtAiDHA==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.5.0.tgz",
+ "integrity": "sha512-0pzuCI6KYi2SIC3LQezmxujU9RK/vwC1U9R0rLuGlNGcOuDWxqWKu6nUdFsX9tH1WU0SXtAxToOsEjeUn1s3hA==",
"dev": true,
"dependencies": {
- "@vitest/spy": "1.4.0",
- "@vitest/utils": "1.4.0",
+ "@vitest/spy": "1.5.0",
+ "@vitest/utils": "1.5.0",
"chai": "^4.3.10"
},
"funding": {
@@ -2552,12 +2537,12 @@
}
},
"node_modules/@vitest/runner": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.4.0.tgz",
- "integrity": "sha512-EDYVSmesqlQ4RD2VvWo3hQgTJ7ZrFQ2VSJdfiJiArkCerDAGeyF1i6dHkmySqk573jLp6d/cfqCN+7wUB5tLgg==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.5.0.tgz",
+ "integrity": "sha512-7HWwdxXP5yDoe7DTpbif9l6ZmDwCzcSIK38kTSIt6CFEpMjX4EpCgT6wUmS0xTXqMI6E/ONmfgRKmaujpabjZQ==",
"dev": true,
"dependencies": {
- "@vitest/utils": "1.4.0",
+ "@vitest/utils": "1.5.0",
"p-limit": "^5.0.0",
"pathe": "^1.1.1"
},
@@ -2593,9 +2578,9 @@
}
},
"node_modules/@vitest/snapshot": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.4.0.tgz",
- "integrity": "sha512-saAFnt5pPIA5qDGxOHxJ/XxhMFKkUSBJmVt5VgDsAqPTX6JP326r5C/c9UuCMPoXNzuudTPsYDZCoJ5ilpqG2A==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.5.0.tgz",
+ "integrity": "sha512-qpv3fSEuNrhAO3FpH6YYRdaECnnRjg9VxbhdtPwPRnzSfHVXnNzzrpX4cJxqiwgRMo7uRMWDFBlsBq4Cr+rO3A==",
"dev": true,
"dependencies": {
"magic-string": "^0.30.5",
@@ -2619,9 +2604,9 @@
}
},
"node_modules/@vitest/spy": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.4.0.tgz",
- "integrity": "sha512-Ywau/Qs1DzM/8Uc+yA77CwSegizMlcgTJuYGAi0jujOteJOUf1ujunHThYo243KG9nAyWT3L9ifPYZ5+As/+6Q==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.5.0.tgz",
+ "integrity": "sha512-vu6vi6ew5N5MMHJjD5PoakMRKYdmIrNJmyfkhRpQt5d9Ewhw9nZ5Aqynbi3N61bvk9UvZ5UysMT6ayIrZ8GA9w==",
"dev": true,
"dependencies": {
"tinyspy": "^2.2.0"
@@ -2631,9 +2616,9 @@
}
},
"node_modules/@vitest/utils": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.4.0.tgz",
- "integrity": "sha512-mx3Yd1/6e2Vt/PUC98DcqTirtfxUyAZ32uK82r8rZzbtBeBo+nqgnjx/LvqQdWsrvNtm14VmurNgcf4nqY5gJg==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.5.0.tgz",
+ "integrity": "sha512-BDU0GNL8MWkRkSRdNFvCUCAVOeHaUlVJ9Tx0TYBZyXaaOTmGtUFObzchCivIBrIwKzvZA7A9sCejVhXM2aY98A==",
"dev": true,
"dependencies": {
"diff-sequences": "^29.6.3",
@@ -3566,9 +3551,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001605",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001605.tgz",
- "integrity": "sha512-nXwGlFWo34uliI9z3n6Qc0wZaf7zaZWA1CPZ169La5mV3I/gem7bst0vr5XQH5TJXZIMfDeZyOrZnSlVzKxxHQ==",
+ "version": "1.0.30001609",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001609.tgz",
+ "integrity": "sha512-JFPQs34lHKx1B5t1EpQpWH4c+29zIyn/haGsbpfq3suuV9v56enjFt23zqijxGTMwy1p/4H2tjnQMY+p1WoAyA==",
"funding": [
{
"type": "opencollective",
@@ -3960,9 +3945,9 @@
}
},
"node_modules/css-loader": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.0.0.tgz",
- "integrity": "sha512-WrO4FVoamxt5zY9CauZjoJgXRi/LZKIk+Ta7YvpSGr5r/eMYPNp5/T9ODlMe4/1rF5DYlycG1avhV4g3A/tiAw==",
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.1.tgz",
+ "integrity": "sha512-OxIR5P2mjO1PSXk44bWuQ8XtMK4dpEqpIyERCx3ewOo3I8EmbcxMPUc5ScLtQfgXtOojoMv57So4V/C02HQLsw==",
"dependencies": {
"icss-utils": "^5.1.0",
"postcss": "^8.4.33",
@@ -4812,9 +4797,9 @@
}
},
"node_modules/dompurify": {
- "version": "3.0.11",
- "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.11.tgz",
- "integrity": "sha512-Fan4uMuyB26gFV3ovPoEoQbxRRPfTu3CvImyZnhGq5fsIEO+gEFLp45ISFt+kQBWsK5ulDdT0oV28jS1UrwQLg=="
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.0.tgz",
+ "integrity": "sha512-yoU4rhgPKCo+p5UrWWWNKiIq+ToGqmVVhk0PmMYBK4kRsR3/qhemNFL8f6CFmBd4gMwm3F4T7HBoydP5uY07fA=="
},
"node_modules/domutils": {
"version": "3.1.0",
@@ -4857,9 +4842,9 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.4.727",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.727.tgz",
- "integrity": "sha512-brpv4KTeC4g0Fx2FeIKytLd4UGn1zBQq5Lauy7zEWT9oqkaj5mgsxblEZIAOf1HHLlXxzr6adGViiBy5Z39/CA=="
+ "version": "1.4.736",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.736.tgz",
+ "integrity": "sha512-Rer6wc3ynLelKNM4lOCg7/zPQj8tPOCB2hzD32PX9wd3hgRRi9MxEbmkFCokzcEhRVMiOVLjnL9ig9cefJ+6+Q=="
},
"node_modules/elkjs": {
"version": "0.9.2",
@@ -4911,9 +4896,9 @@
}
},
"node_modules/envinfo": {
- "version": "7.11.1",
- "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.1.tgz",
- "integrity": "sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg==",
+ "version": "7.12.0",
+ "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.12.0.tgz",
+ "integrity": "sha512-Iw9rQJBGpJRd3rwXm9ft/JiGoAZmLxxJZELYDQoPRZ4USVhkKtIcNBPw6U+/K2mBpaqM25JSV6Yl4Az9vO2wJg==",
"bin": {
"envinfo": "dist/cli.js"
},
@@ -5689,9 +5674,9 @@
}
},
"node_modules/eslint-plugin-regexp": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-2.4.0.tgz",
- "integrity": "sha512-OL2S6VPjQhs9s/NclQ0qattVq1J0GU8ox70/HIVy5Dxw+qbbdd7KQkyucsez2clEQjvdtDe12DTnPphFFUyXFg==",
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-2.5.0.tgz",
+ "integrity": "sha512-I7vKcP0o75WS5SHiVNXN+Eshq49sbrweMQIuqSL3AId9AwDe9Dhbfug65vw64LxmOd4v+yf5l5Xt41y9puiq0g==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
@@ -5785,9 +5770,9 @@
"dev": true
},
"node_modules/eslint-plugin-vue": {
- "version": "9.24.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.24.0.tgz",
- "integrity": "sha512-9SkJMvF8NGMT9aQCwFc5rj8Wo1XWSMSHk36i7ZwdI614BU7sIOR28ZjuFPKp8YGymZN12BSEbiSwa7qikp+PBw==",
+ "version": "9.24.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.24.1.tgz",
+ "integrity": "sha512-wk3SuwmS1pZdcuJlokGYEi/buDOwD6KltvhIZyOnpJ/378dcQ4zchu9PAMbbLAaydCz1iYc5AozszcOOgZIIOg==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
@@ -5803,7 +5788,7 @@
"node": "^14.17.0 || >=16.0.0"
},
"peerDependencies": {
- "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0"
+ "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0"
}
},
"node_modules/eslint-plugin-vue-scoped-css": {
@@ -5833,9 +5818,9 @@
}
},
"node_modules/eslint-plugin-wc": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/eslint-plugin-wc/-/eslint-plugin-wc-2.0.4.tgz",
- "integrity": "sha512-ORu7MBv0hXIvq894EJad70m+AvHGbmrDdKT6lcgtCVVhEbuIAyxg0ilfqqqHOmsh8PfcUBeEae3y7CElKvm1KQ==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-wc/-/eslint-plugin-wc-2.1.0.tgz",
+ "integrity": "sha512-s/BGOtmpgQ2yifR6EC1OM9t0DwYLgg4ZAL07Kw4eXvBb5TYaPafI+65tswvnZvhH8FqcjERLbBZPPvYsvinkfg==",
"dev": true,
"dependencies": {
"is-valid-element-name": "^1.0.0",
@@ -6594,9 +6579,9 @@
}
},
"node_modules/happy-dom": {
- "version": "14.5.0",
- "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-14.5.0.tgz",
- "integrity": "sha512-KvOtCq7eamc7cjihM0F1wj6FptuXzooc3Typa7Vgu6ns2uKGXC4BIFlK80SdH2w8zcW0gtxpBVI/sUqbYtljDA==",
+ "version": "14.7.1",
+ "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-14.7.1.tgz",
+ "integrity": "sha512-v60Q0evZ4clvMcrAh5/F8EdxDdfHdFrtffz/CNe10jKD+nFweZVxM91tW+UyY2L4AtpgIaXdZ7TQmiO1pfcwbg==",
"dev": true,
"dependencies": {
"entities": "^4.5.0",
@@ -9381,12 +9366,12 @@
"dev": true
},
"node_modules/playwright": {
- "version": "1.42.1",
- "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.42.1.tgz",
- "integrity": "sha512-PgwB03s2DZBcNRoW+1w9E+VkLBxweib6KTXM0M3tkiT4jVxKSi6PmVJ591J+0u10LUrgxB7dLRbiJqO5s2QPMg==",
+ "version": "1.43.1",
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.43.1.tgz",
+ "integrity": "sha512-V7SoH0ai2kNt1Md9E3Gwas5B9m8KR2GVvwZnAI6Pg0m3sh7UvgiYhRrhsziCmqMJNouPckiOhk8T+9bSAK0VIA==",
"dev": true,
"dependencies": {
- "playwright-core": "1.42.1"
+ "playwright-core": "1.43.1"
},
"bin": {
"playwright": "cli.js"
@@ -9399,9 +9384,9 @@
}
},
"node_modules/playwright-core": {
- "version": "1.42.1",
- "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.42.1.tgz",
- "integrity": "sha512-mxz6zclokgrke9p1vtdy/COWBH+eOZgYUVVU34C73M+4j4HLlQJHtfcqiqqxpP0o8HhMkflvfbquLX5dg6wlfA==",
+ "version": "1.43.1",
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.43.1.tgz",
+ "integrity": "sha512-EI36Mto2Vrx6VF7rm708qSnesVQKbxEWvPrfA1IPY6HgczBplDx7ENtx+K2n4kJ41sLLkuGfmb0ZLSSXlDhqPg==",
"dev": true,
"bin": {
"playwright-core": "cli.js"
@@ -11241,9 +11226,9 @@
}
},
"node_modules/swagger-ui-dist": {
- "version": "5.13.0",
- "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.13.0.tgz",
- "integrity": "sha512-uaWhh6j18IIs5tOX0arvIBnVINAzpTXaQXkr7qAk8zoupegJVg0UU/5+S/FgsgVCnzVsJ9d7QLjIxkswEeTg0Q=="
+ "version": "5.15.1",
+ "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.15.1.tgz",
+ "integrity": "sha512-Et/WY0NFdKj8sUBOyEx5P3VybsvGl7bo/y9JvgQ22TkH1a/KscQ0ZiQST2YeJ3cwCrIjYTbHbt165fkku0y1Ig=="
},
"node_modules/sync-fetch": {
"version": "0.4.5",
@@ -11379,17 +11364,17 @@
}
},
"node_modules/temporal-polyfill": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/temporal-polyfill/-/temporal-polyfill-0.2.3.tgz",
- "integrity": "sha512-7ZJRc7wq/1XjrOQYkkNpgo2qfE9XLrUU8D/DS+LAC/T0bYqZ46rW6dow0sOTXTPZS4bwer8bD/0OyuKQBfA3yw==",
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/temporal-polyfill/-/temporal-polyfill-0.2.4.tgz",
+ "integrity": "sha512-WA5p0CjQTkMjF9m8sP4wSYgpqI8m2d4q7wPUyaJOWhy4bI9mReLb2yGvTV4qf/DPMTe6H6M/Dig5KmTMB7ev6Q==",
"dependencies": {
- "temporal-spec": "^0.2.0"
+ "temporal-spec": "^0.2.4"
}
},
"node_modules/temporal-spec": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/temporal-spec/-/temporal-spec-0.2.0.tgz",
- "integrity": "sha512-r1AT0XdEp8TMQ13FLvOt8mOtAxDQsRt2QU5rSWCA7YfshddU651Y1NHVrceLANvixKdf9fYO8B/S9fXHodB7HQ=="
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/temporal-spec/-/temporal-spec-0.2.4.tgz",
+ "integrity": "sha512-lDMFv4nKQrSjlkHKAlHVqKrBG4DyFfa9F74cmBZ3Iy3ed8yvWnlWSIdi4IKfSqwmazAohBNwiN64qGx4y5Q3IQ=="
},
"node_modules/terser": {
"version": "5.30.3",
@@ -11749,9 +11734,9 @@
}
},
"node_modules/typescript": {
- "version": "5.4.4",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz",
- "integrity": "sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==",
+ "version": "5.4.5",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
+ "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
"devOptional": true,
"peer": true,
"bin": {
@@ -11855,9 +11840,9 @@
}
},
"node_modules/updates": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/updates/-/updates-16.0.0.tgz",
- "integrity": "sha512-Ra3QUu/rfbSCsG83zNNvoRQt0FVT3qULBSALYTlwTDX6oyz7R5GQAYwqJoIG/RDjYAXpwr3usrInoyHHTP6cag==",
+ "version": "16.0.1",
+ "resolved": "https://registry.npmjs.org/updates/-/updates-16.0.1.tgz",
+ "integrity": "sha512-If3NQKzGcA3aVgz2VyOXqQ+4uqYjPUPqh2PeZPtD+OKT4CTmxRYqoyFO+T3nwfccy4SiWy5AabWrBXXhVQ89Aw==",
"dev": true,
"bin": {
"updates": "dist/updates.js"
@@ -12003,9 +11988,9 @@
}
},
"node_modules/vite-node": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.4.0.tgz",
- "integrity": "sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.5.0.tgz",
+ "integrity": "sha512-tV8h6gMj6vPzVCa7l+VGq9lwoJjW8Y79vst8QZZGiuRAfijU+EEWuc0kFpmndQrWhMMhet1jdSF+40KSZUqIIw==",
"dev": true,
"dependencies": {
"cac": "^6.7.14",
@@ -12051,9 +12036,9 @@
}
},
"node_modules/vite/node_modules/rollup": {
- "version": "4.14.0",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.0.tgz",
- "integrity": "sha512-Qe7w62TyawbDzB4yt32R0+AbIo6m1/sqO7UPzFS8Z/ksL5mrfhA0v4CavfdmFav3D+ub4QeAgsGEe84DoWe/nQ==",
+ "version": "4.14.2",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.2.tgz",
+ "integrity": "sha512-WkeoTWvuBoFjFAhsEOHKRoZ3r9GfTyhh7Vff1zwebEFLEFjT1lG3784xEgKiTa7E+e70vsC81roVL2MP4tgEEQ==",
"dev": true,
"dependencies": {
"@types/estree": "1.0.5"
@@ -12066,35 +12051,35 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.14.0",
- "@rollup/rollup-android-arm64": "4.14.0",
- "@rollup/rollup-darwin-arm64": "4.14.0",
- "@rollup/rollup-darwin-x64": "4.14.0",
- "@rollup/rollup-linux-arm-gnueabihf": "4.14.0",
- "@rollup/rollup-linux-arm64-gnu": "4.14.0",
- "@rollup/rollup-linux-arm64-musl": "4.14.0",
- "@rollup/rollup-linux-powerpc64le-gnu": "4.14.0",
- "@rollup/rollup-linux-riscv64-gnu": "4.14.0",
- "@rollup/rollup-linux-s390x-gnu": "4.14.0",
- "@rollup/rollup-linux-x64-gnu": "4.14.0",
- "@rollup/rollup-linux-x64-musl": "4.14.0",
- "@rollup/rollup-win32-arm64-msvc": "4.14.0",
- "@rollup/rollup-win32-ia32-msvc": "4.14.0",
- "@rollup/rollup-win32-x64-msvc": "4.14.0",
+ "@rollup/rollup-android-arm-eabi": "4.14.2",
+ "@rollup/rollup-android-arm64": "4.14.2",
+ "@rollup/rollup-darwin-arm64": "4.14.2",
+ "@rollup/rollup-darwin-x64": "4.14.2",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.14.2",
+ "@rollup/rollup-linux-arm64-gnu": "4.14.2",
+ "@rollup/rollup-linux-arm64-musl": "4.14.2",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.14.2",
+ "@rollup/rollup-linux-riscv64-gnu": "4.14.2",
+ "@rollup/rollup-linux-s390x-gnu": "4.14.2",
+ "@rollup/rollup-linux-x64-gnu": "4.14.2",
+ "@rollup/rollup-linux-x64-musl": "4.14.2",
+ "@rollup/rollup-win32-arm64-msvc": "4.14.2",
+ "@rollup/rollup-win32-ia32-msvc": "4.14.2",
+ "@rollup/rollup-win32-x64-msvc": "4.14.2",
"fsevents": "~2.3.2"
}
},
"node_modules/vitest": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.4.0.tgz",
- "integrity": "sha512-gujzn0g7fmwf83/WzrDTnncZt2UiXP41mHuFYFrdwaLRVQ6JYQEiME2IfEjU3vcFL3VKa75XhI3lFgn+hfVsQw==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.5.0.tgz",
+ "integrity": "sha512-d8UKgR0m2kjdxDWX6911uwxout6GHS0XaGH1cksSIVVG8kRlE7G7aBw7myKQCvDI5dT4j7ZMa+l706BIORMDLw==",
"dev": true,
"dependencies": {
- "@vitest/expect": "1.4.0",
- "@vitest/runner": "1.4.0",
- "@vitest/snapshot": "1.4.0",
- "@vitest/spy": "1.4.0",
- "@vitest/utils": "1.4.0",
+ "@vitest/expect": "1.5.0",
+ "@vitest/runner": "1.5.0",
+ "@vitest/snapshot": "1.5.0",
+ "@vitest/spy": "1.5.0",
+ "@vitest/utils": "1.5.0",
"acorn-walk": "^8.3.2",
"chai": "^4.3.10",
"debug": "^4.3.4",
@@ -12106,9 +12091,9 @@
"std-env": "^3.5.0",
"strip-literal": "^2.0.0",
"tinybench": "^2.5.1",
- "tinypool": "^0.8.2",
+ "tinypool": "^0.8.3",
"vite": "^5.0.0",
- "vite-node": "1.4.0",
+ "vite-node": "1.5.0",
"why-is-node-running": "^2.2.2"
},
"bin": {
@@ -12123,8 +12108,8 @@
"peerDependencies": {
"@edge-runtime/vm": "*",
"@types/node": "^18.0.0 || >=20.0.0",
- "@vitest/browser": "1.4.0",
- "@vitest/ui": "1.4.0",
+ "@vitest/browser": "1.5.0",
+ "@vitest/ui": "1.5.0",
"happy-dom": "*",
"jsdom": "*"
},
@@ -12191,9 +12176,9 @@
}
},
"node_modules/vue-chartjs": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/vue-chartjs/-/vue-chartjs-5.3.0.tgz",
- "integrity": "sha512-8XqX0JU8vFZ+WA2/knz4z3ThClduni2Nm0BMe2u0mXgTfd9pXrmJ07QBI+WAij5P/aPmPMX54HCE1seWL37ZdQ==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/vue-chartjs/-/vue-chartjs-5.3.1.tgz",
+ "integrity": "sha512-rZjqcHBxKiHrBl0CIvcOlVEBwRhpWAVf6rDU3vUfa7HuSRmGtCslc0Oc8m16oAVuk0erzc1FCtH1VCriHsrz+A==",
"peerDependencies": {
"chart.js": "^4.1.1",
"vue": "^3.0.0-0 || ^2.7.0"
diff --git a/package.json b/package.json
index f58c3b4d8f..ff1ae4d49e 100644
--- a/package.json
+++ b/package.json
@@ -20,7 +20,7 @@
"chartjs-adapter-dayjs-4": "1.0.4",
"chartjs-plugin-zoom": "2.0.1",
"clippie": "4.0.7",
- "css-loader": "7.0.0",
+ "css-loader": "7.1.1",
"dayjs": "1.11.10",
"dropzone": "6.0.0-beta.2",
"easymde": "2.18.0",
@@ -43,9 +43,9 @@
"postcss-nesting": "12.1.1",
"pretty-ms": "9.0.0",
"sortablejs": "1.15.2",
- "swagger-ui-dist": "5.13.0",
+ "swagger-ui-dist": "5.15.1",
"tailwindcss": "3.4.3",
- "temporal-polyfill": "0.2.3",
+ "temporal-polyfill": "0.2.4",
"throttle-debounce": "5.0.0",
"tinycolor2": "1.6.0",
"tippy.js": "6.3.7",
@@ -55,7 +55,7 @@
"vanilla-colorful": "0.7.2",
"vue": "3.4.21",
"vue-bar-graph": "2.0.0",
- "vue-chartjs": "5.3.0",
+ "vue-chartjs": "5.3.1",
"vue-loader": "17.4.2",
"vue3-calendar-heatmap": "2.0.5",
"webpack": "5.91.0",
@@ -63,8 +63,8 @@
"wrap-ansi": "9.0.0"
},
"devDependencies": {
- "@eslint-community/eslint-plugin-eslint-comments": "4.1.0",
- "@playwright/test": "1.42.1",
+ "@eslint-community/eslint-plugin-eslint-comments": "4.3.0",
+ "@playwright/test": "1.43.1",
"@stoplight/spectral-cli": "6.11.1",
"@stylistic/eslint-plugin-js": "1.7.0",
"@stylistic/stylelint-plugin": "2.1.1",
@@ -76,15 +76,15 @@
"eslint-plugin-jquery": "1.5.1",
"eslint-plugin-no-jquery": "2.7.0",
"eslint-plugin-no-use-extend-native": "0.5.0",
- "eslint-plugin-regexp": "2.4.0",
+ "eslint-plugin-regexp": "2.5.0",
"eslint-plugin-sonarjs": "0.25.1",
"eslint-plugin-unicorn": "52.0.0",
"eslint-plugin-vitest": "0.4.1",
"eslint-plugin-vitest-globals": "1.5.0",
- "eslint-plugin-vue": "9.24.0",
+ "eslint-plugin-vue": "9.24.1",
"eslint-plugin-vue-scoped-css": "2.8.0",
- "eslint-plugin-wc": "2.0.4",
- "happy-dom": "14.5.0",
+ "eslint-plugin-wc": "2.1.0",
+ "happy-dom": "14.7.1",
"markdownlint-cli": "0.39.0",
"postcss-html": "1.6.0",
"stylelint": "16.3.1",
@@ -92,9 +92,9 @@
"stylelint-declaration-strict-value": "1.10.4",
"stylelint-value-no-unknown-custom-properties": "6.0.1",
"svgo": "3.2.0",
- "updates": "16.0.0",
+ "updates": "16.0.1",
"vite-string-plugin": "1.1.5",
- "vitest": "1.4.0"
+ "vitest": "1.5.0"
},
"browserslist": [
"defaults"
diff --git a/poetry.lock b/poetry.lock
index 951a0fa7a8..1533ddc5ec 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -113,13 +113,13 @@ six = ">=1.13.0"
[[package]]
name = "json5"
-version = "0.9.24"
+version = "0.9.25"
description = "A Python implementation of the JSON5 data format."
optional = false
python-versions = ">=3.8"
files = [
- {file = "json5-0.9.24-py3-none-any.whl", hash = "sha256:4ca101fd5c7cb47960c055ef8f4d0e31e15a7c6c48c3b6f1473fc83b6c462a13"},
- {file = "json5-0.9.24.tar.gz", hash = "sha256:0c638399421da959a20952782800e5c1a78c14e08e1dc9738fa10d8ec14d58c8"},
+ {file = "json5-0.9.25-py3-none-any.whl", hash = "sha256:34ed7d834b1341a86987ed52f3f76cd8ee184394906b6e22a1e0deb9ab294e8f"},
+ {file = "json5-0.9.25.tar.gz", hash = "sha256:548e41b9be043f9426776f05df8635a00fe06104ea51ed24b67f908856e151ae"},
]
[[package]]
diff --git a/routers/api/v1/misc/nodeinfo.go b/routers/api/v1/misc/nodeinfo.go
index 3bd80de5c1..5973724782 100644
--- a/routers/api/v1/misc/nodeinfo.go
+++ b/routers/api/v1/misc/nodeinfo.go
@@ -29,9 +29,7 @@ func NodeInfo(ctx *context.APIContext) {
nodeInfoUsage := structs.NodeInfoUsage{}
if setting.Federation.ShareUserStatistics {
- var cached bool
- nodeInfoUsage, cached = ctx.Cache.Get(cacheKeyNodeInfoUsage).(structs.NodeInfoUsage)
-
+ cached, _ := ctx.Cache.GetJSON(cacheKeyNodeInfoUsage, &nodeInfoUsage)
if !cached {
usersTotal := int(user_model.CountUsers(ctx, nil))
now := time.Now()
@@ -53,7 +51,7 @@ func NodeInfo(ctx *context.APIContext) {
LocalComments: int(allComments),
}
- if err := ctx.Cache.Put(cacheKeyNodeInfoUsage, nodeInfoUsage, 180); err != nil {
+ if err := ctx.Cache.PutJSON(cacheKeyNodeInfoUsage, nodeInfoUsage, 180); err != nil {
ctx.InternalServerError(err)
return
}
diff --git a/routers/web/org/projects.go b/routers/web/org/projects.go
index 596a370d2e..d439b11cf9 100644
--- a/routers/web/org/projects.go
+++ b/routers/web/org/projects.go
@@ -7,7 +7,6 @@ import (
"errors"
"fmt"
"net/http"
- "net/url"
"strconv"
"strings"
@@ -195,14 +194,15 @@ func NewProjectPost(ctx *context.Context) {
// ChangeProjectStatus updates the status of a project between "open" and "close"
func ChangeProjectStatus(ctx *context.Context) {
- toClose := false
+ var toClose bool
switch ctx.Params(":action") {
case "open":
toClose = false
case "close":
toClose = true
default:
- ctx.Redirect(ctx.ContextUser.HomeLink() + "/-/projects")
+ ctx.JSONRedirect(ctx.ContextUser.HomeLink() + "/-/projects")
+ return
}
id := ctx.ParamsInt64(":id")
@@ -210,7 +210,7 @@ func ChangeProjectStatus(ctx *context.Context) {
ctx.NotFoundOrServerError("ChangeProjectStatusByRepoIDAndID", project_model.IsErrProjectNotExist, err)
return
}
- ctx.Redirect(ctx.ContextUser.HomeLink() + "/-/projects?state=" + url.QueryEscape(ctx.Params(":action")))
+ ctx.JSONRedirect(fmt.Sprintf("%s/-/projects/%d", ctx.ContextUser.HomeLink(), id))
}
// DeleteProject delete a project
diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go
index e4f2e9a2bc..1364d75676 100644
--- a/routers/web/repo/issue.go
+++ b/routers/web/repo/issue.go
@@ -3318,7 +3318,6 @@ func ChangeIssueReaction(ctx *context.Context) {
}
html, err := ctx.RenderToHTML(tplReactions, map[string]any{
- "ctxData": ctx.Data,
"ActionURL": fmt.Sprintf("%s/issues/%d/reactions", ctx.Repo.RepoLink, issue.Index),
"Reactions": issue.Reactions.GroupByType(),
})
@@ -3425,7 +3424,6 @@ func ChangeCommentReaction(ctx *context.Context) {
}
html, err := ctx.RenderToHTML(tplReactions, map[string]any{
- "ctxData": ctx.Data,
"ActionURL": fmt.Sprintf("%s/comments/%d/reactions", ctx.Repo.RepoLink, comment.ID),
"Reactions": comment.Reactions.GroupByType(),
})
diff --git a/routers/web/repo/projects.go b/routers/web/repo/projects.go
index a2db1fc770..9b765e89e8 100644
--- a/routers/web/repo/projects.go
+++ b/routers/web/repo/projects.go
@@ -7,7 +7,6 @@ import (
"errors"
"fmt"
"net/http"
- "net/url"
"strings"
"code.gitea.io/gitea/models/db"
@@ -181,14 +180,10 @@ func ChangeProjectStatus(ctx *context.Context) {
id := ctx.ParamsInt64(":id")
if err := project_model.ChangeProjectStatusByRepoIDAndID(ctx, ctx.Repo.Repository.ID, id, toClose); err != nil {
- if project_model.IsErrProjectNotExist(err) {
- ctx.NotFound("", err)
- } else {
- ctx.ServerError("ChangeProjectStatusByIDAndRepoID", err)
- }
+ ctx.NotFoundOrServerError("ChangeProjectStatusByRepoIDAndID", project_model.IsErrProjectNotExist, err)
return
}
- ctx.JSONRedirect(ctx.Repo.RepoLink + "/projects?state=" + url.QueryEscape(ctx.Params(":action")))
+ ctx.JSONRedirect(fmt.Sprintf("%s/projects/%d", ctx.Repo.RepoLink, id))
}
// DeleteProject delete a project
diff --git a/services/actions/auth_test.go b/services/actions/auth_test.go
index f73ae8ae4c..12db2bae56 100644
--- a/services/actions/auth_test.go
+++ b/services/actions/auth_test.go
@@ -20,7 +20,7 @@ func TestCreateAuthorizationToken(t *testing.T) {
assert.Nil(t, err)
assert.NotEqual(t, "", token)
claims := jwt.MapClaims{}
- _, err = jwt.ParseWithClaims(token, claims, func(t *jwt.Token) (interface{}, error) {
+ _, err = jwt.ParseWithClaims(token, claims, func(t *jwt.Token) (any, error) {
return setting.GetGeneralTokenSigningSecret(), nil
})
assert.Nil(t, err)
diff --git a/services/auth/source/oauth2/store.go b/services/auth/source/oauth2/store.go
index 394bf99463..90fa965602 100644
--- a/services/auth/source/oauth2/store.go
+++ b/services/auth/source/oauth2/store.go
@@ -9,6 +9,7 @@ import (
"net/http"
"code.gitea.io/gitea/modules/log"
+ session_module "code.gitea.io/gitea/modules/session"
chiSession "gitea.com/go-chi/session"
"github.com/gorilla/sessions"
@@ -65,7 +66,7 @@ func (st *SessionsStore) Save(r *http.Request, w http.ResponseWriter, session *s
chiStore := chiSession.GetSession(r)
if session.IsNew {
- _, _ = chiSession.RegenerateSession(w, r)
+ _, _ = session_module.RegenerateSession(w, r)
session.IsNew = false
}
diff --git a/services/context/api.go b/services/context/api.go
index b18a206b5e..c684add297 100644
--- a/services/context/api.go
+++ b/services/context/api.go
@@ -13,7 +13,7 @@ import (
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
- mc "code.gitea.io/gitea/modules/cache"
+ "code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/httpcache"
@@ -21,15 +21,13 @@ import (
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/web"
web_types "code.gitea.io/gitea/modules/web/types"
-
- "gitea.com/go-chi/cache"
)
// APIContext is a specific context for API service
type APIContext struct {
*Base
- Cache cache.Cache
+ Cache cache.StringCache
Doer *user_model.User // current signed-in user
IsSigned bool
@@ -217,7 +215,7 @@ func APIContexter() func(http.Handler) http.Handler {
base, baseCleanUp := NewBaseContext(w, req)
ctx := &APIContext{
Base: base,
- Cache: mc.GetCache(),
+ Cache: cache.GetCache(),
Repo: &Repository{PullRequest: &PullRequest{}},
Org: &APIOrganization{},
}
diff --git a/services/context/captcha.go b/services/context/captcha.go
index fa8d779f56..41afe0e7d2 100644
--- a/services/context/captcha.go
+++ b/services/context/captcha.go
@@ -30,7 +30,7 @@ func GetImageCaptcha() *captcha.Captcha {
cpt = captcha.NewCaptcha(captcha.Options{
SubURL: setting.AppSubURL,
})
- cpt.Store = cache.GetCache()
+ cpt.Store = cache.GetCache().ChiCache()
})
return cpt
}
diff --git a/services/context/context.go b/services/context/context.go
index 4b318f7e33..9d7787bf4b 100644
--- a/services/context/context.go
+++ b/services/context/context.go
@@ -17,7 +17,7 @@ import (
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
- mc "code.gitea.io/gitea/modules/cache"
+ "code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/httpcache"
"code.gitea.io/gitea/modules/setting"
@@ -27,7 +27,6 @@ import (
"code.gitea.io/gitea/modules/web/middleware"
web_types "code.gitea.io/gitea/modules/web/types"
- "gitea.com/go-chi/cache"
"gitea.com/go-chi/session"
)
@@ -46,7 +45,7 @@ type Context struct {
Render Render
PageData map[string]any // data used by JavaScript modules in one page, it's `window.config.pageData`
- Cache cache.Cache
+ Cache cache.StringCache
Csrf CSRFProtector
Flash *middleware.Flash
Session session.Store
@@ -102,6 +101,7 @@ func NewTemplateContextForWeb(ctx *Context) TemplateContext {
tmplCtx := NewTemplateContext(ctx)
tmplCtx["Locale"] = ctx.Base.Locale
tmplCtx["AvatarUtils"] = templates.NewAvatarUtils(ctx)
+ tmplCtx["RootData"] = ctx.Data
return tmplCtx
}
@@ -111,7 +111,7 @@ func NewWebContext(base *Base, render Render, session session.Store) *Context {
Render: render,
Session: session,
- Cache: mc.GetCache(),
+ Cache: cache.GetCache(),
Link: setting.AppSubURL + strings.TrimSuffix(base.Req.URL.EscapedPath(), "/"),
Repo: &Repository{PullRequest: &PullRequest{}},
Org: &Organization{},
diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go
index 21d5f08205..fa23986c54 100644
--- a/services/mirror/mirror_pull.go
+++ b/services/mirror/mirror_pull.go
@@ -13,6 +13,7 @@ import (
system_model "code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/git"
+ giturl "code.gitea.io/gitea/modules/git/url"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/log"
@@ -30,10 +31,15 @@ const gitShortEmptySha = "0000000"
// UpdateAddress writes new address to Git repository and database
func UpdateAddress(ctx context.Context, m *repo_model.Mirror, addr string) error {
+ u, err := giturl.Parse(addr)
+ if err != nil {
+ return fmt.Errorf("invalid addr: %v", err)
+ }
+
remoteName := m.GetRemoteName()
repoPath := m.GetRepository(ctx).RepoPath()
// Remove old remote
- _, _, err := git.NewCommand(ctx, "remote", "rm").AddDynamicArguments(remoteName).RunStdString(&git.RunOpts{Dir: repoPath})
+ _, _, err = git.NewCommand(ctx, "remote", "rm").AddDynamicArguments(remoteName).RunStdString(&git.RunOpts{Dir: repoPath})
if err != nil && !strings.HasPrefix(err.Error(), "exit status 128 - fatal: No such remote ") {
return err
}
@@ -70,7 +76,9 @@ func UpdateAddress(ctx context.Context, m *repo_model.Mirror, addr string) error
}
}
- m.Repo.OriginalURL = addr
+ // erase authentication before storing in database
+ u.User = nil
+ m.Repo.OriginalURL = u.String()
return repo_model.UpdateRepositoryCols(ctx, m.Repo, "original_url")
}
diff --git a/services/repository/branch.go b/services/repository/branch.go
index 229ac54f30..d74e5819a1 100644
--- a/services/repository/branch.go
+++ b/services/repository/branch.go
@@ -26,6 +26,7 @@ import (
"code.gitea.io/gitea/modules/queue"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/timeutil"
+ "code.gitea.io/gitea/modules/util"
webhook_module "code.gitea.io/gitea/modules/webhook"
notify_service "code.gitea.io/gitea/services/notify"
files_service "code.gitea.io/gitea/services/repository/files"
@@ -119,17 +120,15 @@ func getDivergenceCacheKey(repoID int64, branchName string) string {
// getDivergenceFromCache gets the divergence from cache
func getDivergenceFromCache(repoID int64, branchName string) (*git.DivergeObject, bool) {
- data := cache.GetCache().Get(getDivergenceCacheKey(repoID, branchName))
+ data, ok := cache.GetCache().Get(getDivergenceCacheKey(repoID, branchName))
res := git.DivergeObject{
Ahead: -1,
Behind: -1,
}
- s, ok := data.([]byte)
- if !ok || len(s) == 0 {
+ if !ok || data == "" {
return &res, false
}
-
- if err := json.Unmarshal(s, &res); err != nil {
+ if err := json.Unmarshal(util.UnsafeStringToBytes(data), &res); err != nil {
log.Error("json.UnMarshal failed: %v", err)
return &res, false
}
@@ -141,7 +140,7 @@ func putDivergenceFromCache(repoID int64, branchName string, divergence *git.Div
if err != nil {
return err
}
- return cache.GetCache().Put(getDivergenceCacheKey(repoID, branchName), bs, 30*24*60*60)
+ return cache.GetCache().Put(getDivergenceCacheKey(repoID, branchName), util.UnsafeBytesToString(bs), 30*24*60*60)
}
func DelDivergenceFromCache(repoID int64, branchName string) error {
diff --git a/services/repository/commitstatus/commitstatus.go b/services/repository/commitstatus/commitstatus.go
index 7c1c6c2609..8a62a603d4 100644
--- a/services/repository/commitstatus/commitstatus.go
+++ b/services/repository/commitstatus/commitstatus.go
@@ -34,7 +34,7 @@ type commitStatusCacheValue struct {
func getCommitStatusCache(repoID int64, branchName string) *commitStatusCacheValue {
c := cache.GetCache()
- statusStr, ok := c.Get(getCacheKey(repoID, branchName)).(string)
+ statusStr, ok := c.Get(getCacheKey(repoID, branchName))
if ok && statusStr != "" {
var cv commitStatusCacheValue
err := json.Unmarshal([]byte(statusStr), &cv)
diff --git a/services/repository/contributors_graph.go b/services/repository/contributors_graph.go
index 7c9f535ae0..b0d6de99ca 100644
--- a/services/repository/contributors_graph.go
+++ b/services/repository/contributors_graph.go
@@ -17,13 +17,12 @@ import (
"code.gitea.io/gitea/models/avatars"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
api "code.gitea.io/gitea/modules/structs"
-
- "gitea.com/go-chi/cache"
)
const (
@@ -79,13 +78,13 @@ func findLastSundayBeforeDate(dateStr string) (string, error) {
}
// GetContributorStats returns contributors stats for git commits for given revision or default branch
-func GetContributorStats(ctx context.Context, cache cache.Cache, repo *repo_model.Repository, revision string) (map[string]*ContributorData, error) {
+func GetContributorStats(ctx context.Context, cache cache.StringCache, repo *repo_model.Repository, revision string) (map[string]*ContributorData, error) {
// as GetContributorStats is resource intensive we cache the result
cacheKey := fmt.Sprintf(contributorStatsCacheKey, repo.FullName(), revision)
if !cache.IsExist(cacheKey) {
genReady := make(chan struct{})
- // dont start multible async generations
+ // dont start multiple async generations
_, run := generateLock.Load(cacheKey)
if run {
return nil, ErrAwaitGeneration
@@ -104,15 +103,11 @@ func GetContributorStats(ctx context.Context, cache cache.Cache, repo *repo_mode
}
}
// TODO: renew timeout of cache cache.UpdateTimeout(cacheKey, contributorStatsCacheTimeout)
-
- switch v := cache.Get(cacheKey).(type) {
- case error:
- return nil, v
- case map[string]*ContributorData:
- return v, nil
- default:
- return nil, fmt.Errorf("unexpected type in cache detected")
+ var res map[string]*ContributorData
+ if _, cacheErr := cache.GetJSON(cacheKey, &res); cacheErr != nil {
+ return nil, fmt.Errorf("cached error: %w", cacheErr.ToError())
}
+ return res, nil
}
// getExtendedCommitStats return the list of *ExtendedCommitStats for the given revision
@@ -205,13 +200,12 @@ func getExtendedCommitStats(repo *git.Repository, revision string /*, limit int
return extendedCommitStats, nil
}
-func generateContributorStats(genDone chan struct{}, cache cache.Cache, cacheKey string, repo *repo_model.Repository, revision string) {
+func generateContributorStats(genDone chan struct{}, cache cache.StringCache, cacheKey string, repo *repo_model.Repository, revision string) {
ctx := graceful.GetManager().HammerContext()
gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo)
if err != nil {
- err := fmt.Errorf("OpenRepository: %w", err)
- _ = cache.Put(cacheKey, err, contributorStatsCacheTimeout)
+ _ = cache.PutJSON(cacheKey, fmt.Errorf("OpenRepository: %w", err), contributorStatsCacheTimeout)
return
}
defer closer.Close()
@@ -221,13 +215,11 @@ func generateContributorStats(genDone chan struct{}, cache cache.Cache, cacheKey
}
extendedCommitStats, err := getExtendedCommitStats(gitRepo, revision)
if err != nil {
- err := fmt.Errorf("ExtendedCommitStats: %w", err)
- _ = cache.Put(cacheKey, err, contributorStatsCacheTimeout)
+ _ = cache.PutJSON(cacheKey, fmt.Errorf("ExtendedCommitStats: %w", err), contributorStatsCacheTimeout)
return
}
if len(extendedCommitStats) == 0 {
- err := fmt.Errorf("no commit stats returned for revision '%s'", revision)
- _ = cache.Put(cacheKey, err, contributorStatsCacheTimeout)
+ _ = cache.PutJSON(cacheKey, fmt.Errorf("no commit stats returned for revision '%s'", revision), contributorStatsCacheTimeout)
return
}
@@ -309,7 +301,7 @@ func generateContributorStats(genDone chan struct{}, cache cache.Cache, cacheKey
total.TotalCommits++
}
- _ = cache.Put(cacheKey, contributorsCommitStats, contributorStatsCacheTimeout)
+ _ = cache.PutJSON(cacheKey, contributorsCommitStats, contributorStatsCacheTimeout)
generateLock.Delete(cacheKey)
if genDone != nil {
genDone <- struct{}{}
diff --git a/services/repository/contributors_graph_test.go b/services/repository/contributors_graph_test.go
index 3801a5eee4..f22c115276 100644
--- a/services/repository/contributors_graph_test.go
+++ b/services/repository/contributors_graph_test.go
@@ -10,9 +10,9 @@ import (
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/cache"
+ "code.gitea.io/gitea/modules/setting"
- "gitea.com/go-chi/cache"
"github.com/stretchr/testify/assert"
)
@@ -20,20 +20,18 @@ func TestRepository_ContributorsGraph(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
assert.NoError(t, repo.LoadOwner(db.DefaultContext))
- mockCache, err := cache.NewCacher(cache.Options{
- Adapter: "memory",
- Interval: 24 * 60,
- })
+ mockCache, err := cache.NewStringCache(setting.Cache{})
assert.NoError(t, err)
generateContributorStats(nil, mockCache, "key", repo, "404ref")
- err, isErr := mockCache.Get("key").(error)
- assert.True(t, isErr)
- assert.ErrorAs(t, err, &git.ErrNotExist{})
+ var data map[string]*ContributorData
+ _, getErr := mockCache.GetJSON("key", &data)
+ assert.NotNil(t, getErr)
+ assert.ErrorContains(t, getErr.ToError(), "object does not exist")
generateContributorStats(nil, mockCache, "key2", repo, "master")
- data, isData := mockCache.Get("key2").(map[string]*ContributorData)
- assert.True(t, isData)
+ exist, _ := mockCache.GetJSON("key2", &data)
+ assert.True(t, exist)
var keys []string
for k := range data {
keys = append(keys, k)
diff --git a/templates/admin/notice.tmpl b/templates/admin/notice.tmpl
index 33d8a2f963..68703cc884 100644
--- a/templates/admin/notice.tmpl
+++ b/templates/admin/notice.tmpl
@@ -49,7 +49,7 @@
-