diff --git a/.eslintrc.yaml b/.eslintrc.yaml index 71d8dc38148db..8b9123c9884e7 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -22,7 +22,7 @@ plugins: - eslint-plugin-wc env: - es2022: true + es2024: true node: true overrides: @@ -156,7 +156,7 @@ rules: import/no-restricted-paths: [0] import/no-self-import: [2] import/no-unassigned-import: [0] - import/no-unresolved: [2, {commonjs: true, ignore: ["\\?.+$"]}] + import/no-unresolved: [2, {commonjs: true, ignore: [\?.+$, ^vitest/]}] import/no-unused-modules: [2, {unusedExports: true}] import/no-useless-path-segments: [2, {commonjs: true}] import/no-webpack-loader-syntax: [2] @@ -693,7 +693,7 @@ rules: unicorn/prefer-dom-node-remove: [2] unicorn/prefer-dom-node-text-content: [2] unicorn/prefer-event-target: [2] - unicorn/prefer-export-from: [2, {ignoreUsedVariables: true}] + unicorn/prefer-export-from: [0] unicorn/prefer-includes: [2] unicorn/prefer-json-parse-buffer: [0] unicorn/prefer-keyboard-event-key: [2] diff --git a/.golangci.yml b/.golangci.yml index 22de387facb29..7c35bdd2a8dad 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -77,16 +77,21 @@ linters-settings: extra-rules: true lang-version: "1.20" depguard: - list-type: denylist - # Check the list against standard lib. - include-go-root: true - packages-with-error-message: - - encoding/json: "use gitea's modules/json instead of encoding/json" - - github.com/unknwon/com: "use gitea's util and replacements" - - io/ioutil: "use os or io instead" - - golang.org/x/exp: "it's experimental and unreliable." - - code.gitea.io/gitea/modules/git/internal: "do not use the internal package, use AddXxx function instead" - - gopkg.in/ini.v1: "do not use the ini package, use gitea's config system instead" + rules: + main: + deny: + - pkg: encoding/json + desc: use gitea's modules/json instead of encoding/json + - pkg: github.com/unknwon/com + desc: use gitea's util and replacements + - pkg: io/ioutil + desc: use os or io instead + - pkg: golang.org/x/exp + desc: it's experimental and unreliable + - pkg: code.gitea.io/gitea/modules/git/internal + 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 issues: max-issues-per-linter: 0 diff --git a/MAINTAINERS b/MAINTAINERS index 3cdd8307e0585..ac7fb6d05a58c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -53,3 +53,4 @@ wxiaoguang (@wxiaoguang) Gary Moon (@garymoon) Philip Peterson (@philip-peterson) Denys Konovalov (@denyskon) +Punit Inani (@puni9869) diff --git a/Makefile b/Makefile index 0c4b42a8c5435..7de96f09fdd18 100644 --- a/Makefile +++ b/Makefile @@ -25,17 +25,17 @@ COMMA := , XGO_VERSION := go-1.20.x -AIR_PACKAGE ?= github.com/cosmtrek/air@v1.43.0 +AIR_PACKAGE ?= github.com/cosmtrek/air@v1.44.0 EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/cmd/editorconfig-checker@2.7.0 GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.5.0 -GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.52.2 +GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.53.3 GXZ_PAGAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11 MISSPELL_PACKAGE ?= github.com/client9/misspell/cmd/misspell@v0.3.4 -SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.30.4 +SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.30.5 XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1.6.0 -GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@latest -ACTIONLINT_PACKAGE ?= github.com/rhysd/actionlint/cmd/actionlint@latest +GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v0.2.0 +ACTIONLINT_PACKAGE ?= github.com/rhysd/actionlint/cmd/actionlint@v1.6.25 DOCKER_IMAGE ?= gitea/gitea DOCKER_TAG ?= latest diff --git a/contrib/environment-to-ini/environment-to-ini.go b/contrib/environment-to-ini/environment-to-ini.go index 230ed58269aab..e472384a950b4 100644 --- a/contrib/environment-to-ini/environment-to-ini.go +++ b/contrib/environment-to-ini/environment-to-ini.go @@ -5,7 +5,6 @@ package main import ( "os" - "strings" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -13,9 +12,6 @@ import ( "github.com/urfave/cli" ) -// EnvironmentPrefix environment variables prefixed with this represent ini values to write -const EnvironmentPrefix = "GITEA" - func main() { app := cli.NewApp() app.Name = "environment-to-ini" @@ -70,15 +66,6 @@ func main() { Value: "", Usage: "Destination file to write to", }, - cli.BoolFlag{ - Name: "clear", - Usage: "Clears the matched variables from the environment", - }, - cli.StringFlag{ - Name: "prefix, p", - Value: EnvironmentPrefix, - Usage: "Environment prefix to look for - will be suffixed by __ (2 underscores)", - }, } app.Action = runEnvironmentToIni err := app.Run(os.Args) @@ -99,9 +86,7 @@ func runEnvironmentToIni(c *cli.Context) error { log.Fatal("Failed to load custom conf '%s': %v", setting.CustomConf, err) } - prefixGitea := c.String("prefix") + "__" - suffixFile := "__FILE" - changed := setting.EnvironmentToConfig(cfg, prefixGitea, suffixFile, os.Environ()) + changed := setting.EnvironmentToConfig(cfg, os.Environ()) // try to save the config file destination := c.String("out") @@ -116,19 +101,5 @@ func runEnvironmentToIni(c *cli.Context) error { } } - // clear Gitea's specific environment variables if requested - if c.Bool("clear") { - for _, kv := range os.Environ() { - idx := strings.IndexByte(kv, '=') - if idx < 0 { - continue - } - eKey := kv[:idx] - if strings.HasPrefix(eKey, prefixGitea) { - _ = os.Unsetenv(eKey) - } - } - } - return nil } diff --git a/docker/root/usr/local/bin/gitea b/docker/root/usr/local/bin/gitea index 24d3f91eb15de..3f78d65abd0f3 100644 --- a/docker/root/usr/local/bin/gitea +++ b/docker/root/usr/local/bin/gitea @@ -8,7 +8,7 @@ # # And place the original in /usr/lib/gitea with working files in /data/gitea GITEA="/app/gitea/gitea" -WORK_DIR="/app/gitea" +WORK_DIR="/data/gitea" CUSTOM_PATH="/data/gitea" # Provide docker defaults diff --git a/docs/content/doc/installation/with-docker-rootless.en-us.md b/docs/content/doc/installation/with-docker-rootless.en-us.md index b8c76438f9f68..5aa4e46e12c87 100644 --- a/docs/content/doc/installation/with-docker-rootless.en-us.md +++ b/docs/content/doc/installation/with-docker-rootless.en-us.md @@ -119,7 +119,7 @@ services: - /etc/localtime:/etc/localtime:ro ports: - "3000:3000" - - "222:22" + - "2222:2222" + depends_on: + - db + @@ -288,7 +288,7 @@ docker-compose up -d In addition to the environment variables above, any settings in `app.ini` can be set or overridden with an environment variable of the form: `GITEA__SECTION_NAME__KEY_NAME`. -These settings are applied each time the docker container starts. +These settings are applied each time the docker container starts, and won't be passed into Gitea's sub-processes. Full information [here](https://github.com/go-gitea/gitea/tree/main/contrib/environment-to-ini). These environment variables can be passed to the docker container in `docker-compose.yml`. diff --git a/docs/content/doc/installation/with-docker.en-us.md b/docs/content/doc/installation/with-docker.en-us.md index e70a6ab1331fd..a7a575293d3ce 100644 --- a/docs/content/doc/installation/with-docker.en-us.md +++ b/docs/content/doc/installation/with-docker.en-us.md @@ -289,7 +289,7 @@ docker-compose up -d In addition to the environment variables above, any settings in `app.ini` can be set or overridden with an environment variable of the form: `GITEA__SECTION_NAME__KEY_NAME`. -These settings are applied each time the docker container starts. +These settings are applied each time the docker container starts, and won't be passed into Gitea's sub-processes. Full information [here](https://github.com/go-gitea/gitea/tree/master/contrib/environment-to-ini). These environment variables can be passed to the docker container in `docker-compose.yml`. diff --git a/models/activities/notification.go b/models/activities/notification.go index 75276a04434f8..e0af2ee8bbf56 100644 --- a/models/activities/notification.go +++ b/models/activities/notification.go @@ -343,7 +343,7 @@ func getIssueNotification(ctx context.Context, userID, issueID int64) (*Notifica // NotificationsForUser returns notifications for a given user and status func NotificationsForUser(ctx context.Context, user *user_model.User, statuses []NotificationStatus, page, perPage int) (notifications NotificationList, err error) { if len(statuses) == 0 { - return + return nil, nil } sess := db.GetEngine(ctx). @@ -372,16 +372,16 @@ func CountUnread(ctx context.Context, userID int64) int64 { // LoadAttributes load Repo Issue User and Comment if not loaded func (n *Notification) LoadAttributes(ctx context.Context) (err error) { if err = n.loadRepo(ctx); err != nil { - return + return err } if err = n.loadIssue(ctx); err != nil { - return + return err } if err = n.loadUser(ctx); err != nil { - return + return err } if err = n.loadComment(ctx); err != nil { - return + return err } return err } diff --git a/models/asymkey/gpg_key_commit_verification.go b/models/asymkey/gpg_key_commit_verification.go index db6e78cad522c..65af0bc94532b 100644 --- a/models/asymkey/gpg_key_commit_verification.go +++ b/models/asymkey/gpg_key_commit_verification.go @@ -455,9 +455,9 @@ func hashAndVerifyForKeyID(sig *packet.Signature, payload string, committer *use // CalculateTrustStatus will calculate the TrustStatus for a commit verification within a repository // There are several trust models in Gitea -func CalculateTrustStatus(verification *CommitVerification, repoTrustModel repo_model.TrustModelType, isOwnerMemberCollaborator func(*user_model.User) (bool, error), keyMap *map[string]bool) (err error) { +func CalculateTrustStatus(verification *CommitVerification, repoTrustModel repo_model.TrustModelType, isOwnerMemberCollaborator func(*user_model.User) (bool, error), keyMap *map[string]bool) error { if !verification.Verified { - return + return nil } // In the Committer trust model a signature is trusted if it matches the committer @@ -475,7 +475,7 @@ func CalculateTrustStatus(verification *CommitVerification, repoTrustModel repo_ verification.SigningUser.Email == verification.CommittingUser.Email) { verification.TrustStatus = "trusted" } - return + return nil } // Now we drop to the more nuanced trust models... @@ -490,10 +490,11 @@ func CalculateTrustStatus(verification *CommitVerification, repoTrustModel repo_ verification.SigningUser.Email != verification.CommittingUser.Email) { verification.TrustStatus = "untrusted" } - return + return nil } // Check we actually have a GPG SigningKey + var err error if verification.SigningKey != nil { var isMember bool if keyMap != nil { diff --git a/models/asymkey/gpg_key_common.go b/models/asymkey/gpg_key_common.go index 5ceeee9aacf79..b02be2851a75e 100644 --- a/models/asymkey/gpg_key_common.go +++ b/models/asymkey/gpg_key_common.go @@ -111,7 +111,7 @@ func populateHash(hashFunc crypto.Hash, msg []byte) (hash.Hash, error) { func readArmoredSign(r io.Reader) (body io.Reader, err error) { block, err := armor.Decode(r) if err != nil { - return + return nil, err } if block.Type != openpgp.SignatureType { return nil, fmt.Errorf("expected '" + openpgp.SignatureType + "', got: " + block.Type) diff --git a/models/auth/oauth2.go b/models/auth/oauth2.go index 53a5c28b4a59e..0f64b56c1635b 100644 --- a/models/auth/oauth2.go +++ b/models/auth/oauth2.go @@ -306,9 +306,10 @@ func (code *OAuth2AuthorizationCode) TableName() string { } // GenerateRedirectURI generates a redirect URI for a successful authorization request. State will be used if not empty. -func (code *OAuth2AuthorizationCode) GenerateRedirectURI(state string) (redirect *url.URL, err error) { - if redirect, err = url.Parse(code.RedirectURI); err != nil { - return +func (code *OAuth2AuthorizationCode) GenerateRedirectURI(state string) (*url.URL, error) { + redirect, err := url.Parse(code.RedirectURI) + if err != nil { + return nil, err } q := redirect.Query() if state != "" { diff --git a/models/fixtures/org_user.yml b/models/fixtures/org_user.yml index d08f69579913e..8d58169a32f17 100644 --- a/models/fixtures/org_user.yml +++ b/models/fixtures/org_user.yml @@ -81,3 +81,21 @@ uid: 5 org_id: 23 is_public: false + +- + id: 15 + uid: 1 + org_id: 35 + is_public: true + +- + id: 16 + uid: 1 + org_id: 36 + is_public: true + +- + id: 17 + uid: 5 + org_id: 36 + is_public: true diff --git a/models/fixtures/team.yml b/models/fixtures/team.yml index aa3b36e644399..65326eedbf476 100644 --- a/models/fixtures/team.yml +++ b/models/fixtures/team.yml @@ -184,3 +184,36 @@ num_members: 1 includes_all_repositories: false can_create_org_repo: true + +- + id: 18 + org_id: 35 + lower_name: owners + name: Owners + authorize: 4 # owner + num_repos: 0 + num_members: 1 + includes_all_repositories: false + can_create_org_repo: true + +- + id: 19 + org_id: 36 + lower_name: owners + name: Owners + authorize: 4 # owner + num_repos: 0 + num_members: 1 + includes_all_repositories: false + can_create_org_repo: true + +- + id: 20 + org_id: 36 + lower_name: team20writepackage + name: team20writepackage + authorize: 1 + num_repos: 0 + num_members: 1 + includes_all_repositories: false + can_create_org_repo: true diff --git a/models/fixtures/team_unit.yml b/models/fixtures/team_unit.yml index 5257d2c3856d3..5d2ba2fb6cbd7 100644 --- a/models/fixtures/team_unit.yml +++ b/models/fixtures/team_unit.yml @@ -273,4 +273,10 @@ id: 46 team_id: 17 type: 9 # package - access_mode: 0 + access_mode: 2 + +- + id: 47 + team_id: 20 + type: 9 # package + access_mode: 2 diff --git a/models/fixtures/team_user.yml b/models/fixtures/team_user.yml index b95f76c72376b..feace5f2a531d 100644 --- a/models/fixtures/team_user.yml +++ b/models/fixtures/team_user.yml @@ -105,3 +105,21 @@ org_id: 23 team_id: 17 uid: 5 + +- + id: 19 + org_id: 35 + team_id: 18 + uid: 1 + +- + id: 20 + org_id: 36 + team_id: 19 + uid: 1 + +- + id: 21 + org_id: 36 + team_id: 20 + uid: 5 diff --git a/models/fixtures/user.yml b/models/fixtures/user.yml index eba33a7c36369..26bb7a9f4ba89 100644 --- a/models/fixtures/user.yml +++ b/models/fixtures/user.yml @@ -1258,3 +1258,77 @@ repo_admin_change_team_access: false theme: "" keep_activity_private: false + +- + id: 35 + lower_name: private_org35 + name: private_org35 + full_name: Private Org 35 + email: private_org35@example.com + keep_email_private: false + email_notifications_preference: enabled + passwd: ZogKvWdyEx:password + passwd_hash_algo: dummy + must_change_password: false + login_source: 0 + login_name: private_org35 + type: 1 + salt: ZogKvWdyEx + max_repo_creation: -1 + is_active: true + is_admin: false + is_restricted: false + allow_git_hook: false + allow_import_local: false + allow_create_organization: true + prohibit_login: false + avatar: avatar35 + avatar_email: private_org35@example.com + use_custom_avatar: false + num_followers: 0 + num_following: 0 + num_stars: 0 + num_repos: 0 + num_teams: 1 + num_members: 1 + visibility: 2 + repo_admin_change_team_access: false + theme: "" + keep_activity_private: false + +- + id: 36 + lower_name: limited_org36 + name: limited_org36 + full_name: Limited Org 36 + email: limited_org36@example.com + keep_email_private: false + email_notifications_preference: enabled + passwd: ZogKvWdyEx:password + passwd_hash_algo: dummy + must_change_password: false + login_source: 0 + login_name: limited_org36 + type: 1 + salt: ZogKvWdyEx + max_repo_creation: -1 + is_active: true + is_admin: false + is_restricted: false + allow_git_hook: false + allow_import_local: false + allow_create_organization: true + prohibit_login: false + avatar: avatar22 + avatar_email: limited_org36@example.com + use_custom_avatar: false + num_followers: 0 + num_following: 0 + num_stars: 0 + num_repos: 0 + num_teams: 2 + num_members: 2 + visibility: 1 + repo_admin_change_team_access: false + theme: "" + keep_activity_private: false diff --git a/models/git/branch.go b/models/git/branch.go index 5e995449586d6..97891f01ebb40 100644 --- a/models/git/branch.go +++ b/models/git/branch.go @@ -15,6 +15,8 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" + + "xorm.io/builder" ) // ErrBranchNotExist represents an error that branch with such name does not exist. @@ -378,3 +380,22 @@ func RenameBranch(ctx context.Context, repo *repo_model.Repository, from, to str return committer.Commit() } + +// FindRecentlyPushedNewBranches return at most 2 new branches pushed by the user in 6 hours which has no opened PRs created +func FindRecentlyPushedNewBranches(ctx context.Context, repoID, userID int64) (BranchList, error) { + branches := make(BranchList, 0, 2) + subQuery := builder.Select("head_branch").From("pull_request"). + InnerJoin("issue", "issue.id = pull_request.issue_id"). + Where(builder.Eq{ + "pull_request.head_repo_id": repoID, + "issue.is_closed": false, + }) + err := db.GetEngine(ctx). + Where("pusher_id=? AND is_deleted=?", userID, false). + And("updated_unix >= ?", time.Now().Add(-time.Hour*6).Unix()). + NotIn("name", subQuery). + OrderBy("branch.updated_unix DESC"). + Limit(2). + Find(&branches) + return branches, err +} diff --git a/models/issues/comment.go b/models/issues/comment.go index 303c23916ba2a..be020b2e1fb2d 100644 --- a/models/issues/comment.go +++ b/models/issues/comment.go @@ -749,7 +749,7 @@ func (c *Comment) LoadPushCommits(ctx context.Context) (err error) { err = json.Unmarshal([]byte(c.Content), &data) if err != nil { - return + return err } c.IsForcePush = data.IsForcePush @@ -925,7 +925,7 @@ func createIssueDependencyComment(ctx context.Context, doer *user_model.User, is cType = CommentTypeRemoveDependency } if err = issue.LoadRepo(ctx); err != nil { - return + return err } // Make two comments, one in each issue @@ -937,7 +937,7 @@ func createIssueDependencyComment(ctx context.Context, doer *user_model.User, is DependentIssueID: dependentIssue.ID, } if _, err = CreateComment(ctx, opts); err != nil { - return + return err } opts = &CreateCommentOptions{ @@ -1170,11 +1170,11 @@ func CreateAutoMergeComment(ctx context.Context, typ CommentType, pr *PullReques return nil, fmt.Errorf("comment type %d cannot be used to create an auto merge comment", typ) } if err = pr.LoadIssue(ctx); err != nil { - return + return nil, err } if err = pr.LoadBaseRepo(ctx); err != nil { - return + return nil, err } comment, err = CreateComment(ctx, &CreateCommentOptions{ diff --git a/models/issues/comment_list.go b/models/issues/comment_list.go index 477337443ddf8..e9c8406c3a51e 100644 --- a/models/issues/comment_list.go +++ b/models/issues/comment_list.go @@ -468,42 +468,38 @@ func (comments CommentList) loadReviews(ctx context.Context) error { // loadAttributes loads all attributes func (comments CommentList) loadAttributes(ctx context.Context) (err error) { if err = comments.LoadPosters(ctx); err != nil { - return + return err } if err = comments.loadLabels(ctx); err != nil { - return + return err } if err = comments.loadMilestones(ctx); err != nil { - return + return err } if err = comments.loadOldMilestones(ctx); err != nil { - return + return err } if err = comments.loadAssignees(ctx); err != nil { - return + return err } if err = comments.LoadAttachments(ctx); err != nil { - return + return err } if err = comments.loadReviews(ctx); err != nil { - return + return err } if err = comments.LoadIssues(ctx); err != nil { - return - } - - if err = comments.loadDependentIssues(ctx); err != nil { - return + return err } - return nil + return comments.loadDependentIssues(ctx) } // LoadAttributes loads attributes of the comments, except for attachments and diff --git a/models/issues/issue.go b/models/issues/issue.go index 364d53ba318c3..d0c5ad2bf8603 100644 --- a/models/issues/issue.go +++ b/models/issues/issue.go @@ -222,8 +222,7 @@ func (issue *Issue) LoadPoster(ctx context.Context) (err error) { if !user_model.IsErrUserNotExist(err) { return fmt.Errorf("getUserByID.(poster) [%d]: %w", issue.PosterID, err) } - err = nil - return + return nil } } return err @@ -316,27 +315,27 @@ func (issue *Issue) LoadMilestone(ctx context.Context) (err error) { // LoadAttributes loads the attribute of this issue. func (issue *Issue) LoadAttributes(ctx context.Context) (err error) { if err = issue.LoadRepo(ctx); err != nil { - return + return err } if err = issue.LoadPoster(ctx); err != nil { - return + return err } if err = issue.LoadLabels(ctx); err != nil { - return + return err } if err = issue.LoadMilestone(ctx); err != nil { - return + return err } if err = issue.LoadProject(ctx); err != nil { - return + return err } if err = issue.LoadAssignees(ctx); err != nil { - return + return err } if err = issue.LoadPullRequest(ctx); err != nil && !IsErrPullRequestNotExist(err) { diff --git a/models/issues/issue_label.go b/models/issues/issue_label.go index f4060b140260f..119a13adf2227 100644 --- a/models/issues/issue_label.go +++ b/models/issues/issue_label.go @@ -39,7 +39,7 @@ func newIssueLabel(ctx context.Context, issue *Issue, label *Label, doer *user_m } if err = issue.LoadRepo(ctx); err != nil { - return + return err } opts := &CreateCommentOptions{ @@ -168,7 +168,7 @@ func deleteIssueLabel(ctx context.Context, issue *Issue, label *Label, doer *use } if err = issue.LoadRepo(ctx); err != nil { - return + return err } opts := &CreateCommentOptions{ diff --git a/models/issues/issue_update.go b/models/issues/issue_update.go index 9453ddc085d4d..9607b21a67585 100644 --- a/models/issues/issue_update.go +++ b/models/issues/issue_update.go @@ -538,10 +538,10 @@ func FindAndUpdateIssueMentions(ctx context.Context, issue *Issue, doer *user_mo // don't have access to reading it. Teams are expanded into their users, but organizations are ignored. func ResolveIssueMentionsByVisibility(ctx context.Context, issue *Issue, doer *user_model.User, mentions []string) (users []*user_model.User, err error) { if len(mentions) == 0 { - return + return nil, nil } if err = issue.LoadRepo(ctx); err != nil { - return + return nil, err } resolved := make(map[string]bool, 10) @@ -635,7 +635,7 @@ func ResolveIssueMentionsByVisibility(ctx context.Context, issue *Issue, doer *u } } if len(mentionUsers) == 0 { - return + return users, err } if users == nil { @@ -702,66 +702,66 @@ func DeleteIssuesByRepoID(ctx context.Context, repoID int64) (attachmentPaths [] // Delete content histories if _, err = sess.In("issue_id", deleteCond). Delete(&ContentHistory{}); err != nil { - return + return nil, err } // Delete comments and attachments if _, err = sess.In("issue_id", deleteCond). Delete(&Comment{}); err != nil { - return + return nil, err } // Dependencies for issues in this repository if _, err = sess.In("issue_id", deleteCond). Delete(&IssueDependency{}); err != nil { - return + return nil, err } // Delete dependencies for issues in other repositories if _, err = sess.In("dependency_id", deleteCond). Delete(&IssueDependency{}); err != nil { - return + return nil, err } if _, err = sess.In("issue_id", deleteCond). Delete(&IssueUser{}); err != nil { - return + return nil, err } if _, err = sess.In("issue_id", deleteCond). Delete(&Reaction{}); err != nil { - return + return nil, err } if _, err = sess.In("issue_id", deleteCond). Delete(&IssueWatch{}); err != nil { - return + return nil, err } if _, err = sess.In("issue_id", deleteCond). Delete(&Stopwatch{}); err != nil { - return + return nil, err } if _, err = sess.In("issue_id", deleteCond). Delete(&TrackedTime{}); err != nil { - return + return nil, err } if _, err = sess.In("issue_id", deleteCond). Delete(&project_model.ProjectIssue{}); err != nil { - return + return nil, err } if _, err = sess.In("dependent_issue_id", deleteCond). Delete(&Comment{}); err != nil { - return + return nil, err } var attachments []*repo_model.Attachment if err = sess.In("issue_id", deleteCond). Find(&attachments); err != nil { - return + return nil, err } for j := range attachments { @@ -770,11 +770,11 @@ func DeleteIssuesByRepoID(ctx context.Context, repoID int64) (attachmentPaths [] if _, err = sess.In("issue_id", deleteCond). Delete(&repo_model.Attachment{}); err != nil { - return + return nil, err } if _, err = db.DeleteByBean(ctx, &Issue{RepoID: repoID}); err != nil { - return + return nil, err } return attachmentPaths, err diff --git a/models/issues/review.go b/models/issues/review.go index dbacfa3a8785d..3ec2c00fe99b9 100644 --- a/models/issues/review.go +++ b/models/issues/review.go @@ -136,10 +136,10 @@ func init() { // LoadCodeComments loads CodeComments func (r *Review) LoadCodeComments(ctx context.Context) (err error) { if r.CodeComments != nil { - return + return err } if err = r.loadIssue(ctx); err != nil { - return + return err } r.CodeComments, err = fetchCodeCommentsByReview(ctx, r.Issue, nil, r, false) return err @@ -147,7 +147,7 @@ func (r *Review) LoadCodeComments(ctx context.Context) (err error) { func (r *Review) loadIssue(ctx context.Context) (err error) { if r.Issue != nil { - return + return err } r.Issue, err = GetIssueByID(ctx, r.IssueID) return err @@ -156,7 +156,7 @@ func (r *Review) loadIssue(ctx context.Context) (err error) { // LoadReviewer loads reviewer func (r *Review) LoadReviewer(ctx context.Context) (err error) { if r.ReviewerID == 0 || r.Reviewer != nil { - return + return err } r.Reviewer, err = user_model.GetPossibleUserByID(ctx, r.ReviewerID) return err @@ -186,7 +186,7 @@ func LoadReviewers(ctx context.Context, reviews []*Review) (err error) { // LoadReviewerTeam loads reviewer team func (r *Review) LoadReviewerTeam(ctx context.Context) (err error) { if r.ReviewerTeamID == 0 || r.ReviewerTeam != nil { - return + return nil } r.ReviewerTeam, err = organization.GetTeamByID(ctx, r.ReviewerTeamID) @@ -196,16 +196,16 @@ func (r *Review) LoadReviewerTeam(ctx context.Context) (err error) { // LoadAttributes loads all attributes except CodeComments func (r *Review) LoadAttributes(ctx context.Context) (err error) { if err = r.loadIssue(ctx); err != nil { - return + return err } if err = r.LoadCodeComments(ctx); err != nil { - return + return err } if err = r.LoadReviewer(ctx); err != nil { - return + return err } if err = r.LoadReviewerTeam(ctx); err != nil { - return + return err } return err } diff --git a/models/issues/tracked_time.go b/models/issues/tracked_time.go index 1d7592926bc5c..d117b74bc037e 100644 --- a/models/issues/tracked_time.go +++ b/models/issues/tracked_time.go @@ -302,7 +302,7 @@ func DeleteTime(t *TrackedTime) error { func deleteTimes(ctx context.Context, opts FindTrackedTimesOptions) (removedTime int64, err error) { removedTime, err = GetTrackedSeconds(ctx, opts) if err != nil || removedTime == 0 { - return + return removedTime, err } _, err = opts.toSession(db.GetEngine(ctx)).Table("tracked_time").Cols("deleted").Update(&TrackedTime{Deleted: true}) diff --git a/models/migrations/v1_11/v106.go b/models/migrations/v1_11/v106.go index 3e06309a8d8ec..18d436ae20cf0 100644 --- a/models/migrations/v1_11/v106.go +++ b/models/migrations/v1_11/v106.go @@ -16,10 +16,10 @@ type Watch struct { Mode RepoWatchMode `xorm:"SMALLINT NOT NULL DEFAULT 1"` } -func AddModeColumnToWatch(x *xorm.Engine) (err error) { - if err = x.Sync2(new(Watch)); err != nil { - return +func AddModeColumnToWatch(x *xorm.Engine) error { + if err := x.Sync2(new(Watch)); err != nil { + return err } - _, err = x.Exec("UPDATE `watch` SET `mode` = 1") + _, err := x.Exec("UPDATE `watch` SET `mode` = 1") return err } diff --git a/models/migrations/v1_13/v143.go b/models/migrations/v1_13/v143.go index ad1a8c66a5d15..885768dff37de 100644 --- a/models/migrations/v1_13/v143.go +++ b/models/migrations/v1_13/v143.go @@ -23,25 +23,25 @@ func RecalculateStars(x *xorm.Engine) (err error) { for start := 0; ; start += batchSize { users := make([]User, 0, batchSize) - if err = sess.Limit(batchSize, start).Where("type = ?", 0).Cols("id").Find(&users); err != nil { - return + if err := sess.Limit(batchSize, start).Where("type = ?", 0).Cols("id").Find(&users); err != nil { + return err } if len(users) == 0 { break } - if err = sess.Begin(); err != nil { - return + if err := sess.Begin(); err != nil { + return err } for _, user := range users { - if _, err = sess.Exec("UPDATE `user` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE uid=?) WHERE id=?", user.ID, user.ID); err != nil { - return + if _, err := sess.Exec("UPDATE `user` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE uid=?) WHERE id=?", user.ID, user.ID); err != nil { + return err } } - if err = sess.Commit(); err != nil { - return + if err := sess.Commit(); err != nil { + return err } } diff --git a/models/migrations/v1_14/v166.go b/models/migrations/v1_14/v166.go index de7626076a95d..78f33e8f9bddb 100644 --- a/models/migrations/v1_14/v166.go +++ b/models/migrations/v1_14/v166.go @@ -78,14 +78,14 @@ func RecalculateUserEmptyPWD(x *xorm.Engine) (err error) { for start := 0; ; start += batchSize { users := make([]*User, 0, batchSize) if err = sess.Limit(batchSize, start).Where(builder.Neq{"passwd": ""}, 0).Find(&users); err != nil { - return + return err } if len(users) == 0 { break } if err = sess.Begin(); err != nil { - return + return err } for _, user := range users { @@ -100,7 +100,7 @@ func RecalculateUserEmptyPWD(x *xorm.Engine) (err error) { } if err = sess.Commit(); err != nil { - return + return err } } diff --git a/models/migrations/v1_15/v180.go b/models/migrations/v1_15/v180.go index 17163ee2c683f..c71e77186170c 100644 --- a/models/migrations/v1_15/v180.go +++ b/models/migrations/v1_15/v180.go @@ -44,25 +44,25 @@ func DeleteMigrationCredentials(x *xorm.Engine) (err error) { for start := 0; ; start += batchSize { tasks := make([]*Task, 0, batchSize) - if err = sess.Limit(batchSize, start).Where(cond, 0).Find(&tasks); err != nil { - return + if err := sess.Limit(batchSize, start).Where(cond, 0).Find(&tasks); err != nil { + return err } if len(tasks) == 0 { break } - if err = sess.Begin(); err != nil { - return + if err := sess.Begin(); err != nil { + return err } for _, t := range tasks { if t.PayloadContent, err = removeCredentials(t.PayloadContent); err != nil { - return + return err } - if _, err = sess.ID(t.ID).Cols("payload_content").Update(t); err != nil { - return + if _, err := sess.ID(t.ID).Cols("payload_content").Update(t); err != nil { + return err } } - if err = sess.Commit(); err != nil { - return + if err := sess.Commit(); err != nil { + return err } } return err diff --git a/models/migrations/v1_15/v181.go b/models/migrations/v1_15/v181.go index e2bb3208c41d8..f4dd1d6016cd7 100644 --- a/models/migrations/v1_15/v181.go +++ b/models/migrations/v1_15/v181.go @@ -9,7 +9,7 @@ import ( "xorm.io/xorm" ) -func AddPrimaryEmail2EmailAddress(x *xorm.Engine) (err error) { +func AddPrimaryEmail2EmailAddress(x *xorm.Engine) error { type User struct { ID int64 `xorm:"pk autoincr"` Email string `xorm:"NOT NULL"` @@ -26,12 +26,12 @@ func AddPrimaryEmail2EmailAddress(x *xorm.Engine) (err error) { } // Add lower_email and is_primary columns - if err = x.Table("email_address").Sync2(new(EmailAddress1)); err != nil { - return + if err := x.Table("email_address").Sync2(new(EmailAddress1)); err != nil { + return err } - if _, err = x.Exec("UPDATE email_address SET lower_email=LOWER(email), is_primary=?", false); err != nil { - return + if _, err := x.Exec("UPDATE email_address SET lower_email=LOWER(email), is_primary=?", false); err != nil { + return err } type EmailAddress struct { @@ -44,8 +44,8 @@ func AddPrimaryEmail2EmailAddress(x *xorm.Engine) (err error) { } // change lower_email as unique - if err = x.Sync2(new(EmailAddress)); err != nil { - return + if err := x.Sync2(new(EmailAddress)); err != nil { + return err } sess := x.NewSession() @@ -55,34 +55,33 @@ func AddPrimaryEmail2EmailAddress(x *xorm.Engine) (err error) { for start := 0; ; start += batchSize { users := make([]*User, 0, batchSize) - if err = sess.Limit(batchSize, start).Find(&users); err != nil { - return + if err := sess.Limit(batchSize, start).Find(&users); err != nil { + return err } if len(users) == 0 { break } for _, user := range users { - var exist bool - exist, err = sess.Where("email=?", user.Email).Table("email_address").Exist() + exist, err := sess.Where("email=?", user.Email).Table("email_address").Exist() if err != nil { - return + return err } if !exist { - if _, err = sess.Insert(&EmailAddress{ + if _, err := sess.Insert(&EmailAddress{ UID: user.ID, Email: user.Email, LowerEmail: strings.ToLower(user.Email), IsActivated: user.IsActive, IsPrimary: true, }); err != nil { - return + return err } } else { - if _, err = sess.Where("email=?", user.Email).Cols("is_primary").Update(&EmailAddress{ + if _, err := sess.Where("email=?", user.Email).Cols("is_primary").Update(&EmailAddress{ IsPrimary: true, }); err != nil { - return + return err } } } diff --git a/models/packages/package_blob.go b/models/packages/package_blob.go index a55109af964a6..d1f470d5205a8 100644 --- a/models/packages/package_blob.go +++ b/models/packages/package_blob.go @@ -5,11 +5,18 @@ package packages import ( "context" + "strconv" "time" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/perm" + "code.gitea.io/gitea/models/unit" + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" + + "xorm.io/builder" ) // ErrPackageBlobNotExist indicates a package blob not exist error @@ -98,3 +105,42 @@ func GetTotalUnreferencedBlobSize(ctx context.Context) (int64, error) { Where("package_file.id IS NULL"). SumInt(&PackageBlob{}, "size") } + +// IsBlobAccessibleForUser tests if the user has access to the blob +func IsBlobAccessibleForUser(ctx context.Context, blobID int64, user *user_model.User) (bool, error) { + if user.IsAdmin { + return true, nil + } + + maxTeamAuthorize := builder. + Select("max(team.authorize)"). + From("team"). + InnerJoin("team_user", "team_user.team_id = team.id"). + Where(builder.Eq{"team_user.uid": user.ID}.And(builder.Expr("team_user.org_id = `user`.id"))) + + maxTeamUnitAccessMode := builder. + Select("max(team_unit.access_mode)"). + From("team"). + InnerJoin("team_user", "team_user.team_id = team.id"). + InnerJoin("team_unit", "team_unit.team_id = team.id"). + Where(builder.Eq{"team_user.uid": user.ID, "team_unit.type": unit.TypePackages}.And(builder.Expr("team_user.org_id = `user`.id"))) + + cond := builder.Eq{"package_blob.id": blobID}.And( + // owner = user + builder.Eq{"`user`.id": user.ID}. + // user can see owner + Or(builder.Eq{"`user`.visibility": structs.VisibleTypePublic}.Or(builder.Eq{"`user`.visibility": structs.VisibleTypeLimited})). + // owner is an organization and user has access to it + Or(builder.Eq{"`user`.type": user_model.UserTypeOrganization}. + And(builder.Lte{strconv.Itoa(int(perm.AccessModeRead)): maxTeamAuthorize}.Or(builder.Lte{strconv.Itoa(int(perm.AccessModeRead)): maxTeamUnitAccessMode}))), + ) + + return db.GetEngine(ctx). + Table("package_blob"). + Join("INNER", "package_file", "package_file.blob_id = package_blob.id"). + Join("INNER", "package_version", "package_version.id = package_file.version_id"). + Join("INNER", "package", "package.id = package_version.package_id"). + Join("INNER", "user", "`user`.id = package.owner_id"). + Where(cond). + Exist(&PackageBlob{}) +} diff --git a/models/repo.go b/models/repo.go index 9044fc8aedbc3..7579d2ad7348b 100644 --- a/models/repo.go +++ b/models/repo.go @@ -628,14 +628,14 @@ func DoctorUserStarNum() (err error) { for start := 0; ; start += batchSize { users := make([]user_model.User, 0, batchSize) if err = db.GetEngine(db.DefaultContext).Limit(batchSize, start).Where("type = ?", 0).Cols("id").Find(&users); err != nil { - return + return err } if len(users) == 0 { break } if err = updateUserStarNumbers(users); err != nil { - return + return err } } diff --git a/models/repo/git.go b/models/repo/git.go index 7ae88058dc861..c1af7ee9608b4 100644 --- a/models/repo/git.go +++ b/models/repo/git.go @@ -11,7 +11,7 @@ type MergeStyle string const ( // MergeStyleMerge create merge commit MergeStyleMerge MergeStyle = "merge" - // MergeStyleRebase rebase before merging + // MergeStyleRebase rebase before merging, and fast-forward MergeStyleRebase MergeStyle = "rebase" // MergeStyleRebaseMerge rebase before merging with merge commit (--no-ff) MergeStyleRebaseMerge MergeStyle = "rebase-merge" diff --git a/models/repo/repo.go b/models/repo/repo.go index b7c02057c2728..3d1f2dcfa8a67 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -528,6 +528,18 @@ func (repo *Repository) ComposeCompareURL(oldCommitID, newCommitID string) strin return fmt.Sprintf("%s/%s/compare/%s...%s", url.PathEscape(repo.OwnerName), url.PathEscape(repo.Name), util.PathEscapeSegments(oldCommitID), util.PathEscapeSegments(newCommitID)) } +func (repo *Repository) ComposeBranchCompareURL(baseRepo *Repository, branchName string) string { + if baseRepo == nil { + baseRepo = repo + } + var cmpBranchEscaped string + if repo.ID != baseRepo.ID { + cmpBranchEscaped = fmt.Sprintf("%s/%s:", url.PathEscape(repo.OwnerName), url.PathEscape(repo.Name)) + } + cmpBranchEscaped = fmt.Sprintf("%s%s", cmpBranchEscaped, util.PathEscapeSegments(branchName)) + return fmt.Sprintf("%s/compare/%s...%s", baseRepo.Link(), util.PathEscapeSegments(baseRepo.DefaultBranch), cmpBranchEscaped) +} + // IsOwnedBy returns true when user owns this repository func (repo *Repository) IsOwnedBy(userID int64) bool { return repo.OwnerID == userID diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index 7ba82004dfa4e..2c7cec5591de3 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -23,8 +23,6 @@ import ( type DetectedWorkflow struct { EntryName string TriggerEvent string - Commit *git.Commit - Ref string Content []byte } @@ -120,7 +118,6 @@ func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventTy dwf := &DetectedWorkflow{ EntryName: entry.Name(), TriggerEvent: evt.Name, - Commit: commit, Content: content, } workflows = append(workflows, dwf) @@ -335,44 +332,47 @@ func matchIssuesEvent(commit *git.Commit, issuePayload *api.IssuePayload, evt *j } func matchPullRequestEvent(commit *git.Commit, prPayload *api.PullRequestPayload, evt *jobparser.Event) bool { - // with no special filter parameters - if len(evt.Acts()) == 0 { + acts := evt.Acts() + activityTypeMatched := false + matchTimes := 0 + + if vals, ok := acts["types"]; !ok { // defaultly, only pull request `opened`, `reopened` and `synchronized` will trigger workflow // See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request - return prPayload.Action == api.HookIssueSynchronized || prPayload.Action == api.HookIssueOpened || prPayload.Action == api.HookIssueReOpened + activityTypeMatched = prPayload.Action == api.HookIssueSynchronized || prPayload.Action == api.HookIssueOpened || prPayload.Action == api.HookIssueReOpened + } else { + // See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request + // Actions with the same name: + // opened, edited, closed, reopened, assigned, unassigned + // Actions need to be converted: + // synchronized -> synchronize + // label_updated -> labeled + // label_cleared -> unlabeled + // Unsupported activity types: + // converted_to_draft, ready_for_review, locked, unlocked, review_requested, review_request_removed, auto_merge_enabled, auto_merge_disabled + + action := prPayload.Action + switch action { + case api.HookIssueSynchronized: + action = "synchronize" + case api.HookIssueLabelUpdated: + action = "labeled" + case api.HookIssueLabelCleared: + action = "unlabeled" + } + log.Trace("matching pull_request %s with %v", action, vals) + for _, val := range vals { + if glob.MustCompile(val, '/').Match(string(action)) { + activityTypeMatched = true + matchTimes++ + break + } + } } - matchTimes := 0 // all acts conditions should be satisfied - for cond, vals := range evt.Acts() { + for cond, vals := range acts { switch cond { - case "types": - // See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request - // Actions with the same name: - // opened, edited, closed, reopened, assigned, unassigned - // Actions need to be converted: - // synchronized -> synchronize - // label_updated -> labeled - // label_cleared -> unlabeled - // Unsupported activity types: - // converted_to_draft, ready_for_review, locked, unlocked, review_requested, review_request_removed, auto_merge_enabled, auto_merge_disabled - - action := prPayload.Action - switch action { - case api.HookIssueSynchronized: - action = "synchronize" - case api.HookIssueLabelUpdated: - action = "labeled" - case api.HookIssueLabelCleared: - action = "unlabeled" - } - log.Trace("matching pull_request %s with %v", action, vals) - for _, val := range vals { - if glob.MustCompile(val, '/').Match(string(action)) { - matchTimes++ - break - } - } case "branches": refName := git.RefName(prPayload.PullRequest.Base.Ref) patterns, err := workflowpattern.CompilePatterns(vals...) @@ -421,7 +421,7 @@ func matchPullRequestEvent(commit *git.Commit, prPayload *api.PullRequestPayload log.Warn("pull request event unsupported condition %q", cond) } } - return matchTimes == len(evt.Acts()) + return activityTypeMatched && matchTimes == len(evt.Acts()) } func matchIssueCommentEvent(commit *git.Commit, issueCommentPayload *api.IssueCommentPayload, evt *jobparser.Event) bool { diff --git a/modules/actions/workflows_test.go b/modules/actions/workflows_test.go index 2c374d2c0d0fc..ef553c4a57267 100644 --- a/modules/actions/workflows_test.go +++ b/modules/actions/workflows_test.go @@ -57,6 +57,25 @@ func TestDetectMatched(t *testing.T) { yamlOn: "on: pull_request", expected: false, }, + { + desc: "HookEventPullRequest(pull_request) `closed` action doesn't match GithubEventPullRequest(pull_request) with no activity type", + triggedEvent: webhook_module.HookEventPullRequest, + payload: &api.PullRequestPayload{Action: api.HookIssueClosed}, + yamlOn: "on: pull_request", + expected: false, + }, + { + desc: "HookEventPullRequest(pull_request) `closed` action doesn't match GithubEventPullRequest(pull_request) with branches", + triggedEvent: webhook_module.HookEventPullRequest, + payload: &api.PullRequestPayload{ + Action: api.HookIssueClosed, + PullRequest: &api.PullRequest{ + Base: &api.PRBranchInfo{}, + }, + }, + yamlOn: "on:\n pull_request:\n branches: [main]", + expected: false, + }, { desc: "HookEventPullRequest(pull_request) `label_updated` action matches GithubEventPullRequest(pull_request) with `label` activity type", triggedEvent: webhook_module.HookEventPullRequest, diff --git a/modules/activitypub/client.go b/modules/activitypub/client.go index ed5c9990d65ed..fa1b57638f3c4 100644 --- a/modules/activitypub/client.go +++ b/modules/activitypub/client.go @@ -63,19 +63,19 @@ type Client struct { // NewClient function func NewClient(user *user_model.User, pubID string) (c *Client, err error) { if err = containsRequiredHTTPHeaders(http.MethodGet, setting.Federation.GetHeaders); err != nil { - return + return nil, err } else if err = containsRequiredHTTPHeaders(http.MethodPost, setting.Federation.PostHeaders); err != nil { - return + return nil, err } priv, err := GetPrivateKey(user) if err != nil { - return + return nil, err } privPem, _ := pem.Decode([]byte(priv)) privParsed, err := x509.ParsePKCS1PrivateKey(privPem.Bytes) if err != nil { - return + return nil, err } c = &Client{ @@ -99,14 +99,14 @@ func (c *Client) NewRequest(b []byte, to string) (req *http.Request, err error) buf := bytes.NewBuffer(b) req, err = http.NewRequest(http.MethodPost, to, buf) if err != nil { - return + return nil, err } req.Header.Add("Content-Type", ActivityStreamsContentType) req.Header.Add("Date", CurrentTime()) req.Header.Add("User-Agent", "Gitea/"+setting.AppVer) signer, _, err := httpsig.NewSigner(c.algs, c.digestAlg, c.postHeaders, httpsig.Signature, httpsigExpirationTime) if err != nil { - return + return nil, err } err = signer.SignRequest(c.priv, c.pubID, req, b) return req, err @@ -116,7 +116,7 @@ func (c *Client) NewRequest(b []byte, to string) (req *http.Request, err error) func (c *Client) Post(b []byte, to string) (resp *http.Response, err error) { var req *http.Request if req, err = c.NewRequest(b, to); err != nil { - return + return nil, err } resp, err = c.client.Do(req) return resp, err diff --git a/modules/activitypub/user_settings.go b/modules/activitypub/user_settings.go index 2d156c17e65ad..20b3d759c2f99 100644 --- a/modules/activitypub/user_settings.go +++ b/modules/activitypub/user_settings.go @@ -15,22 +15,22 @@ func GetKeyPair(user *user_model.User) (pub, priv string, err error) { var settings map[string]*user_model.Setting settings, err = user_model.GetSettings(user.ID, []string{user_model.UserActivityPubPrivPem, user_model.UserActivityPubPubPem}) if err != nil { - return + return pub, priv, err } else if len(settings) == 0 { if priv, pub, err = util.GenerateKeyPair(rsaBits); err != nil { - return + return pub, priv, err } if err = user_model.SetUserSetting(user.ID, user_model.UserActivityPubPrivPem, priv); err != nil { - return + return pub, priv, err } if err = user_model.SetUserSetting(user.ID, user_model.UserActivityPubPubPem, pub); err != nil { - return + return pub, priv, err } - return + return pub, priv, err } else { priv = settings[user_model.UserActivityPubPrivPem].SettingValue pub = settings[user_model.UserActivityPubPubPem].SettingValue - return + return pub, priv, err } } diff --git a/modules/assetfs/layered.go b/modules/assetfs/layered.go index d032160a6feca..e18a13e4aafe4 100644 --- a/modules/assetfs/layered.go +++ b/modules/assetfs/layered.go @@ -215,6 +215,7 @@ func (l *LayeredFS) WatchLocalChanges(ctx context.Context, callback func()) { log.Error("Unable to list directories for asset local file-system %q: %v", layer.localPath, err) continue } + layerDirs = append(layerDirs, ".") for _, dir := range layerDirs { if err = watcher.Add(util.FilePathJoinAbs(layer.localPath, dir)); err != nil { log.Error("Unable to watch directory %s: %v", dir, err) diff --git a/modules/context/api.go b/modules/context/api.go index 93a587d436933..a367597e8a44e 100644 --- a/modules/context/api.go +++ b/modules/context/api.go @@ -294,7 +294,7 @@ func ReferencesGitRepo(allowEmpty ...bool) func(ctx *APIContext) (cancel context return func(ctx *APIContext) (cancel context.CancelFunc) { // Empty repository does not have reference information. if ctx.Repo.Repository.IsEmpty && !(len(allowEmpty) != 0 && allowEmpty[0]) { - return + return nil } // For API calls. @@ -303,7 +303,7 @@ func ReferencesGitRepo(allowEmpty ...bool) func(ctx *APIContext) (cancel context gitRepo, err := git.OpenRepository(ctx, repoPath) if err != nil { ctx.Error(http.StatusInternalServerError, "RepoRef Invalid repo "+repoPath, err) - return + return cancel } ctx.Repo.GitRepo = gitRepo // We opened it, we should close it diff --git a/modules/context/package.go b/modules/context/package.go index 8e80fa66ec43d..be50e0a991ee2 100644 --- a/modules/context/package.go +++ b/modules/context/package.go @@ -108,18 +108,28 @@ func determineAccessMode(ctx *Base, pkg *Package, doer *user_model.User) (perm.A if doer != nil && !doer.IsGhost() { // 1. If user is logged in, check all team packages permissions - teams, err := organization.GetUserOrgTeams(ctx, org.ID, doer.ID) + var err error + accessMode, err = org.GetOrgUserMaxAuthorizeLevel(doer.ID) if err != nil { return accessMode, err } - for _, t := range teams { - perm := t.UnitAccessMode(ctx, unit.TypePackages) - if accessMode < perm { - accessMode = perm + // If access mode is less than write check every team for more permissions + // The minimum possible access mode is read for org members + if accessMode < perm.AccessModeWrite { + teams, err := organization.GetUserOrgTeams(ctx, org.ID, doer.ID) + if err != nil { + return accessMode, err + } + for _, t := range teams { + perm := t.UnitAccessMode(ctx, unit.TypePackages) + if accessMode < perm { + accessMode = perm + } } } - } else if organization.HasOrgOrUserVisible(ctx, pkg.Owner, doer) { - // 2. If user is non-login, check if org is visible to non-login user + } + if accessMode == perm.AccessModeNone && organization.HasOrgOrUserVisible(ctx, pkg.Owner, doer) { + // 2. If user is unauthorized or no org member, check if org is visible accessMode = perm.AccessModeRead } } else { diff --git a/modules/context/repo.go b/modules/context/repo.go index e99908525128f..eae71cfb7be67 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -422,10 +422,10 @@ func RepoIDAssignment() func(ctx *Context) { } // RepoAssignment returns a middleware to handle repository assignment -func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { +func RepoAssignment(ctx *Context) context.CancelFunc { if _, repoAssignmentOnce := ctx.Data["repoAssignmentExecuted"]; repoAssignmentOnce { log.Trace("RepoAssignment was exec already, skipping second call ...") - return + return nil } ctx.Data["repoAssignmentExecuted"] = true @@ -453,7 +453,7 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { // https://github.com/golang/go/issues/19760 if ctx.FormString("go-get") == "1" { EarlyResponseForGoGetMeta(ctx) - return + return nil } if redirectUserID, err := user_model.LookupUserRedirect(userName); err == nil { @@ -466,7 +466,7 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { } else { ctx.ServerError("GetUserByName", err) } - return + return nil } } ctx.Repo.Owner = owner @@ -490,7 +490,7 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { redirectPath += "?" + ctx.Req.URL.RawQuery } ctx.Redirect(path.Join(setting.AppSubURL, redirectPath)) - return + return nil } // Get repository. @@ -503,7 +503,7 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { } else if repo_model.IsErrRedirectNotExist(err) { if ctx.FormString("go-get") == "1" { EarlyResponseForGoGetMeta(ctx) - return + return nil } ctx.NotFound("GetRepositoryByName", nil) } else { @@ -512,13 +512,13 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { } else { ctx.ServerError("GetRepositoryByName", err) } - return + return nil } repo.Owner = owner repoAssignment(ctx, repo) if ctx.Written() { - return + return nil } ctx.Repo.RepoLink = repo.Link() @@ -542,12 +542,12 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { }) if err != nil { ctx.ServerError("GetReleaseCountByRepoID", err) - return + return nil } ctx.Data["NumReleases"], err = repo_model.GetReleaseCountByRepoID(ctx, ctx.Repo.Repository.ID, repo_model.FindReleasesOptions{}) if err != nil { ctx.ServerError("GetReleaseCountByRepoID", err) - return + return nil } ctx.Data["Title"] = owner.Name + "/" + repo.Name @@ -563,14 +563,14 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { canSignedUserFork, err := repo_module.CanUserForkRepo(ctx.Doer, ctx.Repo.Repository) if err != nil { ctx.ServerError("CanUserForkRepo", err) - return + return nil } ctx.Data["CanSignedUserFork"] = canSignedUserFork userAndOrgForks, err := repo_model.GetForksByUserAndOrgs(ctx, ctx.Doer, ctx.Repo.Repository) if err != nil { ctx.ServerError("GetForksByUserAndOrgs", err) - return + return nil } ctx.Data["UserAndOrgForks"] = userAndOrgForks @@ -604,14 +604,14 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { if repo.IsFork { RetrieveBaseRepo(ctx, repo) if ctx.Written() { - return + return nil } } if repo.IsGenerated() { RetrieveTemplateRepo(ctx, repo) if ctx.Written() { - return + return nil } } @@ -623,7 +623,7 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { if !isHomeOrSettings { ctx.Redirect(ctx.Repo.RepoLink) } - return + return nil } gitRepo, err := git.OpenRepository(ctx, repo_model.RepoPath(userName, repoName)) @@ -636,10 +636,10 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { if !isHomeOrSettings { ctx.Redirect(ctx.Repo.RepoLink) } - return + return nil } ctx.ServerError("RepoAssignment Invalid repo "+repo_model.RepoPath(userName, repoName), err) - return + return nil } if ctx.Repo.GitRepo != nil { ctx.Repo.GitRepo.Close() @@ -647,7 +647,7 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { ctx.Repo.GitRepo = gitRepo // We opened it, we should close it - cancel = func() { + cancel := func() { // If it's been set to nil then assume someone else has closed it. if ctx.Repo.GitRepo != nil { ctx.Repo.GitRepo.Close() @@ -657,13 +657,13 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { // Stop at this point when the repo is empty. if ctx.Repo.Repository.IsEmpty { ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch - return + return cancel } tags, err := repo_model.GetTagNamesByRepoID(ctx, ctx.Repo.Repository.ID) if err != nil { ctx.ServerError("GetTagNamesByRepoID", err) - return + return cancel } ctx.Data["Tags"] = tags @@ -677,7 +677,7 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { branchesTotal, err := git_model.CountBranches(ctx, branchOpts) if err != nil { ctx.ServerError("CountBranches", err) - return + return cancel } // non empty repo should have at least 1 branch, so this repository's branches haven't been synced yet @@ -685,7 +685,7 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { branchesTotal, err = repo_module.SyncRepoBranches(ctx, ctx.Repo.Repository.ID, 0) if err != nil { ctx.ServerError("SyncRepoBranches", err) - return + return cancel } } @@ -694,7 +694,7 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { brs, err := git_model.FindBranchNames(ctx, branchOpts) if err != nil { ctx.ServerError("GetBranches", err) - return + return cancel } // always put default branch on the top ctx.Data["Branches"] = append(branchOpts.ExcludeBranchNames, brs...) @@ -741,12 +741,12 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { repoTransfer, err := models.GetPendingRepositoryTransfer(ctx, ctx.Repo.Repository) if err != nil { ctx.ServerError("GetPendingRepositoryTransfer", err) - return + return cancel } if err := repoTransfer.LoadAttributes(ctx); err != nil { ctx.ServerError("LoadRecipient", err) - return + return cancel } ctx.Data["RepoTransfer"] = repoTransfer @@ -894,7 +894,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context ctx.Repo.IsViewBranch = true ctx.Repo.BranchName = ctx.Repo.Repository.DefaultBranch ctx.Data["TreePath"] = "" - return + return nil } var ( @@ -907,7 +907,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context ctx.Repo.GitRepo, err = git.OpenRepository(ctx, repoPath) if err != nil { ctx.ServerError("RepoRef Invalid repo "+repoPath, err) - return + return nil } // We opened it, we should close it cancel = func() { @@ -944,7 +944,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context ctx.Repo.Repository.MarkAsBrokenEmpty() } else { ctx.ServerError("GetBranchCommit", err) - return + return cancel } ctx.Repo.IsViewBranch = true } else { @@ -956,7 +956,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context ctx.Flash.Info(ctx.Tr("repo.branch.renamed", refName, renamedBranchName)) link := setting.AppSubURL + strings.Replace(ctx.Req.URL.EscapedPath(), util.PathEscapeSegments(refName), util.PathEscapeSegments(renamedBranchName), 1) ctx.Redirect(link) - return + return cancel } if refType.RefTypeIncludesBranches() && ctx.Repo.GitRepo.IsBranchExist(refName) { @@ -966,7 +966,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName) if err != nil { ctx.ServerError("GetBranchCommit", err) - return + return cancel } ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() @@ -978,10 +978,10 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context if err != nil { if git.IsErrNotExist(err) { ctx.NotFound("GetTagCommit", err) - return + return cancel } ctx.ServerError("GetTagCommit", err) - return + return cancel } ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() } else if len(refName) >= 7 && len(refName) <= git.SHAFullLength { @@ -991,7 +991,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommit(refName) if err != nil { ctx.NotFound("GetCommit", err) - return + return cancel } // If short commit ID add canonical link header if len(refName) < git.SHAFullLength { @@ -1000,10 +1000,10 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context } } else { if len(ignoreNotExistErr) > 0 && ignoreNotExistErr[0] { - return + return cancel } ctx.NotFound("RepoRef invalid repo", fmt.Errorf("branch or tag not exist: %s", refName)) - return + return cancel } if refType == RepoRefLegacy { @@ -1015,7 +1015,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context util.PathEscapeSegments(prefix), ctx.Repo.BranchNameSubURL(), util.PathEscapeSegments(ctx.Repo.TreePath))) - return + return cancel } } @@ -1033,7 +1033,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context ctx.Repo.CommitsCount, err = ctx.Repo.GetCommitsCount() if err != nil { ctx.ServerError("GetCommitsCount", err) - return + return cancel } ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount ctx.Repo.GitRepo.LastCommitCache = git.NewLastCommitCache(ctx.Repo.CommitsCount, ctx.Repo.Repository.FullName(), ctx.Repo.GitRepo, cache.GetCache()) diff --git a/modules/doctor/fix16961.go b/modules/doctor/fix16961.go index ea14a9b2c4164..562c78dd76597 100644 --- a/modules/doctor/fix16961.go +++ b/modules/doctor/fix16961.go @@ -6,6 +6,7 @@ package doctor import ( "bytes" "context" + "errors" "fmt" "code.gitea.io/gitea/models/db" @@ -40,12 +41,12 @@ func parseBool16961(bs []byte) (bool, error) { func fixUnitConfig16961(bs []byte, cfg *repo_model.UnitConfig) (fixed bool, err error) { err = json.UnmarshalHandleDoubleEncode(bs, &cfg) if err == nil { - return + return false, nil } // Handle #16961 if string(bs) != "&{}" && len(bs) != 0 { - return + return false, err } return true, nil @@ -54,14 +55,14 @@ func fixUnitConfig16961(bs []byte, cfg *repo_model.UnitConfig) (fixed bool, err func fixExternalWikiConfig16961(bs []byte, cfg *repo_model.ExternalWikiConfig) (fixed bool, err error) { err = json.UnmarshalHandleDoubleEncode(bs, &cfg) if err == nil { - return + return false, nil } if len(bs) < 3 { - return + return false, err } if bs[0] != '&' || bs[1] != '{' || bs[len(bs)-1] != '}' { - return + return false, err } cfg.ExternalWikiURL = string(bs[2 : len(bs)-1]) return true, nil @@ -70,20 +71,20 @@ func fixExternalWikiConfig16961(bs []byte, cfg *repo_model.ExternalWikiConfig) ( func fixExternalTrackerConfig16961(bs []byte, cfg *repo_model.ExternalTrackerConfig) (fixed bool, err error) { err = json.UnmarshalHandleDoubleEncode(bs, &cfg) if err == nil { - return + return false, nil } // Handle #16961 if len(bs) < 3 { - return + return false, err } if bs[0] != '&' || bs[1] != '{' || bs[len(bs)-1] != '}' { - return + return false, err } parts := bytes.Split(bs[2:len(bs)-1], []byte{' '}) if len(parts) != 3 { - return + return false, err } cfg.ExternalTrackerURL = string(bytes.Join(parts[:len(parts)-2], []byte{' '})) @@ -95,16 +96,16 @@ func fixExternalTrackerConfig16961(bs []byte, cfg *repo_model.ExternalTrackerCon func fixPullRequestsConfig16961(bs []byte, cfg *repo_model.PullRequestsConfig) (fixed bool, err error) { err = json.UnmarshalHandleDoubleEncode(bs, &cfg) if err == nil { - return + return false, nil } // Handle #16961 if len(bs) < 3 { - return + return false, err } if bs[0] != '&' || bs[1] != '{' || bs[len(bs)-1] != '}' { - return + return false, err } // PullRequestsConfig was the following in 1.14 @@ -123,37 +124,37 @@ func fixPullRequestsConfig16961(bs []byte, cfg *repo_model.PullRequestsConfig) ( // DefaultMergeStyle MergeStyle parts := bytes.Split(bs[2:len(bs)-1], []byte{' '}) if len(parts) < 7 { - return + return false, err } var parseErr error cfg.IgnoreWhitespaceConflicts, parseErr = parseBool16961(parts[0]) if parseErr != nil { - return + return false, errors.Join(err, parseErr) } cfg.AllowMerge, parseErr = parseBool16961(parts[1]) if parseErr != nil { - return + return false, errors.Join(err, parseErr) } cfg.AllowRebase, parseErr = parseBool16961(parts[2]) if parseErr != nil { - return + return false, errors.Join(err, parseErr) } cfg.AllowRebaseMerge, parseErr = parseBool16961(parts[3]) if parseErr != nil { - return + return false, errors.Join(err, parseErr) } cfg.AllowSquash, parseErr = parseBool16961(parts[4]) if parseErr != nil { - return + return false, errors.Join(err, parseErr) } cfg.AllowManualMerge, parseErr = parseBool16961(parts[5]) if parseErr != nil { - return + return false, errors.Join(err, parseErr) } cfg.AutodetectManualMerge, parseErr = parseBool16961(parts[6]) if parseErr != nil { - return + return false, errors.Join(err, parseErr) } // 1.14 unit @@ -162,12 +163,12 @@ func fixPullRequestsConfig16961(bs []byte, cfg *repo_model.PullRequestsConfig) ( } if len(parts) < 9 { - return + return false, err } cfg.DefaultDeleteBranchAfterMerge, parseErr = parseBool16961(parts[7]) if parseErr != nil { - return + return false, errors.Join(err, parseErr) } cfg.DefaultMergeStyle = repo_model.MergeStyle(string(bytes.Join(parts[8:], []byte{' '}))) @@ -177,34 +178,34 @@ func fixPullRequestsConfig16961(bs []byte, cfg *repo_model.PullRequestsConfig) ( func fixIssuesConfig16961(bs []byte, cfg *repo_model.IssuesConfig) (fixed bool, err error) { err = json.UnmarshalHandleDoubleEncode(bs, &cfg) if err == nil { - return + return false, nil } // Handle #16961 if len(bs) < 3 { - return + return false, err } if bs[0] != '&' || bs[1] != '{' || bs[len(bs)-1] != '}' { - return + return false, err } parts := bytes.Split(bs[2:len(bs)-1], []byte{' '}) if len(parts) != 3 { - return + return false, err } var parseErr error cfg.EnableTimetracker, parseErr = parseBool16961(parts[0]) if parseErr != nil { - return + return false, errors.Join(err, parseErr) } cfg.AllowOnlyContributorsToTrackTime, parseErr = parseBool16961(parts[1]) if parseErr != nil { - return + return false, errors.Join(err, parseErr) } cfg.EnableDependencies, parseErr = parseBool16961(parts[2]) if parseErr != nil { - return + return false, errors.Join(err, parseErr) } return true, nil } diff --git a/modules/eventsource/event.go b/modules/eventsource/event.go index 811f97ff56263..ebcca5090344c 100644 --- a/modules/eventsource/event.go +++ b/modules/eventsource/event.go @@ -15,7 +15,7 @@ import ( func wrapNewlines(w io.Writer, prefix, value []byte) (sum int64, err error) { if len(value) == 0 { - return + return 0, nil } var n int last := 0 @@ -23,24 +23,24 @@ func wrapNewlines(w io.Writer, prefix, value []byte) (sum int64, err error) { n, err = w.Write(prefix) sum += int64(n) if err != nil { - return + return sum, err } n, err = w.Write(value[last : last+j+1]) sum += int64(n) if err != nil { - return + return sum, err } last += j + 1 } n, err = w.Write(prefix) sum += int64(n) if err != nil { - return + return sum, err } n, err = w.Write(value[last:]) sum += int64(n) if err != nil { - return + return sum, err } n, err = w.Write([]byte("\n")) sum += int64(n) diff --git a/modules/git/batch_reader.go b/modules/git/batch_reader.go index 75539c0d0a935..891e8a2384c11 100644 --- a/modules/git/batch_reader.go +++ b/modules/git/batch_reader.go @@ -148,27 +148,25 @@ func CatFileBatch(ctx context.Context, repoPath string) (WriteCloserError, *bufi func ReadBatchLine(rd *bufio.Reader) (sha []byte, typ string, size int64, err error) { typ, err = rd.ReadString('\n') if err != nil { - return + return sha, typ, size, err } if len(typ) == 1 { typ, err = rd.ReadString('\n') if err != nil { - return + return sha, typ, size, err } } idx := strings.IndexByte(typ, ' ') if idx < 0 { log.Debug("missing space typ: %s", typ) - err = ErrNotExist{ID: string(sha)} - return + return sha, typ, size, ErrNotExist{ID: string(sha)} } sha = []byte(typ[:idx]) typ = typ[idx+1:] idx = strings.IndexByte(typ, ' ') if idx < 0 { - err = ErrNotExist{ID: string(sha)} - return + return sha, typ, size, ErrNotExist{ID: string(sha)} } sizeStr := typ[idx+1 : len(typ)-1] @@ -285,14 +283,12 @@ func ParseTreeLine(rd *bufio.Reader, modeBuf, fnameBuf, shaBuf []byte) (mode, fn // Read the Mode & fname readBytes, err = rd.ReadSlice('\x00') if err != nil { - return + return mode, fname, sha, n, err } idx := bytes.IndexByte(readBytes, ' ') if idx < 0 { log.Debug("missing space in readBytes ParseTreeLine: %s", readBytes) - - err = &ErrNotExist{} - return + return mode, fname, sha, n, &ErrNotExist{} } n += idx + 1 @@ -319,7 +315,7 @@ func ParseTreeLine(rd *bufio.Reader, modeBuf, fnameBuf, shaBuf []byte) (mode, fn } n += len(fnameBuf) if err != nil { - return + return mode, fname, sha, n, err } fnameBuf = fnameBuf[:len(fnameBuf)-1] fname = fnameBuf @@ -331,7 +327,7 @@ func ParseTreeLine(rd *bufio.Reader, modeBuf, fnameBuf, shaBuf []byte) (mode, fn read, err = rd.Read(shaBuf[idx:20]) n += read if err != nil { - return + return mode, fname, sha, n, err } idx += read } diff --git a/modules/git/commit.go b/modules/git/commit.go index ff654f394d221..729e3b4672a7c 100644 --- a/modules/git/commit.go +++ b/modules/git/commit.go @@ -435,7 +435,7 @@ func (c *Commit) GetBranchName() (string, error) { // LoadBranchName load branch name for commit func (c *Commit) LoadBranchName() (err error) { if len(c.Branch) != 0 { - return + return nil } c.Branch, err = c.GetBranchName() diff --git a/modules/git/git.go b/modules/git/git.go index c9d174e118113..12d2f94e514cc 100644 --- a/modules/git/git.go +++ b/modules/git/git.go @@ -171,7 +171,7 @@ func InitFull(ctx context.Context) (err error) { } if err = InitSimple(ctx); err != nil { - return + return err } // when git works with gnupg (commit signing), there should be a stable home for gnupg commands diff --git a/modules/git/repo_base_nogogit.go b/modules/git/repo_base_nogogit.go index e0f2d563b3e00..414e4eb1a83de 100644 --- a/modules/git/repo_base_nogogit.go +++ b/modules/git/repo_base_nogogit.go @@ -87,7 +87,7 @@ func (repo *Repository) CatFileBatchCheck(ctx context.Context) (WriteCloserError // Close this repository, in particular close the underlying gogitStorage if this is not nil func (repo *Repository) Close() (err error) { if repo == nil { - return + return nil } if repo.batchCancel != nil { repo.batchCancel() diff --git a/modules/git/repo_index.go b/modules/git/repo_index.go index 5ff2a2e4fc9d2..34dd1e0129158 100644 --- a/modules/git/repo_index.go +++ b/modules/git/repo_index.go @@ -48,7 +48,7 @@ func (repo *Repository) readTreeToIndex(id SHA1, indexFilename ...string) error func (repo *Repository) ReadTreeToTemporaryIndex(treeish string) (filename, tmpDir string, cancel context.CancelFunc, err error) { tmpDir, err = os.MkdirTemp("", "index") if err != nil { - return + return filename, tmpDir, cancel, err } filename = filepath.Join(tmpDir, ".tmp-index") diff --git a/modules/git/signature_nogogit.go b/modules/git/signature_nogogit.go index a203d5ce6d3dc..25277f99d52e6 100644 --- a/modules/git/signature_nogogit.go +++ b/modules/git/signature_nogogit.go @@ -43,12 +43,13 @@ func (s *Signature) Decode(b []byte) { // // but without the "author " at the beginning (this method should) // be used for author and committer. +// FIXME: there are a lot of "return sig, err" (but the err is also nil), that's the old behavior, to avoid breaking func newSignatureFromCommitline(line []byte) (sig *Signature, err error) { sig = new(Signature) emailStart := bytes.LastIndexByte(line, '<') emailEnd := bytes.LastIndexByte(line, '>') if emailStart == -1 || emailEnd == -1 || emailEnd < emailStart { - return + return sig, err } if emailStart > 0 { // Empty name has already occurred, even if it shouldn't @@ -58,7 +59,7 @@ func newSignatureFromCommitline(line []byte) (sig *Signature, err error) { hasTime := emailEnd+2 < len(line) if !hasTime { - return + return sig, err } // Check date format. @@ -66,7 +67,7 @@ func newSignatureFromCommitline(line []byte) (sig *Signature, err error) { if firstChar >= 48 && firstChar <= 57 { idx := bytes.IndexByte(line[emailEnd+2:], ' ') if idx < 0 { - return + return sig, err } timestring := string(line[emailEnd+2 : emailEnd+2+idx]) @@ -75,14 +76,14 @@ func newSignatureFromCommitline(line []byte) (sig *Signature, err error) { idx += emailEnd + 3 if idx >= len(line) || idx+5 > len(line) { - return + return sig, err } timezone := string(line[idx : idx+5]) tzhours, err1 := strconv.ParseInt(timezone[0:3], 10, 64) tzmins, err2 := strconv.ParseInt(timezone[3:], 10, 64) if err1 != nil || err2 != nil { - return + return sig, err } if tzhours < 0 { tzmins *= -1 @@ -92,7 +93,7 @@ func newSignatureFromCommitline(line []byte) (sig *Signature, err error) { } else { sig.When, err = time.Parse(GitTimeLayout, string(line[emailEnd+2:])) if err != nil { - return + return sig, err } } return sig, err diff --git a/modules/httpcache/httpcache.go b/modules/httpcache/httpcache.go index 001ac06415375..b57b3218322c7 100644 --- a/modules/httpcache/httpcache.go +++ b/modules/httpcache/httpcache.go @@ -70,11 +70,11 @@ func checkIfNoneMatchIsValid(req *http.Request, etag string) bool { // HandleGenericETagTimeCache handles ETag-based caching with Last-Modified caching for a HTTP request. // It returns true if the request was handled. -func HandleGenericETagTimeCache(req *http.Request, w http.ResponseWriter, etag string, lastModified time.Time) (handled bool) { +func HandleGenericETagTimeCache(req *http.Request, w http.ResponseWriter, etag string, lastModified *time.Time) (handled bool) { if len(etag) > 0 { w.Header().Set("Etag", etag) } - if !lastModified.IsZero() { + if lastModified != nil && !lastModified.IsZero() { w.Header().Set("Last-Modified", lastModified.Format(http.TimeFormat)) } @@ -84,7 +84,7 @@ func HandleGenericETagTimeCache(req *http.Request, w http.ResponseWriter, etag s return true } } - if !lastModified.IsZero() { + if lastModified != nil && !lastModified.IsZero() { ifModifiedSince := req.Header.Get("If-Modified-Since") if ifModifiedSince != "" { t, err := time.Parse(http.TimeFormat, ifModifiedSince) diff --git a/modules/httplib/serve.go b/modules/httplib/serve.go index 12d68c2d656eb..a193ed901cf99 100644 --- a/modules/httplib/serve.go +++ b/modules/httplib/serve.go @@ -206,7 +206,7 @@ func ServeContentByReader(r *http.Request, w http.ResponseWriter, filePath strin _, _ = io.CopyN(w, reader, partialLength) // just like http.ServeContent, not necessary to handle the error } -func ServeContentByReadSeeker(r *http.Request, w http.ResponseWriter, filePath string, modTime time.Time, reader io.ReadSeeker) { +func ServeContentByReadSeeker(r *http.Request, w http.ResponseWriter, filePath string, modTime *time.Time, reader io.ReadSeeker) { buf := make([]byte, mimeDetectionBufferLen) n, err := util.ReadAtMost(reader, buf) if err != nil { @@ -221,5 +221,8 @@ func ServeContentByReadSeeker(r *http.Request, w http.ResponseWriter, filePath s buf = buf[:n] } setServeHeadersByFile(r, w, filePath, buf) - http.ServeContent(w, r, path.Base(filePath), modTime, reader) + if modTime == nil { + modTime = &time.Time{} + } + http.ServeContent(w, r, path.Base(filePath), *modTime, reader) } diff --git a/modules/httplib/serve_test.go b/modules/httplib/serve_test.go index fed4611d21795..c2229dffe96e8 100644 --- a/modules/httplib/serve_test.go +++ b/modules/httplib/serve_test.go @@ -11,7 +11,6 @@ import ( "os" "strings" "testing" - "time" "github.com/stretchr/testify/assert" ) @@ -78,7 +77,7 @@ func TestServeContentByReadSeeker(t *testing.T) { defer seekReader.Close() w := httptest.NewRecorder() - ServeContentByReadSeeker(r, w, "test", time.Time{}, seekReader) + ServeContentByReadSeeker(r, w, "test", nil, seekReader) assert.Equal(t, expectedStatusCode, w.Code) if expectedStatusCode == http.StatusPartialContent || expectedStatusCode == http.StatusOK { assert.Equal(t, fmt.Sprint(len(expectedContent)), w.Header().Get("Content-Length")) diff --git a/modules/indexer/issues/bleve/bleve.go b/modules/indexer/issues/bleve/bleve.go index 4cc58acac7846..c368a67ab5863 100644 --- a/modules/indexer/issues/bleve/bleve.go +++ b/modules/indexer/issues/bleve/bleve.go @@ -138,7 +138,7 @@ func (b *Indexer) Delete(_ context.Context, ids ...int64) error { // Search searches for issues by given conditions. // Returns the matching issue IDs -func (b *Indexer) Search(ctx context.Context, keyword string, repoIDs []int64, limit, start int) (*internal.SearchResult, error) { +func (b *Indexer) Search(ctx context.Context, keyword string, repoIDs []int64, limit, start int, state string) (*internal.SearchResult, error) { var repoQueriesP []*query.NumericRangeQuery for _, repoID := range repoIDs { repoQueriesP = append(repoQueriesP, numericEqualityQuery(repoID, "repo_id")) diff --git a/modules/indexer/issues/bleve/bleve_test.go b/modules/indexer/issues/bleve/bleve_test.go index f890f8eb488fe..0eb136d22b276 100644 --- a/modules/indexer/issues/bleve/bleve_test.go +++ b/modules/indexer/issues/bleve/bleve_test.go @@ -77,7 +77,7 @@ func TestBleveIndexAndSearch(t *testing.T) { } for _, kw := range keywords { - res, err := indexer.Search(context.TODO(), kw.Keyword, []int64{2}, 10, 0) + res, err := indexer.Search(context.TODO(), kw.Keyword, []int64{2}, 10, 0, "") assert.NoError(t, err) ids := make([]int64, 0, len(res.Hits)) diff --git a/modules/indexer/issues/db/db.go b/modules/indexer/issues/db/db.go index 17ed426b384ba..b054b9d800edb 100644 --- a/modules/indexer/issues/db/db.go +++ b/modules/indexer/issues/db/db.go @@ -36,7 +36,7 @@ func (i *Indexer) Delete(_ context.Context, _ ...int64) error { } // Search searches for issues -func (i *Indexer) Search(ctx context.Context, kw string, repoIDs []int64, limit, start int) (*internal.SearchResult, error) { +func (i *Indexer) Search(ctx context.Context, kw string, repoIDs []int64, limit, start int, state string) (*internal.SearchResult, error) { total, ids, err := issues_model.SearchIssueIDsByKeyword(ctx, kw, repoIDs, limit, start) if err != nil { return nil, err diff --git a/modules/indexer/issues/elasticsearch/elasticsearch.go b/modules/indexer/issues/elasticsearch/elasticsearch.go index 62889ea578f67..cfd3628c18507 100644 --- a/modules/indexer/issues/elasticsearch/elasticsearch.go +++ b/modules/indexer/issues/elasticsearch/elasticsearch.go @@ -140,7 +140,7 @@ func (b *Indexer) Delete(ctx context.Context, ids ...int64) error { // Search searches for issues by given conditions. // Returns the matching issue IDs -func (b *Indexer) Search(ctx context.Context, keyword string, repoIDs []int64, limit, start int) (*internal.SearchResult, error) { +func (b *Indexer) Search(ctx context.Context, keyword string, repoIDs []int64, limit, start int, state string) (*internal.SearchResult, error) { kwQuery := elastic.NewMultiMatchQuery(keyword, "title", "content", "comments") query := elastic.NewBoolQuery() query = query.Must(kwQuery) diff --git a/modules/indexer/issues/indexer.go b/modules/indexer/issues/indexer.go index 9e2f13371e4a3..fe5c5d8f26d30 100644 --- a/modules/indexer/issues/indexer.go +++ b/modules/indexer/issues/indexer.go @@ -242,12 +242,18 @@ func UpdateIssueIndexer(issue *issues_model.Issue) { comments = append(comments, comment.Content) } } + issueType := "issue" + if issue.IsPull { + issueType = "pull" + } indexerData := &internal.IndexerData{ - ID: issue.ID, - RepoID: issue.RepoID, - Title: issue.Title, - Content: issue.Content, - Comments: comments, + ID: issue.ID, + RepoID: issue.RepoID, + State: string(issue.State()), + IssueType: issueType, + Title: issue.Title, + Content: issue.Content, + Comments: comments, } log.Debug("Adding to channel: %v", indexerData) if err := issueIndexerQueue.Push(indexerData); err != nil { @@ -278,10 +284,10 @@ func DeleteRepoIssueIndexer(ctx context.Context, repo *repo_model.Repository) { // SearchIssuesByKeyword search issue ids by keywords and repo id // WARNNING: You have to ensure user have permission to visit repoIDs' issues -func SearchIssuesByKeyword(ctx context.Context, repoIDs []int64, keyword string) ([]int64, error) { +func SearchIssuesByKeyword(ctx context.Context, repoIDs []int64, keyword, state string) ([]int64, error) { var issueIDs []int64 indexer := *globalIndexer.Load() - res, err := indexer.Search(ctx, keyword, repoIDs, 50, 0) + res, err := indexer.Search(ctx, keyword, repoIDs, 50, 0, state) if err != nil { return nil, err } diff --git a/modules/indexer/issues/indexer_test.go b/modules/indexer/issues/indexer_test.go index 5962a4ee9cb76..757eb2f3d9338 100644 --- a/modules/indexer/issues/indexer_test.go +++ b/modules/indexer/issues/indexer_test.go @@ -50,19 +50,19 @@ func TestBleveSearchIssues(t *testing.T) { time.Sleep(5 * time.Second) - ids, err := SearchIssuesByKeyword(context.TODO(), []int64{1}, "issue2") + ids, err := SearchIssuesByKeyword(context.TODO(), []int64{1}, "issue2", "") assert.NoError(t, err) assert.EqualValues(t, []int64{2}, ids) - ids, err = SearchIssuesByKeyword(context.TODO(), []int64{1}, "first") + ids, err = SearchIssuesByKeyword(context.TODO(), []int64{1}, "first", "") assert.NoError(t, err) assert.EqualValues(t, []int64{1}, ids) - ids, err = SearchIssuesByKeyword(context.TODO(), []int64{1}, "for") + ids, err = SearchIssuesByKeyword(context.TODO(), []int64{1}, "for", "") assert.NoError(t, err) assert.ElementsMatch(t, []int64{1, 2, 3, 5, 11}, ids) - ids, err = SearchIssuesByKeyword(context.TODO(), []int64{1}, "good") + ids, err = SearchIssuesByKeyword(context.TODO(), []int64{1}, "good", "") assert.NoError(t, err) assert.EqualValues(t, []int64{1}, ids) } @@ -73,19 +73,19 @@ func TestDBSearchIssues(t *testing.T) { setting.Indexer.IssueType = "db" InitIssueIndexer(true) - ids, err := SearchIssuesByKeyword(context.TODO(), []int64{1}, "issue2") + ids, err := SearchIssuesByKeyword(context.TODO(), []int64{1}, "issue2", "") assert.NoError(t, err) assert.EqualValues(t, []int64{2}, ids) - ids, err = SearchIssuesByKeyword(context.TODO(), []int64{1}, "first") + ids, err = SearchIssuesByKeyword(context.TODO(), []int64{1}, "first", "") assert.NoError(t, err) assert.EqualValues(t, []int64{1}, ids) - ids, err = SearchIssuesByKeyword(context.TODO(), []int64{1}, "for") + ids, err = SearchIssuesByKeyword(context.TODO(), []int64{1}, "for", "") assert.NoError(t, err) assert.ElementsMatch(t, []int64{1, 2, 3, 5, 11}, ids) - ids, err = SearchIssuesByKeyword(context.TODO(), []int64{1}, "good") + ids, err = SearchIssuesByKeyword(context.TODO(), []int64{1}, "good", "") assert.NoError(t, err) assert.EqualValues(t, []int64{1}, ids) } diff --git a/modules/indexer/issues/internal/indexer.go b/modules/indexer/issues/internal/indexer.go index 553c8a573cdcb..b96517bb80db9 100644 --- a/modules/indexer/issues/internal/indexer.go +++ b/modules/indexer/issues/internal/indexer.go @@ -15,7 +15,7 @@ type Indexer interface { internal.Indexer Index(ctx context.Context, issue []*IndexerData) error Delete(ctx context.Context, ids ...int64) error - Search(ctx context.Context, kw string, repoIDs []int64, limit, start int) (*SearchResult, error) + Search(ctx context.Context, kw string, repoIDs []int64, limit, start int, state string) (*SearchResult, error) } // NewDummyIndexer returns a dummy indexer @@ -37,6 +37,6 @@ func (d *dummyIndexer) Delete(ctx context.Context, ids ...int64) error { return fmt.Errorf("indexer is not ready") } -func (d *dummyIndexer) Search(ctx context.Context, kw string, repoIDs []int64, limit, start int) (*SearchResult, error) { +func (d *dummyIndexer) Search(ctx context.Context, kw string, repoIDs []int64, limit, start int, state string) (*SearchResult, error) { return nil, fmt.Errorf("indexer is not ready") } diff --git a/modules/indexer/issues/internal/model.go b/modules/indexer/issues/internal/model.go index 8c206fc1cfcdc..2b52d32302a06 100644 --- a/modules/indexer/issues/internal/model.go +++ b/modules/indexer/issues/internal/model.go @@ -5,13 +5,15 @@ package internal // IndexerData data stored in the issue indexer type IndexerData struct { - ID int64 `json:"id"` - RepoID int64 `json:"repo_id"` - Title string `json:"title"` - Content string `json:"content"` - Comments []string `json:"comments"` - IsDelete bool `json:"is_delete"` - IDs []int64 `json:"ids"` + ID int64 `json:"id"` + RepoID int64 `json:"repo_id"` + State string `json:"state"` // open, closed, all + IssueType string `json:"type"` // issue or pull + Title string `json:"title"` + Content string `json:"content"` + Comments []string `json:"comments"` + IsDelete bool `json:"is_delete"` + IDs []int64 `json:"ids"` } // Match represents on search result diff --git a/modules/indexer/issues/meilisearch/meilisearch.go b/modules/indexer/issues/meilisearch/meilisearch.go index 2a46b1ab15cfd..2ea06b576c0b8 100644 --- a/modules/indexer/issues/meilisearch/meilisearch.go +++ b/modules/indexer/issues/meilisearch/meilisearch.go @@ -16,7 +16,7 @@ import ( ) const ( - issueIndexerLatestVersion = 0 + issueIndexerLatestVersion = 1 ) var _ internal.Indexer = &Indexer{} @@ -70,12 +70,19 @@ func (b *Indexer) Delete(_ context.Context, ids ...int64) error { // Search searches for issues by given conditions. // Returns the matching issue IDs -func (b *Indexer) Search(ctx context.Context, keyword string, repoIDs []int64, limit, start int) (*internal.SearchResult, error) { +func (b *Indexer) Search(ctx context.Context, keyword string, repoIDs []int64, limit, start int, state string) (*internal.SearchResult, error) { repoFilters := make([]string, 0, len(repoIDs)) for _, repoID := range repoIDs { repoFilters = append(repoFilters, "repo_id = "+strconv.FormatInt(repoID, 10)) } filter := strings.Join(repoFilters, " OR ") + if state == "open" || state == "closed" { + if filter != "" { + filter = "(" + filter + ") AND state = " + state + } else { + filter = "state = " + state + } + } searchRes, err := b.inner.Client.Index(b.inner.VersionedIndexName()).Search(keyword, &meilisearch.SearchRequest{ Filter: filter, Limit: int64(limit), diff --git a/modules/nosql/manager.go b/modules/nosql/manager.go index 31e43297dcd12..375c2b5d003ce 100644 --- a/modules/nosql/manager.go +++ b/modules/nosql/manager.go @@ -71,7 +71,7 @@ func valToTimeDuration(vs []string) (result time.Duration) { result = time.Duration(val) } if err == nil { - return + return result } } return result diff --git a/modules/process/manager.go b/modules/process/manager.go index 56908c0408668..9c21f6215210f 100644 --- a/modules/process/manager.go +++ b/modules/process/manager.go @@ -211,7 +211,7 @@ func (pm *Manager) nextPID() (start time.Time, pid IDType) { pid = IDType(strconv.FormatInt(start.Unix(), 16)) if pm.next == 1 { - return + return start, pid } pid = IDType(string(pid) + "-" + strconv.FormatInt(pm.next, 10)) return start, pid diff --git a/modules/queue/workerqueue.go b/modules/queue/workerqueue.go index e0d5183bd9b82..b28fd880270ab 100644 --- a/modules/queue/workerqueue.go +++ b/modules/queue/workerqueue.go @@ -93,7 +93,7 @@ func (q *WorkerPoolQueue[T]) GetQueueItemNumber() int { func (q *WorkerPoolQueue[T]) FlushWithContext(ctx context.Context, timeout time.Duration) (err error) { if q.isBaseQueueDummy() { - return + return nil } log.Debug("Try to flush queue %q with timeout %v", q.GetName(), timeout) diff --git a/modules/setting/config_env.go b/modules/setting/config_env.go index 63488037059ab..e23b64557f8fe 100644 --- a/modules/setting/config_env.go +++ b/modules/setting/config_env.go @@ -12,10 +12,31 @@ import ( "code.gitea.io/gitea/modules/log" ) +const ( + EnvConfigKeyPrefixGitea = "GITEA__" + EnvConfigKeySuffixFile = "__FILE" +) + const escapeRegexpString = "_0[xX](([0-9a-fA-F][0-9a-fA-F])+)_" var escapeRegex = regexp.MustCompile(escapeRegexpString) +func CollectEnvConfigKeys() (keys []string) { + for _, env := range os.Environ() { + if strings.HasPrefix(env, EnvConfigKeyPrefixGitea) { + k, _, _ := strings.Cut(env, "=") + keys = append(keys, k) + } + } + return keys +} + +func ClearEnvConfigKeys() { + for _, k := range CollectEnvConfigKeys() { + _ = os.Unsetenv(k) + } +} + // decodeEnvSectionKey will decode a portable string encoded Section__Key pair // Portable strings are considered to be of the form [A-Z0-9_]* // We will encode a disallowed value as the UTF8 byte string preceded by _0X and @@ -87,7 +108,7 @@ func decodeEnvironmentKey(prefixGitea, suffixFile, envKey string) (ok bool, sect return ok, section, key, useFileValue } -func EnvironmentToConfig(cfg ConfigProvider, prefixGitea, suffixFile string, envs []string) (changed bool) { +func EnvironmentToConfig(cfg ConfigProvider, envs []string) (changed bool) { for _, kv := range envs { idx := strings.IndexByte(kv, '=') if idx < 0 { @@ -97,7 +118,7 @@ func EnvironmentToConfig(cfg ConfigProvider, prefixGitea, suffixFile string, env // parse the environment variable to config section name and key name envKey := kv[:idx] envValue := kv[idx+1:] - ok, sectionName, keyName, useFileValue := decodeEnvironmentKey(prefixGitea, suffixFile, envKey) + ok, sectionName, keyName, useFileValue := decodeEnvironmentKey(EnvConfigKeyPrefixGitea, EnvConfigKeySuffixFile, envKey) if !ok { continue } diff --git a/modules/setting/config_env_test.go b/modules/setting/config_env_test.go index d574554bcc049..2c1dd2f5c71f7 100644 --- a/modules/setting/config_env_test.go +++ b/modules/setting/config_env_test.go @@ -72,7 +72,7 @@ func TestDecodeEnvironmentKey(t *testing.T) { func TestEnvironmentToConfig(t *testing.T) { cfg, _ := NewConfigProviderFromData("") - changed := EnvironmentToConfig(cfg, "GITEA__", "__FILE", nil) + changed := EnvironmentToConfig(cfg, nil) assert.False(t, changed) cfg, err := NewConfigProviderFromData(` @@ -81,16 +81,16 @@ key = old `) assert.NoError(t, err) - changed = EnvironmentToConfig(cfg, "GITEA__", "__FILE", []string{"GITEA__sec__key=new"}) + changed = EnvironmentToConfig(cfg, []string{"GITEA__sec__key=new"}) assert.True(t, changed) assert.Equal(t, "new", cfg.Section("sec").Key("key").String()) - changed = EnvironmentToConfig(cfg, "GITEA__", "__FILE", []string{"GITEA__sec__key=new"}) + changed = EnvironmentToConfig(cfg, []string{"GITEA__sec__key=new"}) assert.False(t, changed) tmpFile := t.TempDir() + "/the-file" _ = os.WriteFile(tmpFile, []byte("value-from-file"), 0o644) - changed = EnvironmentToConfig(cfg, "GITEA__", "__FILE", []string{"GITEA__sec__key__FILE=" + tmpFile}) + changed = EnvironmentToConfig(cfg, []string{"GITEA__sec__key__FILE=" + tmpFile}) assert.True(t, changed) assert.Equal(t, "value-from-file", cfg.Section("sec").Key("key").String()) } diff --git a/modules/setting/path.go b/modules/setting/path.go index 163f1d159067f..32ed8d81fa3e9 100644 --- a/modules/setting/path.go +++ b/modules/setting/path.go @@ -171,6 +171,9 @@ func InitWorkPathAndCfgProvider(getEnvFn func(name string) string, args ArgWorkP // only read the config but do not load/init anything more, because the AppWorkPath and CustomPath are not ready InitCfgProvider(tmpCustomConf.Value) + if HasInstallLock(CfgProvider) { + ClearEnvConfigKeys() // if the instance has been installed, do not pass the environment variables to sub-processes + } configWorkPath := ConfigSectionKeyString(CfgProvider.Section(""), "WORK_PATH") if configWorkPath != "" { if !filepath.IsAbs(configWorkPath) { diff --git a/modules/setting/security.go b/modules/setting/security.go index 5f1f9f4ade894..7064d7a008f40 100644 --- a/modules/setting/security.go +++ b/modules/setting/security.go @@ -102,7 +102,7 @@ func generateSaveInternalToken(rootCfg ConfigProvider) { func loadSecurityFrom(rootCfg ConfigProvider) { sec := rootCfg.Section("security") - InstallLock = sec.Key("INSTALL_LOCK").MustBool(false) + InstallLock = HasInstallLock(rootCfg) LogInRememberDays = sec.Key("LOGIN_REMEMBER_DAYS").MustInt(7) CookieUserName = sec.Key("COOKIE_USERNAME").MustString("gitea_awesome") SecretKey = loadSecret(sec, "SECRET_KEY_URI", "SECRET_KEY") diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 0d69847dbeab2..d444d9a0175c6 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -183,10 +183,14 @@ func loadRunModeFrom(rootCfg ConfigProvider) { } } +// HasInstallLock checks the install-lock in ConfigProvider directly, because sometimes the config file is not loaded into setting variables yet. +func HasInstallLock(rootCfg ConfigProvider) bool { + return rootCfg.Section("security").Key("INSTALL_LOCK").MustBool(false) +} + func mustCurrentRunUserMatch(rootCfg ConfigProvider) { // Does not check run user when the "InstallLock" is off. - installLock := rootCfg.Section("security").Key("INSTALL_LOCK").MustBool(false) - if installLock { + if HasInstallLock(rootCfg) { currentUser, match := IsRunUserMatchCurrentUser(RunUser) if !match { log.Fatal("Expect user '%s' but current user is: %s", RunUser, currentUser) diff --git a/modules/util/util.go b/modules/util/util.go index 3051449544d00..9d5e6c1e89303 100644 --- a/modules/util/util.go +++ b/modules/util/util.go @@ -256,3 +256,8 @@ func ToFloat64(number any) (float64, error) { } return value, nil } + +// ToPointer returns the pointer of a copy of any given value +func ToPointer[T any](val T) *T { + return &val +} diff --git a/modules/util/util_test.go b/modules/util/util_test.go index 8cceafa2f66d7..c5830ce01cb22 100644 --- a/modules/util/util_test.go +++ b/modules/util/util_test.go @@ -224,3 +224,12 @@ func TestToTitleCase(t *testing.T) { assert.Equal(t, ToTitleCase(`foo bar baz`), `Foo Bar Baz`) assert.Equal(t, ToTitleCase(`FOO BAR BAZ`), `Foo Bar Baz`) } + +func TestToPointer(t *testing.T) { + assert.Equal(t, "abc", *ToPointer("abc")) + assert.Equal(t, 123, *ToPointer(123)) + abc := "abc" + assert.False(t, &abc == ToPointer(abc)) + val123 := 123 + assert.False(t, &val123 == ToPointer(val123)) +} diff --git a/modules/web/route.go b/modules/web/route.go index 8685062a8e5f9..dc87e112ec60c 100644 --- a/modules/web/route.go +++ b/modules/web/route.go @@ -50,7 +50,9 @@ func NewRoute() *Route { // Use supports two middlewares func (r *Route) Use(middlewares ...any) { for _, m := range middlewares { - r.R.Use(toHandlerProvider(m)) + if m != nil { + r.R.Use(toHandlerProvider(m)) + } } } @@ -79,15 +81,23 @@ func (r *Route) getPattern(pattern string) string { } func (r *Route) wrapMiddlewareAndHandler(h []any) ([]func(http.Handler) http.Handler, http.HandlerFunc) { - handlerProviders := make([]func(http.Handler) http.Handler, 0, len(r.curMiddlewares)+len(h)) + handlerProviders := make([]func(http.Handler) http.Handler, 0, len(r.curMiddlewares)+len(h)+1) for _, m := range r.curMiddlewares { - handlerProviders = append(handlerProviders, toHandlerProvider(m)) + if m != nil { + handlerProviders = append(handlerProviders, toHandlerProvider(m)) + } } for _, m := range h { - handlerProviders = append(handlerProviders, toHandlerProvider(m)) + if h != nil { + handlerProviders = append(handlerProviders, toHandlerProvider(m)) + } } middlewares := handlerProviders[:len(handlerProviders)-1] handlerFunc := handlerProviders[len(handlerProviders)-1](nil).ServeHTTP + mockPoint := RouteMockPoint(MockAfterMiddlewares) + if mockPoint != nil { + middlewares = append(middlewares, mockPoint) + } return middlewares, handlerFunc } diff --git a/modules/web/routemock.go b/modules/web/routemock.go new file mode 100644 index 0000000000000..cb41f63b91ab8 --- /dev/null +++ b/modules/web/routemock.go @@ -0,0 +1,61 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package web + +import ( + "net/http" + + "code.gitea.io/gitea/modules/setting" +) + +// MockAfterMiddlewares is a general mock point, it's between middlewares and the handler +const MockAfterMiddlewares = "MockAfterMiddlewares" + +var routeMockPoints = map[string]func(next http.Handler) http.Handler{} + +// RouteMockPoint registers a mock point as a middleware for testing, example: +// +// r.Use(web.RouteMockPoint("my-mock-point-1")) +// r.Get("/foo", middleware2, web.RouteMockPoint("my-mock-point-2"), middleware2, handler) +// +// Then use web.RouteMock to mock the route execution. +// It only takes effect in testing mode (setting.IsInTesting == true). +func RouteMockPoint(pointName string) func(next http.Handler) http.Handler { + if !setting.IsInTesting { + return nil + } + routeMockPoints[pointName] = nil + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if h := routeMockPoints[pointName]; h != nil { + h(next).ServeHTTP(w, r) + } else { + next.ServeHTTP(w, r) + } + }) + } +} + +// RouteMock uses the registered mock point to mock the route execution, example: +// +// defer web.RouteMockReset() +// web.RouteMock(web.MockAfterMiddlewares, func(ctx *context.Context) { +// ctx.WriteResponse(...) +// } +// +// Then the mock function will be executed as a middleware at the mock point. +// It only takes effect in testing mode (setting.IsInTesting == true). +func RouteMock(pointName string, h any) { + if _, ok := routeMockPoints[pointName]; !ok { + panic("route mock point not found: " + pointName) + } + routeMockPoints[pointName] = toHandlerProvider(h) +} + +// RouteMockReset resets all mock points (no mock anymore) +func RouteMockReset() { + for k := range routeMockPoints { + routeMockPoints[k] = nil // keep the keys because RouteMock will check the keys to make sure no misspelling + } +} diff --git a/modules/web/routemock_test.go b/modules/web/routemock_test.go new file mode 100644 index 0000000000000..04c6d1d82e576 --- /dev/null +++ b/modules/web/routemock_test.go @@ -0,0 +1,70 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package web + +import ( + "net/http" + "net/http/httptest" + "testing" + + "code.gitea.io/gitea/modules/setting" + + "github.com/stretchr/testify/assert" +) + +func TestRouteMock(t *testing.T) { + setting.IsInTesting = true + + r := NewRoute() + middleware1 := func(resp http.ResponseWriter, req *http.Request) { + resp.Header().Set("X-Test-Middleware1", "m1") + } + middleware2 := func(resp http.ResponseWriter, req *http.Request) { + resp.Header().Set("X-Test-Middleware2", "m2") + } + handler := func(resp http.ResponseWriter, req *http.Request) { + resp.Header().Set("X-Test-Handler", "h") + } + r.Get("/foo", middleware1, RouteMockPoint("mock-point"), middleware2, handler) + + // normal request + recorder := httptest.NewRecorder() + req, err := http.NewRequest("GET", "http://localhost:8000/foo", nil) + assert.NoError(t, err) + r.ServeHTTP(recorder, req) + assert.Len(t, recorder.Header(), 3) + assert.EqualValues(t, "m1", recorder.Header().Get("X-Test-Middleware1")) + assert.EqualValues(t, "m2", recorder.Header().Get("X-Test-Middleware2")) + assert.EqualValues(t, "h", recorder.Header().Get("X-Test-Handler")) + RouteMockReset() + + // mock at "mock-point" + RouteMock("mock-point", func(resp http.ResponseWriter, req *http.Request) { + resp.Header().Set("X-Test-MockPoint", "a") + resp.WriteHeader(http.StatusOK) + }) + recorder = httptest.NewRecorder() + req, err = http.NewRequest("GET", "http://localhost:8000/foo", nil) + assert.NoError(t, err) + r.ServeHTTP(recorder, req) + assert.Len(t, recorder.Header(), 2) + assert.EqualValues(t, "m1", recorder.Header().Get("X-Test-Middleware1")) + assert.EqualValues(t, "a", recorder.Header().Get("X-Test-MockPoint")) + RouteMockReset() + + // mock at MockAfterMiddlewares + RouteMock(MockAfterMiddlewares, func(resp http.ResponseWriter, req *http.Request) { + resp.Header().Set("X-Test-MockPoint", "b") + resp.WriteHeader(http.StatusOK) + }) + recorder = httptest.NewRecorder() + req, err = http.NewRequest("GET", "http://localhost:8000/foo", nil) + assert.NoError(t, err) + r.ServeHTTP(recorder, req) + assert.Len(t, recorder.Header(), 3) + assert.EqualValues(t, "m1", recorder.Header().Get("X-Test-Middleware1")) + assert.EqualValues(t, "m2", recorder.Header().Get("X-Test-Middleware2")) + assert.EqualValues(t, "b", recorder.Header().Get("X-Test-MockPoint")) + RouteMockReset() +} diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index ee55e946ab33f..c4c9d32e1d4ac 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -296,6 +296,8 @@ invalid_password_algorithm = Invalid password hash algorithm password_algorithm_helper = Set the password hashing algorithm. Algorithms have differing requirements and strength. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems. enable_update_checker = Enable Update Checker enable_update_checker_helper = Checks for new version releases periodically by connecting to gitea.io. +env_config_keys = Environment Configuration +env_config_keys_prompt = The following environment variables will also be applied to your configuration file: [home] uname_holder = Username or Email Address @@ -1767,6 +1769,8 @@ pulls.auto_merge_canceled_schedule_comment = `canceled auto merging this pull re pulls.delete.title = Delete this pull request? pulls.delete.text = Do you really want to delete this pull request? (This will permanently remove all content. Consider closing it instead, if you intend to keep it archived) +pulls.recently_pushed_new_branches = You pushed on branch %[1]s %[2]s + milestones.new = New Milestone milestones.closed = Closed %s milestones.update_ago = Updated %s @@ -3232,6 +3236,7 @@ desc = Manage repository packages. empty = There are no packages yet. empty.documentation = For more information on the package registry, see the documentation. empty.repo = Did you upload a package, but it's not shown here? Go to package settings and link it to this repo. +registry.documentation = For more information on the %s registry, see the documentation. filter.type = Type filter.type.all = All filter.no_result = Your filter produced no results. @@ -3259,38 +3264,31 @@ alpine.registry = Setup this registry by adding the url in your /etc/apk/r alpine.registry.key = Download the registry public RSA key into the /etc/apk/keys/ folder to verify the index signature: alpine.registry.info = Choose $branch and $repository from the list below. alpine.install = To install the package, run the following command: -alpine.documentation = For more information on the Alpine registry, see the documentation. alpine.repository = Repository Info alpine.repository.branches = Branches alpine.repository.repositories = Repositories alpine.repository.architectures = Architectures cargo.registry = Setup this registry in the Cargo configuration file (for example ~/.cargo/config.toml): cargo.install = To install the package using Cargo, run the following command: -cargo.documentation = For more information on the Cargo registry, see the documentation. cargo.details.repository_site = Repository Site cargo.details.documentation_site = Documentation Site chef.registry = Setup this registry in your ~/.chef/config.rb file: chef.install = To install the package, run the following command: -chef.documentation = For more information on the Chef registry, see the documentation. composer.registry = Setup this registry in your ~/.composer/config.json file: composer.install = To install the package using Composer, run the following command: -composer.documentation = For more information on the Composer registry, see the documentation. composer.dependencies = Dependencies composer.dependencies.development = Development Dependencies conan.details.repository = Repository conan.registry = Setup this registry from the command line: conan.install = To install the package using Conan, run the following command: -conan.documentation = For more information on the Conan registry, see the documentation. conda.registry = Setup this registry as a Conda repository in your .condarc file: conda.install = To install the package using Conda, run the following command: -conda.documentation = For more information on the Conda registry, see the documentation. conda.details.repository_site = Repository Site conda.details.documentation_site = Documentation Site container.details.type = Image Type container.details.platform = Platform container.pull = Pull the image from the command line: container.digest = Digest: -container.documentation = For more information on the Container registry, see the documentation. container.multi_arch = OS / Arch container.layers = Image Layers container.labels = Labels @@ -3298,61 +3296,47 @@ container.labels.key = Key container.labels.value = Value cran.registry = Setup this registry in your Rprofile.site file: cran.install = To install the package, run the following command: -cran.documentation = For more information on the CRAN registry, see the documentation. debian.registry = Setup this registry from the command line: debian.registry.info = Choose $distribution and $component from the list below. debian.install = To install the package, run the following command: -debian.documentation = For more information on the Debian registry, see the documentation. debian.repository = Repository Info debian.repository.distributions = Distributions debian.repository.components = Components debian.repository.architectures = Architectures generic.download = Download package from the command line: -generic.documentation = For more information on the generic registry, see the documentation. go.install = Install the package from the command line: -go.documentation = For more information on the Go registry, see the documentation. helm.registry = Setup this registry from the command line: helm.install = To install the package, run the following command: -helm.documentation = For more information on the Helm registry, see the documentation. maven.registry = Setup this registry in your project pom.xml file: maven.install = To use the package include the following in the dependencies block in the pom.xml file: maven.install2 = Run via command line: maven.download = To download the dependency, run via command line: -maven.documentation = For more information on the Maven registry, see the documentation. nuget.registry = Setup this registry from the command line: nuget.install = To install the package using NuGet, run the following command: -nuget.documentation = For more information on the NuGet registry, see the documentation. nuget.dependency.framework = Target Framework npm.registry = Setup this registry in your project .npmrc file: npm.install = To install the package using npm, run the following command: npm.install2 = or add it to the package.json file: -npm.documentation = For more information on the npm registry, see the documentation. npm.dependencies = Dependencies npm.dependencies.development = Development Dependencies npm.dependencies.peer = Peer Dependencies npm.dependencies.optional = Optional Dependencies npm.details.tag = Tag pub.install = To install the package using Dart, run the following command: -pub.documentation = For more information on the Pub registry, see the documentation. pypi.requires = Requires Python pypi.install = To install the package using pip, run the following command: -pypi.documentation = For more information on the PyPI registry, see the documentation. rpm.registry = Setup this registry from the command line: rpm.install = To install the package, run the following command: -rpm.documentation = For more information on the RPM registry, see the documentation. rubygems.install = To install the package using gem, run the following command: rubygems.install2 = or add it to the Gemfile: rubygems.dependencies.runtime = Runtime Dependencies rubygems.dependencies.development = Development Dependencies rubygems.required.ruby = Requires Ruby version rubygems.required.rubygems = Requires RubyGem version -rubygems.documentation = For more information on the RubyGems registry, see the documentation. swift.registry = Setup this registry from the command line: swift.install = Add the package in your Package.swift file: swift.install2 = and run the following command: -swift.documentation = For more information on the Swift registry, see the documentation. vagrant.install = To add a Vagrant box, run the following command: -vagrant.documentation = For more information on the Vagrant registry, see the documentation. settings.link = Link this package to a repository settings.link.description = If you link a package with a repository, the package is listed in the repository's package list. settings.link.select = Select Repository diff --git a/package-lock.json b/package-lock.json index 437534b525f77..a24ece0eb0bd0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,21 +25,23 @@ "easymde": "2.18.0", "esbuild-loader": "3.0.1", "escape-goat": "4.0.0", - "fast-glob": "3.2.12", + "fast-glob": "3.3.0", "jquery": "3.7.0", "jquery.are-you-sure": "1.9.0", "katex": "0.16.8", "license-checker-webpack-plugin": "0.2.1", - "mermaid": "10.2.3", + "lightningcss-loader": "2.1.0", + "mermaid": "10.2.4", "mini-css-extract-plugin": "2.7.6", - "minimatch": "9.0.2", - "monaco-editor": "0.39.0", + "minimatch": "9.0.3", + "monaco-editor": "0.40.0", "monaco-editor-webpack-plugin": "7.0.1", "pdfobject": "2.2.12", "pretty-ms": "8.0.0", "sortablejs": "1.15.0", "swagger-ui-dist": "5.1.0", "throttle-debounce": "5.0.0", + "tinycolor2": "1.6.0", "tippy.js": "6.3.7", "toastify-js": "1.12.0", "tributejs": "5.1.3", @@ -48,17 +50,16 @@ "vue-bar-graph": "2.0.0", "vue-loader": "17.2.2", "vue3-calendar-heatmap": "2.0.5", - "webpack": "5.88.0", + "webpack": "5.88.1", "webpack-cli": "5.1.4", "wrap-ansi": "8.1.0" }, "devDependencies": { "@eslint-community/eslint-plugin-eslint-comments": "3.2.1", "@playwright/test": "1.35.1", - "@rollup/pluginutils": "5.0.2", "@stoplight/spectral-cli": "6.8.0", "@vitejs/plugin-vue": "4.2.3", - "eslint": "8.43.0", + "eslint": "8.44.0", "eslint-plugin-array-func": "3.1.8", "eslint-plugin-custom-elements": "0.0.8", "eslint-plugin-import": "2.27.5", @@ -78,13 +79,23 @@ "stylelint-declaration-strict-value": "1.9.2", "stylelint-stylistic": "0.4.2", "svgo": "3.0.2", - "updates": "14.2.8", - "vitest": "0.32.2" + "updates": "14.3.2", + "vite-string-plugin": "1.1.0", + "vitest": "0.33.0" }, "engines": { "node": ">= 16.0.0" } }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@asyncapi/specs": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@asyncapi/specs/-/specs-4.3.1.tgz", @@ -198,9 +209,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.5.tgz", - "integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==", + "version": "7.22.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz", + "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==", "bin": { "parser": "bin/babel-parser.js" }, @@ -209,9 +220,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", - "integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", + "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", "dependencies": { "regenerator-runtime": "^0.13.11" }, @@ -368,9 +379,9 @@ } }, "node_modules/@csstools/css-parser-algorithms": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.2.0.tgz", - "integrity": "sha512-9BoQ/jSrPq4vv3b9jjLW+PNNv56KlDH5JMx5yASSNrCtvq70FCNZUjXRvbCeR9hYj9ZyhURtqpU/RFIgg6kiOw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.3.0.tgz", + "integrity": "sha512-dTKSIHHWc0zPvcS5cqGP+/TPFUJB0ekJ9dGKvMAFoNuBFhDPBt9OMGNZiIA5vTiNdGHHBeScYPXIGBMnVOahsA==", "dev": true, "funding": [ { @@ -403,9 +414,9 @@ } }, "node_modules/@csstools/media-query-list-parser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.1.tgz", - "integrity": "sha512-pUjtFbaKbiFNjJo8pprrIaXLvQvWIlwPiFnRI4sEnc4F0NIGTOsw8kaJSR3CmZAKEvV8QYckovgAnWQC0bgLLQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.2.tgz", + "integrity": "sha512-M8cFGGwl866o6++vIY7j1AKuq9v57cf+dGepScwCcbut9ypJNr4Cj+LLTWligYUZ0uyhEoJDKt5lvyBfh2L3ZQ==", "dev": true, "funding": [ { @@ -421,7 +432,7 @@ "node": "^14 || ^16 || >=18" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^2.2.0", + "@csstools/css-parser-algorithms": "^2.3.0", "@csstools/css-tokenizer": "^2.1.1" } }, @@ -820,14 +831,14 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", - "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", + "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.2", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -887,9 +898,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz", - "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", + "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1040,6 +1051,18 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/@jest/schemas": { + "version": "29.6.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.0.tgz", + "integrity": "sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", @@ -1070,9 +1093,9 @@ } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", - "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -1264,7 +1287,7 @@ "rollup": "^2.68.0" } }, - "node_modules/@rollup/plugin-commonjs/node_modules/@rollup/pluginutils": { + "node_modules/@rollup/pluginutils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", @@ -1281,40 +1304,18 @@ "rollup": "^1.20.0||^2.0.0" } }, - "node_modules/@rollup/plugin-commonjs/node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", "dev": true }, - "node_modules/@rollup/plugin-commonjs/node_modules/@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "dev": true }, - "node_modules/@rollup/pluginutils": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", - "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, "node_modules/@stoplight/better-ajv-errors": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@stoplight/better-ajv-errors/-/better-ajv-errors-1.0.3.tgz", @@ -1439,10 +1440,38 @@ "node": "^12.20 || >= 14.13" } }, + "node_modules/@stoplight/spectral-cli/node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/@stoplight/spectral-cli/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/@stoplight/spectral-core": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.18.0.tgz", - "integrity": "sha512-0aj+IELHvhjoPWoOFj41EJilPbaexUuWFg7GCsiJ3BXrniRp3GnPl+TIZkC1ZuuAr/oi77RviDhW9Gm7ndKB9Q==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.18.1.tgz", + "integrity": "sha512-tgUoQZ68hdhFG6CJToBZQtY2fCkh66T4BUtBhdzQ0ZqLU6MhgdL4PlE0yT2tObwsSExNuzaRZH6ssjvbjnHtQQ==", "dev": true, "dependencies": { "@stoplight/better-ajv-errors": "1.0.3", @@ -1623,9 +1652,9 @@ } }, "node_modules/@stoplight/spectral-ruleset-migrator": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-migrator/-/spectral-ruleset-migrator-1.9.3.tgz", - "integrity": "sha512-lqdBW7pZT+V1DNbOxG2EkjqMIMC5YjQ4bFkgvziH6HFAnGLlvoa2chJHt+X22+DhuvBF8tzpaYrT51iL/BhxXg==", + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-migrator/-/spectral-ruleset-migrator-1.9.4.tgz", + "integrity": "sha512-bQjmYTf1COdhXdFg4dRzfZ7Ukc9ylr9f9J8c1PO3NGZtryUavw/109BrYfdQGgO0Hfkc/yVsRbkI4mKYNlvnXg==", "dev": true, "dependencies": { "@stoplight/json": "~3.20.1", @@ -1801,9 +1830,9 @@ } }, "node_modules/@types/eslint": { - "version": "8.40.2", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.2.tgz", - "integrity": "sha512-PRVjQ4Eh9z9pmmtaq8nTjZjQwKFk7YIHIud3lRoKRBgUQjgjRmoGxxGEPXQkF+lH7QkHJRNr5F4aBgYCW0lqpQ==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.0.tgz", + "integrity": "sha512-gsF+c/0XOguWgaOgvFs+xnnRqt9GwgTvIks36WpE6ueeI4KCEHHd8K/CKHqhOqrJKsYH8m27kRzQEvWXAwXUTw==", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -1819,9 +1848,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==" + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" }, "node_modules/@types/json-schema": { "version": "7.0.12", @@ -1859,9 +1888,9 @@ "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" }, "node_modules/@types/node": { - "version": "20.3.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.2.tgz", - "integrity": "sha512-vOBLVQeCQfIcF/2Y7eKFTqrMnizK5lRNQ7ykML/5RuwVXVWxYkgwS7xbt4B6fKCUPgbSL5FSsjHQpaGQP/dQmw==" + "version": "20.4.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.1.tgz", + "integrity": "sha512-JIzsAvJeA/5iY6Y/OxZbv1lUcc8dNSE77lb2gnBH+/PJ3lFR1Ccvgwl5JWnHAkNHcRsT0TbpVOsiMKZ1F/yyJg==" }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", @@ -1902,13 +1931,13 @@ } }, "node_modules/@vitest/expect": { - "version": "0.32.2", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.32.2.tgz", - "integrity": "sha512-6q5yzweLnyEv5Zz1fqK5u5E83LU+gOMVBDuxBl2d2Jfx1BAp5M+rZgc5mlyqdnxquyoiOXpXmFNkcGcfFnFH3Q==", + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.33.0.tgz", + "integrity": "sha512-sVNf+Gla3mhTCxNJx+wJLDPp/WcstOe0Ksqz4Vec51MmgMth/ia0MGFEkIZmVGeTL5HtjYR4Wl/ZxBxBXZJTzQ==", "dev": true, "dependencies": { - "@vitest/spy": "0.32.2", - "@vitest/utils": "0.32.2", + "@vitest/spy": "0.33.0", + "@vitest/utils": "0.33.0", "chai": "^4.3.7" }, "funding": { @@ -1916,15 +1945,14 @@ } }, "node_modules/@vitest/runner": { - "version": "0.32.2", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.32.2.tgz", - "integrity": "sha512-06vEL0C1pomOEktGoLjzZw+1Fb+7RBRhmw/06WkDrd1akkT9i12su0ku+R/0QM69dfkIL/rAIDTG+CSuQVDcKw==", + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.33.0.tgz", + "integrity": "sha512-UPfACnmCB6HKRHTlcgCoBh6ppl6fDn+J/xR8dTufWiKt/74Y9bHci5CKB8tESSV82zKYtkBJo9whU3mNvfaisg==", "dev": true, "dependencies": { - "@vitest/utils": "0.32.2", - "concordance": "^5.0.4", + "@vitest/utils": "0.33.0", "p-limit": "^4.0.0", - "pathe": "^1.1.0" + "pathe": "^1.1.1" }, "funding": { "url": "https://opencollective.com/vitest" @@ -1958,52 +1986,58 @@ } }, "node_modules/@vitest/snapshot": { - "version": "0.32.2", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.32.2.tgz", - "integrity": "sha512-JwhpeH/PPc7GJX38vEfCy9LtRzf9F4er7i4OsAJyV7sjPwjj+AIR8cUgpMTWK4S3TiamzopcTyLsZDMuldoi5A==", + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.33.0.tgz", + "integrity": "sha512-tJjrl//qAHbyHajpFvr8Wsk8DIOODEebTu7pgBrP07iOepR5jYkLFiqLq2Ltxv+r0uptUb4izv1J8XBOwKkVYA==", "dev": true, "dependencies": { - "magic-string": "^0.30.0", - "pathe": "^1.1.0", - "pretty-format": "^27.5.1" + "magic-string": "^0.30.1", + "pathe": "^1.1.1", + "pretty-format": "^29.5.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, + "node_modules/@vitest/snapshot/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, "node_modules/@vitest/snapshot/node_modules/magic-string": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz", - "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==", + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz", + "integrity": "sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==", "dev": true, "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" + "@jridgewell/sourcemap-codec": "^1.4.15" }, "engines": { "node": ">=12" } }, "node_modules/@vitest/spy": { - "version": "0.32.2", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.32.2.tgz", - "integrity": "sha512-Q/ZNILJ4ca/VzQbRM8ur3Si5Sardsh1HofatG9wsJY1RfEaw0XKP8IVax2lI1qnrk9YPuG9LA2LkZ0EI/3d4ug==", + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.33.0.tgz", + "integrity": "sha512-Kv+yZ4hnH1WdiAkPUQTpRxW8kGtH8VRTnus7ZTGovFYM1ZezJpvGtb9nPIjPnptHbsyIAxYZsEpVPYgtpjGnrg==", "dev": true, "dependencies": { - "tinyspy": "^2.1.0" + "tinyspy": "^2.1.1" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/utils": { - "version": "0.32.2", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.32.2.tgz", - "integrity": "sha512-lnJ0T5i03j0IJaeW73hxe2AuVnZ/y1BhhCOuIcl9LIzXnbpXJT9Lrt6brwKHXLOiA7MZ6N5hSJjt0xE1dGNCzQ==", + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.33.0.tgz", + "integrity": "sha512-pF1w22ic965sv+EN6uoePkAOTkAPWM03Ri/jXNyMIKBb/XHLDPfhLvf/Fa9g0YECevAIz56oVYXhodLvLQ/awA==", "dev": true, "dependencies": { "diff-sequences": "^29.4.3", "loupe": "^2.3.6", - "pretty-format": "^27.5.1" + "pretty-format": "^29.5.0" }, "funding": { "url": "https://opencollective.com/vitest" @@ -2046,12 +2080,17 @@ "source-map-js": "^1.0.2" } }, + "node_modules/@vue/compiler-sfc/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, "node_modules/@vue/compiler-sfc/node_modules/magic-string": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz", - "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==", + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz", + "integrity": "sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" + "@jridgewell/sourcemap-codec": "^1.4.15" }, "engines": { "node": ">=12" @@ -2086,12 +2125,17 @@ "magic-string": "^0.30.0" } }, + "node_modules/@vue/reactivity-transform/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, "node_modules/@vue/reactivity-transform/node_modules/magic-string": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz", - "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==", + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz", + "integrity": "sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" + "@jridgewell/sourcemap-codec": "^1.4.15" }, "engines": { "node": ">=12" @@ -2339,9 +2383,9 @@ } }, "node_modules/acorn": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", - "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "bin": { "acorn": "bin/acorn" }, @@ -2702,12 +2746,6 @@ "node": "*" } }, - "node_modules/blueimp-md5": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz", - "integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==", - "dev": true - }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -2877,9 +2915,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001508", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001508.tgz", - "integrity": "sha512-sdQZOJdmt3GJs1UMNpCCCyeuS2IEGLXnHyAo9yIO5JJDjbjoVRij4M1qep6P6gFpptD1PqIYgzM+gwJbOi92mw==", + "version": "1.0.30001513", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001513.tgz", + "integrity": "sha512-pnjGJo7SOOjAGytZZ203Em95MRM8Cr6jhCXNF/FAXTpCTRTECnqQWLpiTRqrFtdYcth8hf4WECUpkezuYsMVww==", "funding": [ { "type": "opencollective", @@ -3123,25 +3161,6 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, - "node_modules/concordance": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/concordance/-/concordance-5.0.4.tgz", - "integrity": "sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==", - "dev": true, - "dependencies": { - "date-time": "^3.1.0", - "esutils": "^2.0.3", - "fast-diff": "^1.2.0", - "js-string-escape": "^1.0.1", - "lodash": "^4.17.15", - "md5-hex": "^3.0.1", - "semver": "^7.3.2", - "well-known-symbols": "^2.0.0" - }, - "engines": { - "node": ">=10.18.0 <11 || >=12.14.0 <13 || >=14" - } - }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -3812,22 +3831,10 @@ "node": ">=14" } }, - "node_modules/date-time": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz", - "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==", - "dev": true, - "dependencies": { - "time-zone": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/dayjs": { - "version": "1.11.8", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.8.tgz", - "integrity": "sha512-LcgxzFoWMEPO7ggRv1Y2N31hUf2R0Vj7fuy/m+Bg1K8rr+KAs1AEy4y9jd5DXe8pbHgX+srkHNS7TH6Q6ZhYeQ==" + "version": "1.11.9", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.9.tgz", + "integrity": "sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==" }, "node_modules/debug": { "version": "4.3.4", @@ -4010,6 +4017,17 @@ "node": ">=6" } }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/diff": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", @@ -4162,9 +4180,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.441", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.441.tgz", - "integrity": "sha512-LlCgQ8zgYZPymf5H4aE9itwiIWH4YlCiv1HFLmmcBeFYi5E+3eaIFnjHzYtcFQbaKfAW+CqZ9pgxo33DZuoqPg==" + "version": "1.4.454", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.454.tgz", + "integrity": "sha512-pmf1rbAStw8UEQ0sr2cdJtWl48ZMuPD9Sto8HVQOq9vx9j2WgDEN6lYoaqFvqEHYOmGA9oRGn7LqWI9ta0YugQ==" }, "node_modules/elkjs": { "version": "0.8.2", @@ -4515,15 +4533,15 @@ } }, "node_modules/eslint": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz", - "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz", + "integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.43.0", + "@eslint/eslintrc": "^2.1.0", + "@eslint/js": "8.44.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -4535,7 +4553,7 @@ "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.0", "eslint-visitor-keys": "^3.4.1", - "espree": "^9.5.2", + "espree": "^9.6.0", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -4555,7 +4573,7 @@ "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" @@ -4937,12 +4955,12 @@ } }, "node_modules/espree": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", - "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz", + "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==", "dev": true, "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" }, @@ -5033,16 +5051,10 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true - }, "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz", + "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -5599,9 +5611,9 @@ "dev": true }, "node_modules/gsap": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.12.1.tgz", - "integrity": "sha512-FXtb2YbBE9l8I9Pl5DFLpCMedaiMPztRlr0Ln0CMSnJn+pbTaeKlzgth8cLNPc7PzNwIZe+SEQiBBAWaBKJdVA==" + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.12.2.tgz", + "integrity": "sha512-EkYnpG8qHgYBFAwsgsGEqvT1WUidX0tt/ijepx7z8EUJHElykg91RvW1XbkT59T0gZzzszOpjQv7SE41XuIXyQ==" }, "node_modules/hard-rejection": { "version": "2.1.0", @@ -6413,15 +6425,6 @@ "integrity": "sha512-fzreKVq1eD7eGcQr7MtRpQH94f8gIfhdrc7yeih38xh684TNMK9v5aAu2wxfIRMk/GpAJRrzcirMAPIaSDaByQ==", "dev": true }, - "node_modules/js-string-escape": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", - "integrity": "sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/js-tokens": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.1.tgz", @@ -6717,6 +6720,204 @@ "node": ">=8" } }, + "node_modules/lightningcss": { + "version": "1.21.5", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.21.5.tgz", + "integrity": "sha512-/pEUPeih2EwIx9n4T82aOG6CInN83tl/mWlw6B5gWLf36UplQi1L+5p3FUHsdt4fXVfOkkh9KIaM3owoq7ss8A==", + "dependencies": { + "detect-libc": "^1.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.21.5", + "lightningcss-darwin-x64": "1.21.5", + "lightningcss-linux-arm-gnueabihf": "1.21.5", + "lightningcss-linux-arm64-gnu": "1.21.5", + "lightningcss-linux-arm64-musl": "1.21.5", + "lightningcss-linux-x64-gnu": "1.21.5", + "lightningcss-linux-x64-musl": "1.21.5", + "lightningcss-win32-x64-msvc": "1.21.5" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.21.5", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.21.5.tgz", + "integrity": "sha512-z05hyLX85WY0UfhkFUOrWEFqD69lpVAmgl3aDzMKlIZJGygbhbegqb4PV8qfUrKKNBauut/qVNPKZglhTaDDxA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.21.5", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.21.5.tgz", + "integrity": "sha512-MSJhmej/U9MrdPxDk7+FWhO8+UqVoZUHG4VvKT5RQ4RJtqtANTiWiI97LvoVNMtdMnHaKs1Pkji6wHUFxjJsHQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.21.5", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.21.5.tgz", + "integrity": "sha512-xN6+5/JsMrbZHL1lPl+MiNJ3Xza12ueBKPepiyDCFQzlhFRTj7D0LG+cfNTzPBTO8KcYQynLpl1iBB8LGp3Xtw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.21.5", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.21.5.tgz", + "integrity": "sha512-KfzFNhC4XTbmG3ma/xcTs/IhCwieW89XALIusKmnV0N618ZDXEB0XjWOYQRCXeK9mfqPdbTBpurEHV/XZtkniQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.21.5", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.21.5.tgz", + "integrity": "sha512-bc0GytQO5Mn9QM6szaZ+31fQHNdidgpM1sSCwzPItz8hg3wOvKl8039rU0veMJV3ZgC9z0ypNRceLrSHeRHmXw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.21.5", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.21.5.tgz", + "integrity": "sha512-JwMbgypPQgc2kW2av3OwzZ8cbrEuIiDiXPJdXRE6aVxu67yHauJawQLqJKTGUhiAhy6iLDG8Wg0a3/ziL+m+Kw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.21.5", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.21.5.tgz", + "integrity": "sha512-Ib8b6IQ/OR/VrPU6YBgy4T3QnuHY7DUa95O+nz+cwrTkMSN6fuHcTcIaz4t8TJ6HI5pl3uxUOZjmtls2pyQWow==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-loader": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lightningcss-loader/-/lightningcss-loader-2.1.0.tgz", + "integrity": "sha512-mB+M/lvs/GdXT4yc8ZiNgLUAbYpPI9grDyC3ybz/Zo6s4GZv53iZnLTnkJT/Qm3Sh89dbFUm+omoHFXCfZtcXw==", + "dependencies": { + "browserslist": "^4.21.4", + "lightningcss": "^1.16.0", + "webpack-sources": "^3.2.3" + }, + "peerDependencies": { + "webpack": ">=5" + } + }, + "node_modules/lightningcss-loader/node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.21.5", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.21.5.tgz", + "integrity": "sha512-A8cSi8lUpBeVmoF+DqqW7cd0FemDbCuKr490IXdjyeI+KL8adpSKUs8tcqO0OXPh1EoDqK7JNkD/dELmd4Iz5g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -6997,18 +7198,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/md5-hex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz", - "integrity": "sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==", - "dev": true, - "dependencies": { - "blueimp-md5": "^2.10.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/mdast-util-from-markdown": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", @@ -7153,9 +7342,9 @@ } }, "node_modules/mermaid": { - "version": "10.2.3", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.2.3.tgz", - "integrity": "sha512-cMVE5s9PlQvOwfORkyVpr5beMsLdInrycAosdr+tpZ0WFjG4RJ/bUHST7aTgHNJbujHkdBRAm+N50P3puQOfPw==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.2.4.tgz", + "integrity": "sha512-zHGjEI7lBvWZX+PQYmlhSA2p40OzW6QbGodTCSzDeVpqaTnyAC+2sRGqrpXO+uQk3CnoeClHQPraQUMStdqy2g==", "dependencies": { "@braintree/sanitize-url": "^6.0.2", "cytoscape": "^3.23.0", @@ -7656,9 +7845,9 @@ } }, "node_modules/minimatch": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.2.tgz", - "integrity": "sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -7714,9 +7903,9 @@ } }, "node_modules/monaco-editor": { - "version": "0.39.0", - "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.39.0.tgz", - "integrity": "sha512-zhbZ2Nx93tLR8aJmL2zI1mhJpsl87HMebNBM6R8z4pLfs8pj604pIVIVwyF1TivcfNtIPpMXL+nb3DsBmE/x6Q==" + "version": "0.40.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.40.0.tgz", + "integrity": "sha512-1wymccLEuFSMBvCk/jT1YDW/GuxMLYwnFwF9CDyYCxoTw2Pt379J3FUhwy9c43j51JdcxVPjwk0jm0EVDsBS2g==" }, "node_modules/monaco-editor-webpack-plugin": { "version": "7.0.1", @@ -7815,9 +8004,9 @@ } }, "node_modules/node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -7853,9 +8042,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz", - "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==" + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" }, "node_modules/non-layered-tidy-tree-layout": { "version": "2.0.2", @@ -7905,9 +8094,9 @@ } }, "node_modules/nwsapi": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.5.tgz", - "integrity": "sha512-6xpotnECFy/og7tKSBVmUNft7J3jyXAka4XvG6AUhFWRz+Q/Ljus7znJAA3bxColfQLdS+XsjoodtJfCgeTEFQ==", + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", + "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==", "dev": true }, "node_modules/obj-props": { @@ -7989,17 +8178,17 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -8195,13 +8384,13 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-scurry": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz", - "integrity": "sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", "dev": true, "dependencies": { - "lru-cache": "^9.1.1", - "minipass": "^5.0.0 || ^6.0.2" + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -8211,9 +8400,9 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.2.tgz", - "integrity": "sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.0.tgz", + "integrity": "sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw==", "dev": true, "engines": { "node": "14 || >=16.14" @@ -8371,9 +8560,9 @@ } }, "node_modules/postcss": { - "version": "8.4.24", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", - "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==", + "version": "8.4.25", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.25.tgz", + "integrity": "sha512-7taJ/8t2av0Z+sQEvNzCkpDynl0tX3uJMCODi6nT3PfASC7dYCWV9aQ+uiCf+KBD4SEFcu+GvJdGdwzQ6OSjCw==", "funding": [ { "type": "opencollective", @@ -8522,17 +8711,17 @@ } }, "node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", "dev": true, "dependencies": { - "ansi-regex": "^5.0.1", + "@jest/schemas": "^29.6.0", "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" + "react-is": "^18.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/pretty-format/node_modules/ansi-styles": { @@ -8708,9 +8897,9 @@ } }, "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, "node_modules/read-pkg": { @@ -9210,9 +9399,9 @@ } }, "node_modules/semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -10071,25 +10260,21 @@ "node": ">=12.22" } }, - "node_modules/time-zone": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", - "integrity": "sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/tinybench": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.0.tgz", "integrity": "sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==", "dev": true }, + "node_modules/tinycolor2": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" + }, "node_modules/tinypool": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.5.0.tgz", - "integrity": "sha512-paHQtnrlS1QZYKF/GnLoOM/DN9fqaGOFbCbxzAhwniySnzl9Ebk8w73/dd34DAhe/obUbPAOldTyYXQZxnPBPQ==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.6.0.tgz", + "integrity": "sha512-FdswUUo5SxRizcBc6b1GSuLpLjisa8N8qMyYoP3rl+bym+QauhtJP5bvZY1ytt8krKGmMLYIRl36HBZfeAoqhQ==", "dev": true, "engines": { "node": ">=14.0.0" @@ -10369,9 +10554,9 @@ } }, "node_modules/updates": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/updates/-/updates-14.2.8.tgz", - "integrity": "sha512-Ca+M1vKKBBRiQSi3yrN8OdncmP9osIf1oJM/HpEIHeDvyGLs/noTi9X2LS4zl50VXRTSCqssF5CZN0XWzSPigg==", + "version": "14.3.2", + "resolved": "https://registry.npmjs.org/updates/-/updates-14.3.2.tgz", + "integrity": "sha512-cgEaWadntOSW8aFG6b956U3TVrMbRzZnF+iHjJhLEGvyV36v7cZ0RVFW3eZ4iLYyWZ2E7/aV3DrA/W6rLwpS1g==", "dev": true, "bin": { "updates": "bin/updates.js" @@ -10463,14 +10648,14 @@ } }, "node_modules/vite": { - "version": "4.3.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz", - "integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==", + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.2.tgz", + "integrity": "sha512-zUcsJN+UvdSyHhYa277UHhiJ3iq4hUBwHavOpsNUGsTgjBeoBlK8eDt+iT09pBq0h9/knhG/SPrZiM7cGmg7NA==", "dev": true, "dependencies": { - "esbuild": "^0.17.5", - "postcss": "^8.4.23", - "rollup": "^3.21.0" + "esbuild": "^0.18.10", + "postcss": "^8.4.24", + "rollup": "^3.25.2" }, "bin": { "vite": "bin/vite.js" @@ -10478,12 +10663,16 @@ "engines": { "node": "^14.18.0 || >=16.0.0" }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@types/node": ">= 14", "less": "*", + "lightningcss": "^1.21.0", "sass": "*", "stylus": "*", "sugarss": "*", @@ -10496,6 +10685,9 @@ "less": { "optional": true }, + "lightningcss": { + "optional": true + }, "sass": { "optional": true }, @@ -10511,15 +10703,15 @@ } }, "node_modules/vite-node": { - "version": "0.32.2", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.32.2.tgz", - "integrity": "sha512-dTQ1DCLwl2aEseov7cfQ+kDMNJpM1ebpyMMMwWzBvLbis8Nla/6c9WQcqpPssTwS6Rp/+U6KwlIj8Eapw4bLdA==", + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.33.0.tgz", + "integrity": "sha512-19FpHYbwWWxDr73ruNahC+vtEdza52kA90Qb3La98yZ0xULqV8A5JLNPUff0f5zID4984tW7l3DH2przTJUZSw==", "dev": true, "dependencies": { "cac": "^6.7.14", "debug": "^4.3.4", - "mlly": "^1.2.0", - "pathe": "^1.1.0", + "mlly": "^1.4.0", + "pathe": "^1.1.1", "picocolors": "^1.0.0", "vite": "^3.0.0 || ^4.0.0" }, @@ -10533,10 +10725,408 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/vite-string-plugin": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vite-string-plugin/-/vite-string-plugin-1.1.0.tgz", + "integrity": "sha512-RMxstCLl6Zyyz4tkzzHDFrrVvom1GAxjo2lTmgfus5CZYOnFNcJ2iQiDaFpc4KAOHSNkBNtkj5YauSs+f1gqCA==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.11.tgz", + "integrity": "sha512-q4qlUf5ucwbUJZXF5tEQ8LF7y0Nk4P58hOsGk3ucY0oCwgQqAnqXVbUuahCddVHfrxmpyewRpiTHwVHIETYu7Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.11.tgz", + "integrity": "sha512-snieiq75Z1z5LJX9cduSAjUr7vEI1OdlzFPMw0HH5YI7qQHDd3qs+WZoMrWYDsfRJSq36lIA6mfZBkvL46KoIw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.11.tgz", + "integrity": "sha512-iPuoxQEV34+hTF6FT7om+Qwziv1U519lEOvekXO9zaMMlT9+XneAhKL32DW3H7okrCOBQ44BMihE8dclbZtTuw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.11.tgz", + "integrity": "sha512-Gm0QkI3k402OpfMKyQEEMG0RuW2LQsSmI6OeO4El2ojJMoF5NLYb3qMIjvbG/lbMeLOGiW6ooU8xqc+S0fgz2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.11.tgz", + "integrity": "sha512-N15Vzy0YNHu6cfyDOjiyfJlRJCB/ngKOAvoBf1qybG3eOq0SL2Lutzz9N7DYUbb7Q23XtHPn6lMDF6uWbGv9Fw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.11.tgz", + "integrity": "sha512-atEyuq6a3omEY5qAh5jIORWk8MzFnCpSTUruBgeyN9jZq1K/QI9uke0ATi3MHu4L8c59CnIi4+1jDKMuqmR71A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.11.tgz", + "integrity": "sha512-XtuPrEfBj/YYYnAAB7KcorzzpGTvOr/dTtXPGesRfmflqhA4LMF0Gh/n5+a9JBzPuJ+CGk17CA++Hmr1F/gI0Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.11.tgz", + "integrity": "sha512-Idipz+Taso/toi2ETugShXjQ3S59b6m62KmLHkJlSq/cBejixmIydqrtM2XTvNCywFl3VC7SreSf6NV0i6sRyg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.11.tgz", + "integrity": "sha512-c6Vh2WS9VFKxKZ2TvJdA7gdy0n6eSy+yunBvv4aqNCEhSWVor1TU43wNRp2YLO9Vng2G+W94aRz+ILDSwAiYog==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.11.tgz", + "integrity": "sha512-S3hkIF6KUqRh9n1Q0dSyYcWmcVa9Cg+mSoZEfFuzoYXXsk6196qndrM+ZiHNwpZKi3XOXpShZZ+9dfN5ykqjjw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.11.tgz", + "integrity": "sha512-MRESANOoObQINBA+RMZW+Z0TJWpibtE7cPFnahzyQHDCA9X9LOmGh68MVimZlM9J8n5Ia8lU773te6O3ILW8kw==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.11.tgz", + "integrity": "sha512-qVyPIZrXNMOLYegtD1u8EBccCrBVshxMrn5MkuFc3mEVsw7CCQHaqZ4jm9hbn4gWY95XFnb7i4SsT3eflxZsUg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.11.tgz", + "integrity": "sha512-T3yd8vJXfPirZaUOoA9D2ZjxZX4Gr3QuC3GztBJA6PklLotc/7sXTOuuRkhE9W/5JvJP/K9b99ayPNAD+R+4qQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.11.tgz", + "integrity": "sha512-evUoRPWiwuFk++snjH9e2cAjF5VVSTj+Dnf+rkO/Q20tRqv+644279TZlPK8nUGunjPAtQRCj1jQkDAvL6rm2w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.11.tgz", + "integrity": "sha512-/SlRJ15XR6i93gRWquRxYCfhTeC5PdqEapKoLbX63PLCmAkXZHY2uQm2l9bN0oPHBsOw2IswRZctMYS0MijFcg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.11.tgz", + "integrity": "sha512-xcncej+wF16WEmIwPtCHi0qmx1FweBqgsRtEL1mSHLFR6/mb3GEZfLQnx+pUDfRDEM4DQF8dpXIW7eDOZl1IbA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.11.tgz", + "integrity": "sha512-aSjMHj/F7BuS1CptSXNg6S3M4F3bLp5wfFPIJM+Km2NfIVfFKhdmfHF9frhiCLIGVzDziggqWll0B+9AUbud/Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.11.tgz", + "integrity": "sha512-tNBq+6XIBZtht0xJGv7IBB5XaSyvYPCm1PxJ33zLQONdZoLVM0bgGqUrXnJyiEguD9LU4AHiu+GCXy/Hm9LsdQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.11.tgz", + "integrity": "sha512-kxfbDOrH4dHuAAOhr7D7EqaYf+W45LsAOOhAet99EyuxxQmjbk8M9N4ezHcEiCYPaiW8Dj3K26Z2V17Gt6p3ng==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.11.tgz", + "integrity": "sha512-Sh0dDRyk1Xi348idbal7lZyfSkjhJsdFeuC13zqdipsvMetlGiFQNdO+Yfp6f6B4FbyQm7qsk16yaZk25LChzg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.11.tgz", + "integrity": "sha512-o9JUIKF1j0rqJTFbIoF4bXj6rvrTZYOrfRcGyL0Vm5uJ/j5CkBD/51tpdxe9lXEDouhRgdr/BYzUrDOvrWwJpg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.11.tgz", + "integrity": "sha512-rQI4cjLHd2hGsM1LqgDI7oOCYbQ6IBOVsX9ejuRMSze0GqXUG2ekwiKkiBU1pRGSeCqFFHxTrcEydB2Hyoz9CA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.11.tgz", + "integrity": "sha512-i8u6mQF0JKJUlGR3OdFLKldJQMMs8OqM9Cc3UCi9XXziJ9WERM5bfkHaEAy0YAvPRMgqSW55W7xYn84XtEFTtA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.11", + "@esbuild/android-arm64": "0.18.11", + "@esbuild/android-x64": "0.18.11", + "@esbuild/darwin-arm64": "0.18.11", + "@esbuild/darwin-x64": "0.18.11", + "@esbuild/freebsd-arm64": "0.18.11", + "@esbuild/freebsd-x64": "0.18.11", + "@esbuild/linux-arm": "0.18.11", + "@esbuild/linux-arm64": "0.18.11", + "@esbuild/linux-ia32": "0.18.11", + "@esbuild/linux-loong64": "0.18.11", + "@esbuild/linux-mips64el": "0.18.11", + "@esbuild/linux-ppc64": "0.18.11", + "@esbuild/linux-riscv64": "0.18.11", + "@esbuild/linux-s390x": "0.18.11", + "@esbuild/linux-x64": "0.18.11", + "@esbuild/netbsd-x64": "0.18.11", + "@esbuild/openbsd-x64": "0.18.11", + "@esbuild/sunos-x64": "0.18.11", + "@esbuild/win32-arm64": "0.18.11", + "@esbuild/win32-ia32": "0.18.11", + "@esbuild/win32-x64": "0.18.11" + } + }, "node_modules/vite/node_modules/rollup": { - "version": "3.25.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.25.3.tgz", - "integrity": "sha512-ZT279hx8gszBj9uy5FfhoG4bZx8c+0A1sbqtr7Q3KNWIizpTdDEPZbV2xcbvHsnFp4MavCQYZyzApJ+virB8Yw==", + "version": "3.26.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.26.2.tgz", + "integrity": "sha512-6umBIGVz93er97pMgQO08LuH3m6PUb3jlDUUGFsNJB6VgTCUaDFpupf5JfU30529m/UKOgmiX+uY6Sx8cOYpLA==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -10550,35 +11140,34 @@ } }, "node_modules/vitest": { - "version": "0.32.2", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.32.2.tgz", - "integrity": "sha512-hU8GNNuQfwuQmqTLfiKcqEhZY72Zxb7nnN07koCUNmntNxbKQnVbeIS6sqUgR3eXSlbOpit8+/gr1KpqoMgWCQ==", + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.33.0.tgz", + "integrity": "sha512-1CxaugJ50xskkQ0e969R/hW47za4YXDUfWJDxip1hwbnhUjYolpfUn2AMOulqG/Dtd9WYAtkHmM/m3yKVrEejQ==", "dev": true, "dependencies": { "@types/chai": "^4.3.5", "@types/chai-subset": "^1.3.3", "@types/node": "*", - "@vitest/expect": "0.32.2", - "@vitest/runner": "0.32.2", - "@vitest/snapshot": "0.32.2", - "@vitest/spy": "0.32.2", - "@vitest/utils": "0.32.2", - "acorn": "^8.8.2", + "@vitest/expect": "0.33.0", + "@vitest/runner": "0.33.0", + "@vitest/snapshot": "0.33.0", + "@vitest/spy": "0.33.0", + "@vitest/utils": "0.33.0", + "acorn": "^8.9.0", "acorn-walk": "^8.2.0", "cac": "^6.7.14", "chai": "^4.3.7", - "concordance": "^5.0.4", "debug": "^4.3.4", "local-pkg": "^0.4.3", - "magic-string": "^0.30.0", - "pathe": "^1.1.0", + "magic-string": "^0.30.1", + "pathe": "^1.1.1", "picocolors": "^1.0.0", - "std-env": "^3.3.2", + "std-env": "^3.3.3", "strip-literal": "^1.0.1", "tinybench": "^2.5.0", - "tinypool": "^0.5.0", + "tinypool": "^0.6.0", "vite": "^3.0.0 || ^4.0.0", - "vite-node": "0.32.2", + "vite-node": "0.33.0", "why-is-node-running": "^2.2.2" }, "bin": { @@ -10627,13 +11216,19 @@ } } }, + "node_modules/vitest/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, "node_modules/vitest/node_modules/magic-string": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz", - "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==", + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz", + "integrity": "sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==", "dev": true, "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" + "@jridgewell/sourcemap-codec": "^1.4.15" }, "engines": { "node": ">=12" @@ -10772,9 +11367,9 @@ } }, "node_modules/webpack": { - "version": "5.88.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.0.tgz", - "integrity": "sha512-O3jDhG5e44qIBSi/P6KpcCcH7HD+nYIHVBhdWFxcLOcIGN8zGo5nqF3BjyNCxIh4p1vFdNnreZv2h2KkoAw3lw==", + "version": "5.88.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.1.tgz", + "integrity": "sha512-FROX3TxQnC/ox4N+3xQoWZzvGXSuscxR32rbzjpXgEzWudJFEJBpdlkkob2ylrv5yzzufD1zph1OoFsLtm6stQ==", "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.0", @@ -10890,6 +11485,11 @@ "source-map": "~0.6.1" } }, + "node_modules/webpack/node_modules/@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==" + }, "node_modules/webpack/node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -10963,15 +11563,6 @@ "node": ">=10.13.0" } }, - "node_modules/well-known-symbols": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", - "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/whatwg-encoding": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", diff --git a/package.json b/package.json index da95145e4abbc..10956595b6891 100644 --- a/package.json +++ b/package.json @@ -24,21 +24,23 @@ "easymde": "2.18.0", "esbuild-loader": "3.0.1", "escape-goat": "4.0.0", - "fast-glob": "3.2.12", + "fast-glob": "3.3.0", "jquery": "3.7.0", "jquery.are-you-sure": "1.9.0", "katex": "0.16.8", "license-checker-webpack-plugin": "0.2.1", - "mermaid": "10.2.3", + "lightningcss-loader": "2.1.0", + "mermaid": "10.2.4", "mini-css-extract-plugin": "2.7.6", - "minimatch": "9.0.2", - "monaco-editor": "0.39.0", + "minimatch": "9.0.3", + "monaco-editor": "0.40.0", "monaco-editor-webpack-plugin": "7.0.1", "pdfobject": "2.2.12", "pretty-ms": "8.0.0", "sortablejs": "1.15.0", "swagger-ui-dist": "5.1.0", "throttle-debounce": "5.0.0", + "tinycolor2": "1.6.0", "tippy.js": "6.3.7", "toastify-js": "1.12.0", "tributejs": "5.1.3", @@ -47,17 +49,16 @@ "vue-bar-graph": "2.0.0", "vue-loader": "17.2.2", "vue3-calendar-heatmap": "2.0.5", - "webpack": "5.88.0", + "webpack": "5.88.1", "webpack-cli": "5.1.4", "wrap-ansi": "8.1.0" }, "devDependencies": { "@eslint-community/eslint-plugin-eslint-comments": "3.2.1", "@playwright/test": "1.35.1", - "@rollup/pluginutils": "5.0.2", "@stoplight/spectral-cli": "6.8.0", "@vitejs/plugin-vue": "4.2.3", - "eslint": "8.43.0", + "eslint": "8.44.0", "eslint-plugin-array-func": "3.1.8", "eslint-plugin-custom-elements": "0.0.8", "eslint-plugin-import": "2.27.5", @@ -77,8 +78,9 @@ "stylelint-declaration-strict-value": "1.9.2", "stylelint-stylistic": "0.4.2", "svgo": "3.0.2", - "updates": "14.2.8", - "vitest": "0.32.2" + "updates": "14.3.2", + "vite-string-plugin": "1.1.0", + "vitest": "0.33.0" }, "browserslist": [ "defaults", diff --git a/pyproject.toml b/pyproject.toml index 7a30f5914066e..43c6b050bb64e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,4 +12,4 @@ djlint = "1.31.1" [tool.djlint] profile="golang" -ignore="H005,H006,H008,H013,H014,H016,H020,H021,H023,H026,H030,H031,T027" +ignore="H005,H006,H008,H013,H016,H020,H021,H026,H030,H031,T027" diff --git a/routers/api/actions/runner/utils.go b/routers/api/actions/runner/utils.go index 834a8c44000c7..e95df7a00fa80 100644 --- a/routers/api/actions/runner/utils.go +++ b/routers/api/actions/runner/utils.go @@ -129,12 +129,22 @@ func generateTaskContext(t *actions_model.ActionTask) *structpb.Struct { baseRef := "" headRef := "" + ref := t.Job.Run.Ref + sha := t.Job.Run.CommitSHA if pullPayload, err := t.Job.Run.GetPullRequestEventPayload(); err == nil && pullPayload.PullRequest != nil && pullPayload.PullRequest.Base != nil && pullPayload.PullRequest.Head != nil { baseRef = pullPayload.PullRequest.Base.Ref headRef = pullPayload.PullRequest.Head.Ref + + // if the TriggerEvent is pull_request_target, ref and sha need to be set according to the base of pull request + // In GitHub's documentation, ref should be the branch or tag that triggered workflow. But when the TriggerEvent is pull_request_target, + // the ref will be the base branch. + if t.Job.Run.TriggerEvent == actions_module.GithubEventPullRequestTarget { + ref = git.BranchPrefix + pullPayload.PullRequest.Base.Name + sha = pullPayload.PullRequest.Base.Sha + } } - refName := git.RefName(t.Job.Run.Ref) + refName := git.RefName(ref) taskContext, err := structpb.NewStruct(map[string]any{ // standard contexts, see https://docs.github.com/en/actions/learn-github-actions/contexts#github-context @@ -153,7 +163,7 @@ func generateTaskContext(t *actions_model.ActionTask) *structpb.Struct { "graphql_url": "", // string, The URL of the GitHub GraphQL API. "head_ref": headRef, // string, The head_ref or source branch of the pull request in a workflow run. This property is only available when the event that triggers a workflow run is either pull_request or pull_request_target. "job": fmt.Sprint(t.JobID), // string, The job_id of the current job. - "ref": t.Job.Run.Ref, // string, The fully-formed ref of the branch or tag that triggered the workflow run. For workflows triggered by push, this is the branch or tag ref that was pushed. For workflows triggered by pull_request, this is the pull request merge branch. For workflows triggered by release, this is the release tag created. For other triggers, this is the branch or tag ref that triggered the workflow run. This is only set if a branch or tag is available for the event type. The ref given is fully-formed, meaning that for branches the format is refs/heads/, for pull requests it is refs/pull//merge, and for tags it is refs/tags/. For example, refs/heads/feature-branch-1. + "ref": ref, // string, The fully-formed ref of the branch or tag that triggered the workflow run. For workflows triggered by push, this is the branch or tag ref that was pushed. For workflows triggered by pull_request, this is the pull request merge branch. For workflows triggered by release, this is the release tag created. For other triggers, this is the branch or tag ref that triggered the workflow run. This is only set if a branch or tag is available for the event type. The ref given is fully-formed, meaning that for branches the format is refs/heads/, for pull requests it is refs/pull//merge, and for tags it is refs/tags/. For example, refs/heads/feature-branch-1. "ref_name": refName.ShortName(), // string, The short ref name of the branch or tag that triggered the workflow run. This value matches the branch or tag name shown on GitHub. For example, feature-branch-1. "ref_protected": false, // boolean, true if branch protections are configured for the ref that triggered the workflow run. "ref_type": refName.RefType(), // string, The type of ref that triggered the workflow run. Valid values are branch or tag. @@ -167,7 +177,7 @@ func generateTaskContext(t *actions_model.ActionTask) *structpb.Struct { "run_attempt": fmt.Sprint(t.Job.Attempt), // string, A unique number for each attempt of a particular workflow run in a repository. This number begins at 1 for the workflow run's first attempt, and increments with each re-run. "secret_source": "Actions", // string, The source of a secret used in a workflow. Possible values are None, Actions, Dependabot, or Codespaces. "server_url": setting.AppURL, // string, The URL of the GitHub server. For example: https://github.com. - "sha": t.Job.Run.CommitSHA, // string, The commit SHA that triggered the workflow. The value of this commit SHA depends on the event that triggered the workflow. For more information, see "Events that trigger workflows." For example, ffac537e6cbbf934b08745a378932722df287a53. + "sha": sha, // string, The commit SHA that triggered the workflow. The value of this commit SHA depends on the event that triggered the workflow. For more information, see "Events that trigger workflows." For example, ffac537e6cbbf934b08745a378932722df287a53. "token": t.Token, // string, A token to authenticate on behalf of the GitHub App installed on your repository. This is functionally equivalent to the GITHUB_TOKEN secret. For more information, see "Automatic token authentication." "triggering_actor": "", // string, The username of the user that initiated the workflow run. If the workflow run is a re-run, this value may differ from github.actor. Any workflow re-runs will use the privileges of github.actor, even if the actor initiating the re-run (github.triggering_actor) has different privileges. "workflow": t.Job.Run.WorkflowID, // string, The name of the workflow. If the workflow file doesn't specify a name, the value of this property is the full path of the workflow file in the repository. diff --git a/routers/api/packages/container/container.go b/routers/api/packages/container/container.go index 126be43cdd59c..8f79805cc8b36 100644 --- a/routers/api/packages/container/container.go +++ b/routers/api/packages/container/container.go @@ -203,17 +203,25 @@ func InitiateUploadBlob(ctx *context.Context) { Digest: mount, }) if blob != nil { - if err := mountBlob(&packages_service.PackageInfo{Owner: ctx.Package.Owner, Name: image}, blob.Blob); err != nil { + accessible, err := packages_model.IsBlobAccessibleForUser(ctx, blob.Blob.ID, ctx.Doer) + if err != nil { apiError(ctx, http.StatusInternalServerError, err) return } - setResponseHeaders(ctx.Resp, &containerHeaders{ - Location: fmt.Sprintf("/v2/%s/%s/blobs/%s", ctx.Package.Owner.LowerName, image, mount), - ContentDigest: mount, - Status: http.StatusCreated, - }) - return + if accessible { + if err := mountBlob(&packages_service.PackageInfo{Owner: ctx.Package.Owner, Name: image}, blob.Blob); err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + + setResponseHeaders(ctx.Resp, &containerHeaders{ + Location: fmt.Sprintf("/v2/%s/%s/blobs/%s", ctx.Package.Owner.LowerName, image, mount), + ContentDigest: mount, + Status: http.StatusCreated, + }) + return + } } } diff --git a/routers/api/v1/activitypub/reqsignature.go b/routers/api/v1/activitypub/reqsignature.go index 2d945c27a51cb..3f60ed7776a3f 100644 --- a/routers/api/v1/activitypub/reqsignature.go +++ b/routers/api/v1/activitypub/reqsignature.go @@ -25,19 +25,16 @@ func getPublicKeyFromResponse(b []byte, keyID *url.URL) (p crypto.PublicKey, err person := ap.PersonNew(ap.IRI(keyID.String())) err = person.UnmarshalJSON(b) if err != nil { - err = fmt.Errorf("ActivityStreams type cannot be converted to one known to have publicKey property: %w", err) - return + return nil, fmt.Errorf("ActivityStreams type cannot be converted to one known to have publicKey property: %w", err) } pubKey := person.PublicKey if pubKey.ID.String() != keyID.String() { - err = fmt.Errorf("cannot find publicKey with id: %s in %s", keyID, string(b)) - return + return nil, fmt.Errorf("cannot find publicKey with id: %s in %s", keyID, string(b)) } pubKeyPem := pubKey.PublicKeyPem block, _ := pem.Decode([]byte(pubKeyPem)) if block == nil || block.Type != "PUBLIC KEY" { - err = fmt.Errorf("could not decode publicKeyPem to PUBLIC KEY pem block type") - return + return nil, fmt.Errorf("could not decode publicKeyPem to PUBLIC KEY pem block type") } p, err = x509.ParsePKIXPublicKey(block.Bytes) return p, err @@ -49,13 +46,12 @@ func fetch(iri *url.URL) (b []byte, err error) { req.Header("User-Agent", "Gitea/"+setting.AppVer) resp, err := req.Response() if err != nil { - return + return nil, err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - err = fmt.Errorf("url IRI fetch [%s] failed with status (%d): %s", iri, resp.StatusCode, resp.Status) - return + return nil, fmt.Errorf("url IRI fetch [%s] failed with status (%d): %s", iri, resp.StatusCode, resp.Status) } b, err = io.ReadAll(io.LimitReader(resp.Body, setting.Federation.MaxSize)) return b, err @@ -67,21 +63,21 @@ func verifyHTTPSignatures(ctx *gitea_context.APIContext) (authenticated bool, er // 1. Figure out what key we need to verify v, err := httpsig.NewVerifier(r) if err != nil { - return + return false, err } ID := v.KeyId() idIRI, err := url.Parse(ID) if err != nil { - return + return false, err } // 2. Fetch the public key of the other actor b, err := fetch(idIRI) if err != nil { - return + return false, err } pubKey, err := getPublicKeyFromResponse(b, idIRI) if err != nil { - return + return false, err } // 3. Verify the other actor's key algo := httpsig.Algorithm(setting.Federation.Algorithms[0]) diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index 48f890ee552b1..bf37532fc86f4 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -219,7 +219,7 @@ func GetRawFileOrLFS(ctx *context.APIContext) { common.ServeContentByReadSeeker(ctx.Base, ctx.Repo.TreePath, lastModified, lfsDataRc) } -func getBlobForEntry(ctx *context.APIContext) (blob *git.Blob, entry *git.TreeEntry, lastModified time.Time) { +func getBlobForEntry(ctx *context.APIContext) (blob *git.Blob, entry *git.TreeEntry, lastModified *time.Time) { entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath) if err != nil { if git.IsErrNotExist(err) { @@ -227,23 +227,23 @@ func getBlobForEntry(ctx *context.APIContext) (blob *git.Blob, entry *git.TreeEn } else { ctx.Error(http.StatusInternalServerError, "GetTreeEntryByPath", err) } - return + return nil, nil, nil } if entry.IsDir() || entry.IsSubModule() { ctx.NotFound("getBlobForEntry", nil) - return + return nil, nil, nil } info, _, err := git.Entries([]*git.TreeEntry{entry}).GetCommitsInfo(ctx, ctx.Repo.Commit, path.Dir("/" + ctx.Repo.TreePath)[1:]) if err != nil { ctx.Error(http.StatusInternalServerError, "GetCommitsInfo", err) - return + return nil, nil, nil } if len(info) == 1 { // Not Modified - lastModified = info[0].Commit.Committer.When + lastModified = &info[0].Commit.Committer.When } blob = entry.Blob() diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 49252f7a4b49a..e76775ae82226 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -195,7 +195,7 @@ func SearchIssues(ctx *context.APIContext) { } var issueIDs []int64 if len(keyword) > 0 && len(repoIDs) > 0 { - if issueIDs, err = issue_indexer.SearchIssuesByKeyword(ctx, repoIDs, keyword); err != nil { + if issueIDs, err = issue_indexer.SearchIssuesByKeyword(ctx, repoIDs, keyword, ctx.FormString("state")); err != nil { ctx.Error(http.StatusInternalServerError, "SearchIssuesByKeyword", err) return } @@ -394,7 +394,7 @@ func ListIssues(ctx *context.APIContext) { var issueIDs []int64 var labelIDs []int64 if len(keyword) > 0 { - issueIDs, err = issue_indexer.SearchIssuesByKeyword(ctx, []int64{ctx.Repo.Repository.ID}, keyword) + issueIDs, err = issue_indexer.SearchIssuesByKeyword(ctx, []int64{ctx.Repo.Repository.ID}, keyword, ctx.FormString("state")) if err != nil { ctx.Error(http.StatusInternalServerError, "SearchIssuesByKeyword", err) return diff --git a/routers/api/v1/repo/issue_label.go b/routers/api/v1/repo/issue_label.go index 1f0d21141bcce..9d43c66d8c99c 100644 --- a/routers/api/v1/repo/issue_label.go +++ b/routers/api/v1/repo/issue_label.go @@ -298,26 +298,26 @@ func ClearIssueLabels(ctx *context.APIContext) { ctx.Status(http.StatusNoContent) } -func prepareForReplaceOrAdd(ctx *context.APIContext, form api.IssueLabelsOption) (issue *issues_model.Issue, labels []*issues_model.Label, err error) { - issue, err = issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) +func prepareForReplaceOrAdd(ctx *context.APIContext, form api.IssueLabelsOption) (*issues_model.Issue, []*issues_model.Label, error) { + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) } - return + return nil, nil, err } - labels, err = issues_model.GetLabelsByIDs(form.Labels) + labels, err := issues_model.GetLabelsByIDs(form.Labels) if err != nil { ctx.Error(http.StatusInternalServerError, "GetLabelsByIDs", err) - return + return nil, nil, err } if !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) { ctx.Status(http.StatusForbidden) - return + return nil, nil, nil } return issue, labels, err diff --git a/routers/common/serve.go b/routers/common/serve.go index 3094ee6a6ec9b..8a7f8b3332127 100644 --- a/routers/common/serve.go +++ b/routers/common/serve.go @@ -15,7 +15,7 @@ import ( ) // ServeBlob download a git.Blob -func ServeBlob(ctx *context.Base, filePath string, blob *git.Blob, lastModified time.Time) error { +func ServeBlob(ctx *context.Base, filePath string, blob *git.Blob, lastModified *time.Time) error { if httpcache.HandleGenericETagTimeCache(ctx.Req, ctx.Resp, `"`+blob.ID.String()+`"`, lastModified) { return nil } @@ -38,6 +38,6 @@ func ServeContentByReader(ctx *context.Base, filePath string, size int64, reader httplib.ServeContentByReader(ctx.Req, ctx.Resp, filePath, size, reader) } -func ServeContentByReadSeeker(ctx *context.Base, filePath string, modTime time.Time, reader io.ReadSeeker) { +func ServeContentByReadSeeker(ctx *context.Base, filePath string, modTime *time.Time, reader io.ReadSeeker) { httplib.ServeContentByReadSeeker(ctx.Req, ctx.Resp, filePath, modTime, reader) } diff --git a/routers/install/install.go b/routers/install/install.go index f121f313769d1..a2e89d3dac48d 100644 --- a/routers/install/install.go +++ b/routers/install/install.go @@ -56,6 +56,7 @@ func getSupportedDbTypeNames() (dbTypeNames []map[string]string) { func Contexter() func(next http.Handler) http.Handler { rnd := templates.HTMLRenderer() dbTypeNames := getSupportedDbTypeNames() + envConfigKeys := setting.CollectEnvConfigKeys() return func(next http.Handler) http.Handler { return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { base, baseCleanUp := context.NewBaseContext(resp, req) @@ -70,11 +71,13 @@ func Contexter() func(next http.Handler) http.Handler { ctx.AppendContextValue(context.WebContextKey, ctx) ctx.Data.MergeFrom(middleware.CommonTemplateContextData()) ctx.Data.MergeFrom(middleware.ContextData{ - "locale": ctx.Locale, - "Title": ctx.Locale.Tr("install.install"), - "PageIsInstall": true, - "DbTypeNames": dbTypeNames, - "AllLangs": translation.AllLangs(), + "locale": ctx.Locale, + "Title": ctx.Locale.Tr("install.install"), + "PageIsInstall": true, + "DbTypeNames": dbTypeNames, + "EnvConfigKeys": envConfigKeys, + "CustomConfFile": setting.CustomConf, + "AllLangs": translation.AllLangs(), "PasswordHashAlgorithms": hash.RecommendedHashAlgorithms, }) @@ -218,7 +221,7 @@ func checkDatabase(ctx *context.Context, form *forms.InstallForm) bool { return false } - log.Info("User confirmed reinstallation of Gitea into a pre-existing database") + log.Info("User confirmed re-installation of Gitea into a pre-existing database") } if hasPostInstallationUser || dbMigrationVersion > 0 { @@ -502,6 +505,8 @@ func SubmitInstall(ctx *context.Context) { return } + setting.EnvironmentToConfig(cfg, os.Environ()) + if err = cfg.SaveTo(setting.CustomConf); err != nil { ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form) return @@ -568,6 +573,7 @@ func SubmitInstall(ctx *context.Context) { } } + setting.ClearEnvConfigKeys() log.Info("First-time run install finished!") InstallDone(ctx) diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go index 9f13952257472..3bf133f56222c 100644 --- a/routers/web/auth/auth.go +++ b/routers/web/auth/auth.go @@ -497,23 +497,23 @@ func createUserInContext(ctx *context.Context, tpl base.TplName, form any, u *us hasUser, err = user_model.GetUser(user) if !hasUser || err != nil { ctx.ServerError("UserLinkAccount", err) - return + return false } } // TODO: probably we should respect 'remember' user's choice... linkAccount(ctx, user, *gothUser, true) - return // user is already created here, all redirects are handled + return false // user is already created here, all redirects are handled } else if setting.OAuth2Client.AccountLinking == setting.OAuth2AccountLinkingLogin { showLinkingLogin(ctx, *gothUser) - return // user will be created only after linking login + return false // user will be created only after linking login } } // handle error without template if len(tpl) == 0 { ctx.ServerError("CreateUser", err) - return + return false } // handle error with template @@ -542,7 +542,7 @@ func createUserInContext(ctx *context.Context, tpl base.TplName, form any, u *us default: ctx.ServerError("CreateUser", err) } - return + return false } log.Trace("Account created: %s", u.Name) return true @@ -559,7 +559,7 @@ func handleUserCreated(ctx *context.Context, u *user_model.User, gothUser *goth. u.SetLastLogin() if err := user_model.UpdateUserCols(ctx, u, "is_admin", "is_active", "last_login_unix"); err != nil { ctx.ServerError("UpdateUser", err) - return + return false } } @@ -577,7 +577,7 @@ func handleUserCreated(ctx *context.Context, u *user_model.User, gothUser *goth. if setting.Service.RegisterManualConfirm { ctx.Data["ManualActivationOnly"] = true ctx.HTML(http.StatusOK, TplActivate) - return + return false } mailer.SendActivateAccountMail(ctx.Locale, u) @@ -592,7 +592,7 @@ func handleUserCreated(ctx *context.Context, u *user_model.User, gothUser *goth. log.Error("Set cache(MailResendLimit) fail: %v", err) } } - return + return false } return true diff --git a/routers/web/repo/attachment.go b/routers/web/repo/attachment.go index af1842ad109a5..b7be77914f045 100644 --- a/routers/web/repo/attachment.go +++ b/routers/web/repo/attachment.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/upload" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/common" "code.gitea.io/gitea/services/attachment" repo_service "code.gitea.io/gitea/services/repository" @@ -148,7 +149,7 @@ func ServeAttachment(ctx *context.Context, uuid string) { } defer fr.Close() - common.ServeContentByReadSeeker(ctx.Base, attach.Name, attach.CreatedUnix.AsTime(), fr) + common.ServeContentByReadSeeker(ctx.Base, attach.Name, util.ToPointer(attach.CreatedUnix.AsTime()), fr) } // GetAttachment serve attachments diff --git a/routers/web/repo/download.go b/routers/web/repo/download.go index fd67b82ef277a..a9e2e2b2fad77 100644 --- a/routers/web/repo/download.go +++ b/routers/web/repo/download.go @@ -20,7 +20,7 @@ import ( ) // ServeBlobOrLFS download a git.Blob redirecting to LFS if necessary -func ServeBlobOrLFS(ctx *context.Context, blob *git.Blob, lastModified time.Time) error { +func ServeBlobOrLFS(ctx *context.Context, blob *git.Blob, lastModified *time.Time) error { if httpcache.HandleGenericETagTimeCache(ctx.Req, ctx.Resp, `"`+blob.ID.String()+`"`, lastModified) { return nil } @@ -82,7 +82,7 @@ func ServeBlobOrLFS(ctx *context.Context, blob *git.Blob, lastModified time.Time return common.ServeBlob(ctx.Base, ctx.Repo.TreePath, blob, lastModified) } -func getBlobForEntry(ctx *context.Context) (blob *git.Blob, lastModified time.Time) { +func getBlobForEntry(ctx *context.Context) (blob *git.Blob, lastModified *time.Time) { entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath) if err != nil { if git.IsErrNotExist(err) { @@ -90,23 +90,23 @@ func getBlobForEntry(ctx *context.Context) (blob *git.Blob, lastModified time.Ti } else { ctx.ServerError("GetTreeEntryByPath", err) } - return + return nil, nil } if entry.IsDir() || entry.IsSubModule() { ctx.NotFound("getBlobForEntry", nil) - return + return nil, nil } info, _, err := git.Entries([]*git.TreeEntry{entry}).GetCommitsInfo(ctx, ctx.Repo.Commit, path.Dir("/" + ctx.Repo.TreePath)[1:]) if err != nil { ctx.ServerError("GetCommitsInfo", err) - return + return nil, nil } if len(info) == 1 { // Not Modified - lastModified = info[0].Commit.Committer.When + lastModified = &info[0].Commit.Committer.When } blob = entry.Blob() @@ -148,7 +148,7 @@ func DownloadByID(ctx *context.Context) { } return } - if err = common.ServeBlob(ctx.Base, ctx.Repo.TreePath, blob, time.Time{}); err != nil { + if err = common.ServeBlob(ctx.Base, ctx.Repo.TreePath, blob, nil); err != nil { ctx.ServerError("ServeBlob", err) } } @@ -164,7 +164,7 @@ func DownloadByIDOrLFS(ctx *context.Context) { } return } - if err = ServeBlobOrLFS(ctx, blob, time.Time{}); err != nil { + if err = ServeBlobOrLFS(ctx, blob, nil); err != nil { ctx.ServerError("ServeBlob", err) } } diff --git a/routers/web/repo/http.go b/routers/web/repo/http.go index f4e9ac86a1bc3..0cae9aeda4549 100644 --- a/routers/web/repo/http.go +++ b/routers/web/repo/http.go @@ -56,13 +56,13 @@ func CorsHandler() func(next http.Handler) http.Handler { } // httpBase implementation git smart HTTP protocol -func httpBase(ctx *context.Context) (h *serviceHandler) { +func httpBase(ctx *context.Context) *serviceHandler { username := ctx.Params(":username") reponame := strings.TrimSuffix(ctx.Params(":reponame"), ".git") if ctx.FormString("go-get") == "1" { context.EarlyResponseForGoGetMeta(ctx) - return + return nil } var isPull, receivePack bool @@ -101,7 +101,7 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { owner := ctx.ContextUser if !owner.IsOrganization() && !owner.IsActive { ctx.PlainText(http.StatusForbidden, "Repository cannot be accessed. You cannot push or open issues/pull-requests.") - return + return nil } repoExist := true @@ -110,19 +110,19 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { if repo_model.IsErrRepoNotExist(err) { if redirectRepoID, err := repo_model.LookupRedirect(owner.ID, reponame); err == nil { context.RedirectToRepo(ctx.Base, redirectRepoID) - return + return nil } repoExist = false } else { ctx.ServerError("GetRepositoryByName", err) - return + return nil } } // Don't allow pushing if the repo is archived if repoExist && repo.IsArchived && !isPull { ctx.PlainText(http.StatusForbidden, "This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.") - return + return nil } // Only public pull don't need auth. @@ -136,7 +136,7 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { if isPublicPull { if err := repo.LoadOwner(ctx); err != nil { ctx.ServerError("LoadOwner", err) - return + return nil } askAuth = askAuth || (repo.Owner.Visibility != structs.VisibleTypePublic) @@ -149,12 +149,12 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { // TODO: support digit auth - which would be Authorization header with digit ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=\".\"") ctx.Error(http.StatusUnauthorized) - return + return nil } context.CheckRepoScopedToken(ctx, repo, auth_model.GetScopeLevelFromAccessMode(accessMode)) if ctx.Written() { - return + return nil } if ctx.IsBasicAuth && ctx.Data["IsApiToken"] != true && ctx.Data["IsActionsToken"] != true { @@ -162,16 +162,16 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { if err == nil { // TODO: This response should be changed to "invalid credentials" for security reasons once the expectation behind it (creating an app token to authenticate) is properly documented ctx.PlainText(http.StatusUnauthorized, "Users with two-factor authentication enabled cannot perform HTTP/HTTPS operations via plain username and password. Please create and use a personal access token on the user settings page") - return + return nil } else if !auth_model.IsErrTwoFactorNotEnrolled(err) { ctx.ServerError("IsErrTwoFactorNotEnrolled", err) - return + return nil } } if !ctx.Doer.IsActive || ctx.Doer.ProhibitLogin { ctx.PlainText(http.StatusForbidden, "Your account is disabled.") - return + return nil } environ = []string{ @@ -193,23 +193,23 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { task, err := actions_model.GetTaskByID(ctx, taskID) if err != nil { ctx.ServerError("GetTaskByID", err) - return + return nil } if task.RepoID != repo.ID { ctx.PlainText(http.StatusForbidden, "User permission denied") - return + return nil } if task.IsForkPullRequest { if accessMode > perm.AccessModeRead { ctx.PlainText(http.StatusForbidden, "User permission denied") - return + return nil } environ = append(environ, fmt.Sprintf("%s=%d", repo_module.EnvActionPerm, perm.AccessModeRead)) } else { if accessMode > perm.AccessModeWrite { ctx.PlainText(http.StatusForbidden, "User permission denied") - return + return nil } environ = append(environ, fmt.Sprintf("%s=%d", repo_module.EnvActionPerm, perm.AccessModeWrite)) } @@ -217,18 +217,18 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { p, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) if err != nil { ctx.ServerError("GetUserRepoPermission", err) - return + return nil } if !p.CanAccess(accessMode, unitType) { ctx.PlainText(http.StatusNotFound, "Repository not found") - return + return nil } } if !isPull && repo.IsMirror { ctx.PlainText(http.StatusForbidden, "mirror repository is read-only") - return + return nil } } @@ -246,34 +246,34 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { if !repoExist { if !receivePack { ctx.PlainText(http.StatusNotFound, "Repository not found") - return + return nil } if isWiki { // you cannot send wiki operation before create the repository ctx.PlainText(http.StatusNotFound, "Repository not found") - return + return nil } if owner.IsOrganization() && !setting.Repository.EnablePushCreateOrg { ctx.PlainText(http.StatusForbidden, "Push to create is not enabled for organizations.") - return + return nil } if !owner.IsOrganization() && !setting.Repository.EnablePushCreateUser { ctx.PlainText(http.StatusForbidden, "Push to create is not enabled for users.") - return + return nil } // Return dummy payload if GET receive-pack if ctx.Req.Method == http.MethodGet { dummyInfoRefs(ctx) - return + return nil } repo, err = repo_service.PushCreateRepo(ctx, ctx.Doer, owner, reponame) if err != nil { log.Error("pushCreateRepo: %v", err) ctx.Status(http.StatusNotFound) - return + return nil } } @@ -282,11 +282,11 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { if _, err := repo.GetUnit(ctx, unit.TypeWiki); err != nil { if repo_model.IsErrUnitTypeNotExist(err) { ctx.PlainText(http.StatusForbidden, "repository wiki is disabled") - return + return nil } log.Error("Failed to get the wiki unit in %-v Error: %v", repo, err) ctx.ServerError("GetUnit(UnitTypeWiki) for "+repo.FullName(), err) - return + return nil } } diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 6acfc87d5eedf..317f762fb1a21 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -189,7 +189,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti var issueIDs []int64 if len(keyword) > 0 { - issueIDs, err = issue_indexer.SearchIssuesByKeyword(ctx, []int64{repo.ID}, keyword) + issueIDs, err = issue_indexer.SearchIssuesByKeyword(ctx, []int64{repo.ID}, keyword, ctx.FormString("state")) if err != nil { if issue_indexer.IsAvailable(ctx) { ctx.ServerError("issueIndexer.Search", err) @@ -1922,9 +1922,12 @@ func ViewIssue(ctx *context.Context) { ctx.HTML(http.StatusOK, tplIssueView) } +// checkBlockedByIssues return canRead and notPermitted func checkBlockedByIssues(ctx *context.Context, blockers []*issues_model.DependencyInfo) (canRead, notPermitted []*issues_model.DependencyInfo) { - var lastRepoID int64 - var lastPerm access_model.Permission + var ( + lastRepoID int64 + lastPerm access_model.Permission + ) for i, blocker := range blockers { // Get the permissions for this repository perm := lastPerm @@ -1936,7 +1939,7 @@ func checkBlockedByIssues(ctx *context.Context, blockers []*issues_model.Depende perm, err = access_model.GetUserRepoPermission(ctx, &blocker.Repository, ctx.Doer) if err != nil { ctx.ServerError("GetUserRepoPermission", err) - return + return nil, nil } } lastRepoID = blocker.Repository.ID @@ -2463,7 +2466,7 @@ func SearchIssues(ctx *context.Context) { } var issueIDs []int64 if len(keyword) > 0 && len(repoIDs) > 0 { - if issueIDs, err = issue_indexer.SearchIssuesByKeyword(ctx, repoIDs, keyword); err != nil { + if issueIDs, err = issue_indexer.SearchIssuesByKeyword(ctx, repoIDs, keyword, ctx.FormString("state")); err != nil { ctx.Error(http.StatusInternalServerError, "SearchIssuesByKeyword", err.Error()) return } @@ -2611,7 +2614,7 @@ func ListIssues(ctx *context.Context) { var issueIDs []int64 var labelIDs []int64 if len(keyword) > 0 { - issueIDs, err = issue_indexer.SearchIssuesByKeyword(ctx, []int64{ctx.Repo.Repository.ID}, keyword) + issueIDs, err = issue_indexer.SearchIssuesByKeyword(ctx, []int64{ctx.Repo.Repository.ID}, keyword, ctx.FormString("state")) if err != nil { ctx.Error(http.StatusInternalServerError, err.Error()) return diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index e0a618bf596c7..1b68ef352a4ef 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -723,6 +723,9 @@ func ViewPullCommits(ctx *context.Context) { ctx.Data["Commits"] = commits ctx.Data["CommitCount"] = len(commits) + ctx.Data["HasIssuesOrPullsWritePermission"] = ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) + ctx.Data["IsIssuePoster"] = ctx.IsSigned && issue.IsPoster(ctx.Doer.ID) + getBranchData(ctx, issue) ctx.HTML(http.StatusOK, tplPullCommits) } diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index ad87bae9b8fa0..acea08d6297ec 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -977,6 +977,18 @@ func renderCode(ctx *context.Context) { return } + if ctx.Doer != nil { + if err := ctx.Repo.Repository.GetBaseRepo(ctx); err != nil { + ctx.ServerError("GetBaseRepo", err) + return + } + ctx.Data["RecentlyPushedNewBranches"], err = git_model.FindRecentlyPushedNewBranches(ctx, ctx.Repo.Repository.ID, ctx.Doer.ID) + if err != nil { + ctx.ServerError("GetRecentlyPushedBranches", err) + return + } + } + var treeNames []string paths := make([]string, 0, 5) if len(ctx.Repo.TreePath) > 0 { diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go index 7da6917912e4b..4773e25c70664 100644 --- a/routers/web/repo/wiki.go +++ b/routers/web/repo/wiki.go @@ -12,7 +12,6 @@ import ( "net/url" "path/filepath" "strings" - "time" git_model "code.gitea.io/gitea/models/git" repo_model "code.gitea.io/gitea/models/repo" @@ -671,7 +670,7 @@ func WikiRaw(ctx *context.Context) { } if entry != nil { - if err = common.ServeBlob(ctx.Base, ctx.Repo.TreePath, entry.Blob(), time.Time{}); err != nil { + if err = common.ServeBlob(ctx.Base, ctx.Repo.TreePath, entry.Blob(), nil); err != nil { ctx.ServerError("ServeBlob", err) } return diff --git a/routers/web/user/home.go b/routers/web/user/home.go index 6a89c507a9fd6..5f1e0eb4277b8 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -725,7 +725,7 @@ func issueIDsFromSearch(ctx *context.Context, ctxUser *user_model.User, keyword if err != nil { return nil, fmt.Errorf("GetRepoIDsForIssuesOptions: %w", err) } - issueIDsFromSearch, err := issue_indexer.SearchIssuesByKeyword(ctx, searchRepoIDs, keyword) + issueIDsFromSearch, err := issue_indexer.SearchIssuesByKeyword(ctx, searchRepoIDs, keyword, ctx.FormString("state")) if err != nil { return nil, fmt.Errorf("SearchIssuesByKeyword: %w", err) } diff --git a/routers/web/user/notification.go b/routers/web/user/notification.go index e0aa92879fcc4..cae12f4126775 100644 --- a/routers/web/user/notification.go +++ b/routers/web/user/notification.go @@ -186,7 +186,7 @@ func NotificationStatusPost(ctx *context.Context) { if ctx.Written() { return } - ctx.Data["Link"] = setting.AppURL + "notifications" + ctx.Data["Link"] = setting.AppSubURL + "/notifications" ctx.Data["SequenceNumber"] = ctx.Req.PostFormValue("sequence-number") ctx.HTML(http.StatusOK, tplNotificationDiv) diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go index 442fd0433a72c..07a2261c967d3 100644 --- a/routers/web/user/profile.go +++ b/routers/web/user/profile.go @@ -287,9 +287,9 @@ func Action(ctx *context.Context) { } if err != nil { - ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.FormString("action")), err) + log.Error("Failed to apply action %q: %v", ctx.FormString("action"), err) + ctx.JSONError(fmt.Sprintf("Action %q failed", ctx.FormString("action"))) return } - // FIXME: We should check this URL and make sure that it's a valid Gitea URL - ctx.RedirectToFirst(ctx.FormString("redirect_to"), ctx.ContextUser.HomeLink()) + ctx.JSONOK() } diff --git a/routers/web/web.go b/routers/web/web.go index 45c374e9c0a8e..4f5901c0ec661 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1256,20 +1256,20 @@ func registerRoutes(m *web.Route) { m.Group("/blob_excerpt", func() { m.Get("/{sha}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.ExcerptBlob) - }, func(ctx *context.Context) (cancel gocontext.CancelFunc) { + }, func(ctx *context.Context) gocontext.CancelFunc { if ctx.FormBool("wiki") { ctx.Data["PageIsWiki"] = true repo.MustEnableWiki(ctx) - return + return nil } reqRepoCodeReader(ctx) if ctx.Written() { - return + return nil } - cancel = context.RepoRef()(ctx) + cancel := context.RepoRef()(ctx) if ctx.Written() { - return + return cancel } repo.MustBeNotEmpty(ctx) diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index 8e6cdcf680d1b..c4c2a0df29b74 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -152,7 +152,6 @@ func notify(ctx context.Context, input *notifyInput) error { } else { for _, wf := range workflows { if wf.TriggerEvent != actions_module.GithubEventPullRequestTarget { - wf.Ref = ref detectedWorkflows = append(detectedWorkflows, wf) } } @@ -174,7 +173,6 @@ func notify(ctx context.Context, input *notifyInput) error { } else { for _, wf := range baseWorkflows { if wf.TriggerEvent == actions_module.GithubEventPullRequestTarget { - wf.Ref = baseRef detectedWorkflows = append(detectedWorkflows, wf) } } @@ -212,8 +210,8 @@ func notify(ctx context.Context, input *notifyInput) error { OwnerID: input.Repo.OwnerID, WorkflowID: dwf.EntryName, TriggerUserID: input.Doer.ID, - Ref: dwf.Ref, - CommitSHA: dwf.Commit.ID.String(), + Ref: ref, + CommitSHA: commit.ID.String(), IsForkPullRequest: isForkPullRequest, Event: input.Event, EventPayload: string(p), diff --git a/services/forms/user_form_hidden_comments.go b/services/forms/user_form_hidden_comments.go index 7eb800a020185..03e629a553ac0 100644 --- a/services/forms/user_form_hidden_comments.go +++ b/services/forms/user_form_hidden_comments.go @@ -90,7 +90,7 @@ func IsUserHiddenCommentTypeGroupChecked(group string, hiddenCommentTypes *big.I commentTypes, ok := hiddenCommentTypeGroups[group] if !ok { log.Critical("the group map for hidden comment types is out of sync, unknown group: %v", group) - return + return false } if hiddenCommentTypes == nil { return false diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index 38283680ae49e..9e1db6fd4353c 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -779,7 +779,7 @@ func skipToNextDiffHead(input *bufio.Reader) (line string, err error) { for { lineBytes, isFragment, err = input.ReadLine() if err != nil { - return + return "", err } if wasFragment { wasFragment = isFragment @@ -795,7 +795,7 @@ func skipToNextDiffHead(input *bufio.Reader) (line string, err error) { var tail string tail, err = input.ReadString('\n') if err != nil { - return + return "", err } line += tail } @@ -821,22 +821,21 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio _, isFragment, err = input.ReadLine() if err != nil { // Now by the definition of ReadLine this cannot be io.EOF - err = fmt.Errorf("unable to ReadLine: %w", err) - return + return nil, false, fmt.Errorf("unable to ReadLine: %w", err) } } sb.Reset() lineBytes, isFragment, err = input.ReadLine() if err != nil { if err == io.EOF { - return + return lineBytes, isFragment, err } err = fmt.Errorf("unable to ReadLine: %w", err) - return + return nil, false, err } if lineBytes[0] == 'd' { // End of hunks - return + return lineBytes, isFragment, err } switch lineBytes[0] { @@ -853,8 +852,7 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio lineBytes, isFragment, err = input.ReadLine() if err != nil { // Now by the definition of ReadLine this cannot be io.EOF - err = fmt.Errorf("unable to ReadLine: %w", err) - return + return nil, false, fmt.Errorf("unable to ReadLine: %w", err) } _, _ = sb.Write(lineBytes) } @@ -884,8 +882,7 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio } // This is used only to indicate that the current file does not have a terminal newline if !bytes.Equal(lineBytes, []byte("\\ No newline at end of file")) { - err = fmt.Errorf("unexpected line in hunk: %s", string(lineBytes)) - return + return nil, false, fmt.Errorf("unexpected line in hunk: %s", string(lineBytes)) } // Technically this should be the end the file! // FIXME: we should be putting a marker at the end of the file if there is no terminal new line @@ -953,8 +950,7 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio curSection.Lines = append(curSection.Lines, diffLine) default: // This is unexpected - err = fmt.Errorf("unexpected line in hunk: %s", string(lineBytes)) - return + return nil, false, fmt.Errorf("unexpected line in hunk: %s", string(lineBytes)) } line := string(lineBytes) @@ -965,8 +961,7 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio lineBytes, isFragment, err = input.ReadLine() if err != nil { // Now by the definition of ReadLine this cannot be io.EOF - err = fmt.Errorf("unable to ReadLine: %w", err) - return + return lineBytes, isFragment, fmt.Errorf("unable to ReadLine: %w", err) } } } diff --git a/services/issue/assignee.go b/services/issue/assignee.go index 943a761e28290..8fe35b560203e 100644 --- a/services/issue/assignee.go +++ b/services/issue/assignee.go @@ -46,13 +46,12 @@ func DeleteNotPassedAssignee(ctx context.Context, issue *issues_model.Issue, doe func ToggleAssignee(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, assigneeID int64) (removed bool, comment *issues_model.Comment, err error) { removed, comment, err = issues_model.ToggleIssueAssignee(ctx, issue, doer, assigneeID) if err != nil { - return + return false, nil, err } - assignee, err1 := user_model.GetUserByID(ctx, assigneeID) - if err1 != nil { - err = err1 - return + assignee, err := user_model.GetUserByID(ctx, assigneeID) + if err != nil { + return false, nil, err } notification.NotifyIssueChangeAssignee(ctx, doer, issue, assignee, removed, comment) @@ -236,23 +235,23 @@ func TeamReviewRequest(ctx context.Context, issue *issues_model.Issue, doer *use } if err != nil { - return + return nil, err } if comment == nil || !isAdd { - return + return nil, nil } // notify all user in this team - if err = comment.LoadIssue(ctx); err != nil { - return + if err := comment.LoadIssue(ctx); err != nil { + return nil, err } members, err := organization.GetTeamMembers(ctx, &organization.SearchMembersOptions{ TeamID: reviewer.ID, }) if err != nil { - return + return nil, err } for _, member := range members { diff --git a/services/issue/issue.go b/services/issue/issue.go index 61890c75def09..b6c6a26cbdc93 100644 --- a/services/issue/issue.go +++ b/services/issue/issue.go @@ -49,17 +49,17 @@ func NewIssue(ctx context.Context, repo *repo_model.Repository, issue *issues_mo } // ChangeTitle changes the title of this issue, as the given user. -func ChangeTitle(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, title string) (err error) { +func ChangeTitle(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, title string) error { oldTitle := issue.Title issue.Title = title - if err = issues_model.ChangeIssueTitle(ctx, issue, doer, oldTitle); err != nil { - return + if err := issues_model.ChangeIssueTitle(ctx, issue, doer, oldTitle); err != nil { + return err } if issue.IsPull && issues_model.HasWorkInProgressPrefix(oldTitle) && !issues_model.HasWorkInProgressPrefix(title) { - if err = issues_model.PullRequestCodeOwnersReview(ctx, issue, issue.PullRequest); err != nil { - return + if err := issues_model.PullRequestCodeOwnersReview(ctx, issue, issue.PullRequest); err != nil { + return err } } diff --git a/services/issue/label.go b/services/issue/label.go index c18abbfcda3d2..ee821a49c94d3 100644 --- a/services/issue/label.go +++ b/services/issue/label.go @@ -12,9 +12,9 @@ import ( ) // ClearLabels clears all of an issue's labels -func ClearLabels(issue *issues_model.Issue, doer *user_model.User) (err error) { - if err = issues_model.ClearIssueLabels(issue, doer); err != nil { - return +func ClearLabels(issue *issues_model.Issue, doer *user_model.User) error { + if err := issues_model.ClearIssueLabels(issue, doer); err != nil { + return err } notification.NotifyIssueClearLabels(db.DefaultContext, doer, issue) diff --git a/services/pull/merge.go b/services/pull/merge.go index 85bb90b853899..416c74446351d 100644 --- a/services/pull/merge.go +++ b/services/pull/merge.go @@ -110,6 +110,11 @@ func getMergeMessage(ctx context.Context, baseGitRepo *git.Repository, pr *issue } } + if mergeStyle == repo_model.MergeStyleRebase { + // for fast-forward rebase, do not amend the last commit if there is no template + return "", "", nil + } + // Squash merge has a different from other styles. if mergeStyle == repo_model.MergeStyleSquash { return fmt.Sprintf("%s (%s%d)", pr.Issue.Title, issueReference, pr.Issue.Index), "", nil diff --git a/services/pull/review.go b/services/pull/review.go index 6feffe4ec4e7a..e920bc8c1652b 100644 --- a/services/pull/review.go +++ b/services/pull/review.go @@ -320,7 +320,7 @@ func SubmitReview(ctx context.Context, doer *user_model.User, gitRepo *git.Repos func DismissReview(ctx context.Context, reviewID, repoID int64, message string, doer *user_model.User, isDismiss, dismissPriors bool) (comment *issues_model.Comment, err error) { review, err := issues_model.GetReviewByID(ctx, reviewID) if err != nil { - return + return nil, err } if review.Type != issues_model.ReviewTypeApprove && review.Type != issues_model.ReviewTypeReject { @@ -328,7 +328,7 @@ func DismissReview(ctx context.Context, reviewID, repoID int64, message string, } // load data for notify - if err = review.LoadAttributes(ctx); err != nil { + if err := review.LoadAttributes(ctx); err != nil { return nil, err } @@ -337,8 +337,8 @@ func DismissReview(ctx context.Context, reviewID, repoID int64, message string, return nil, fmt.Errorf("reviews's repository is not the same as the one we expect") } - if err = issues_model.DismissReview(review, isDismiss); err != nil { - return + if err := issues_model.DismissReview(review, isDismiss); err != nil { + return nil, err } if dismissPriors { @@ -361,11 +361,11 @@ func DismissReview(ctx context.Context, reviewID, repoID int64, message string, return nil, nil } - if err = review.Issue.LoadPullRequest(ctx); err != nil { - return + if err := review.Issue.LoadPullRequest(ctx); err != nil { + return nil, err } - if err = review.Issue.LoadAttributes(ctx); err != nil { - return + if err := review.Issue.LoadAttributes(ctx); err != nil { + return nil, err } comment, err = issue_service.CreateComment(ctx, &issues_model.CreateCommentOptions{ @@ -377,7 +377,7 @@ func DismissReview(ctx context.Context, reviewID, repoID int64, message string, Repo: review.Issue.Repo, }) if err != nil { - return + return nil, err } comment.Review = review @@ -386,5 +386,5 @@ func DismissReview(ctx context.Context, reviewID, repoID int64, message string, notification.NotifyPullReviewDismiss(ctx, doer, review, comment) - return comment, err + return comment, nil } diff --git a/services/release/release.go b/services/release/release.go index c1190305b6688..1ccbd9c81163e 100644 --- a/services/release/release.go +++ b/services/release/release.go @@ -187,7 +187,7 @@ func CreateNewTag(ctx context.Context, doer *user_model.User, repo *repo_model.R // editAttachments accept a map of attachment uuid to new attachment name which will be updated with attachments. func UpdateRelease(doer *user_model.User, gitRepo *git.Repository, rel *repo_model.Release, addAttachmentUUIDs, delAttachmentUUIDs []string, editAttachments map[string]string, -) (err error) { +) error { if rel.ID == 0 { return errors.New("UpdateRelease only accepts an exist release") } @@ -264,8 +264,8 @@ func UpdateRelease(doer *user_model.User, gitRepo *git.Repository, rel *repo_mod } } - if err = committer.Commit(); err != nil { - return + if err := committer.Commit(); err != nil { + return err } for _, uuid := range delAttachmentUUIDs { @@ -280,14 +280,14 @@ func UpdateRelease(doer *user_model.User, gitRepo *git.Repository, rel *repo_mod if !isCreated { notification.NotifyUpdateRelease(gitRepo.Ctx, doer, rel) - return + return nil } if !rel.IsDraft { notification.NotifyNewRelease(gitRepo.Ctx, rel) } - return err + return nil } // DeleteReleaseByID deletes a release and corresponding Git tag by given ID. diff --git a/services/task/migrate.go b/services/task/migrate.go index bebdb5078b26f..52b6220a048f4 100644 --- a/services/task/migrate.go +++ b/services/task/migrate.go @@ -71,7 +71,7 @@ func runMigrateTask(t *admin_model.Task) (err error) { }() if err = t.LoadRepo(); err != nil { - return + return err } // if repository is ready, then just finish the task @@ -80,16 +80,16 @@ func runMigrateTask(t *admin_model.Task) (err error) { } if err = t.LoadDoer(); err != nil { - return + return err } if err = t.LoadOwner(); err != nil { - return + return err } var opts *migration.MigrateOptions opts, err = t.MigrateConfig() if err != nil { - return + return err } opts.MigrateToRepoID = t.RepoID @@ -101,7 +101,7 @@ func runMigrateTask(t *admin_model.Task) (err error) { t.StartTime = timeutil.TimeStampNow() t.Status = structs.TaskStatusRunning if err = t.UpdateCols("start_time", "status"); err != nil { - return + return err } // check whether the task should be canceled, this goroutine is also managed by process manager @@ -133,12 +133,11 @@ func runMigrateTask(t *admin_model.Task) (err error) { if err == nil { log.Trace("Repository migrated [%d]: %s/%s", t.Repo.ID, t.Owner.Name, t.Repo.Name) - return + return nil } if repo_model.IsErrRepoAlreadyExist(err) { - err = errors.New("the repository name is already used") - return + return errors.New("the repository name is already used") } // remoteAddr may contain credentials, so we sanitize it diff --git a/templates/admin/auth/edit.tmpl b/templates/admin/auth/edit.tmpl index 801cf9e7b4548..6dfa86d9dd154 100644 --- a/templates/admin/auth/edit.tmpl +++ b/templates/admin/auth/edit.tmpl @@ -106,7 +106,6 @@ -
diff --git a/templates/base/head_navbar.tmpl b/templates/base/head_navbar.tmpl index 944bba5b3190f..2cdbb7bc9cf67 100644 --- a/templates/base/head_navbar.tmpl +++ b/templates/base/head_navbar.tmpl @@ -23,7 +23,6 @@
- {{if and .IsSigned .MustChangePassword}} {{/* No links */}} diff --git a/templates/install.tmpl b/templates/install.tmpl index ccbd67347000b..b5caab148981d 100644 --- a/templates/install.tmpl +++ b/templates/install.tmpl @@ -1,6 +1,6 @@ {{template "base/head" .}}
-
+

{{.locale.Tr "install.title"}} @@ -149,19 +149,18 @@

- +
{{.locale.Tr "install.enable_update_checker_helper"}}
-

{{.locale.Tr "install.optional_title"}}

- + {{.locale.Tr "install.email_title"}}
@@ -201,7 +200,7 @@
- + {{.locale.Tr "install.server_service_title"}}
@@ -299,7 +298,7 @@
- + {{.locale.Tr "install.admin_title"}}

{{.locale.Tr "install.admin_setting_desc"}}

@@ -321,10 +320,27 @@
+ {{if .EnvConfigKeys}} + +

{{.locale.Tr "install.env_config_keys"}}

+
+
+ {{.locale.Tr "install.env_config_keys_prompt"}} +
+
+ {{range .EnvConfigKeys}}{{.}}{{end}} +
+
+ {{end}} +
- - +
+ These configuration options will be written into: {{.CustomConfFile}} +
+
+ +
diff --git a/templates/org/home.tmpl b/templates/org/home.tmpl index 7f52b8cc6dcab..967b31e7a8f5e 100644 --- a/templates/org/home.tmpl +++ b/templates/org/home.tmpl @@ -20,16 +20,13 @@
diff --git a/templates/org/projects/view.tmpl b/templates/org/projects/view.tmpl index ef8ec2422524f..33346b61544b8 100644 --- a/templates/org/projects/view.tmpl +++ b/templates/org/projects/view.tmpl @@ -1,5 +1,5 @@ {{template "base/head" .}} -
+
{{template "shared/user/org_profile_avatar" .}}
{{template "user/overview/header" .}} diff --git a/templates/package/content/alpine.tmpl b/templates/package/content/alpine.tmpl index 97e2289ad8f74..2622118331a24 100644 --- a/templates/package/content/alpine.tmpl +++ b/templates/package/content/alpine.tmpl @@ -18,7 +18,7 @@
- +
diff --git a/templates/package/content/cargo.tmpl b/templates/package/content/cargo.tmpl index bfa585ec297fa..b3dfbae257206 100644 --- a/templates/package/content/cargo.tmpl +++ b/templates/package/content/cargo.tmpl @@ -18,7 +18,7 @@ git-fetch-with-cli = true
cargo add {{.PackageDescriptor.Package.Name}}@{{.PackageDescriptor.Version.Version}}
- +
diff --git a/templates/package/content/chef.tmpl b/templates/package/content/chef.tmpl index 77f1f37998199..331b1fb49f66f 100644 --- a/templates/package/content/chef.tmpl +++ b/templates/package/content/chef.tmpl @@ -11,7 +11,7 @@
knife supermarket install {{.PackageDescriptor.Package.Name}} {{.PackageDescriptor.Version.Version}}
- +
diff --git a/templates/package/content/composer.tmpl b/templates/package/content/composer.tmpl index d0f88dadc6929..c2a8bc9625998 100644 --- a/templates/package/content/composer.tmpl +++ b/templates/package/content/composer.tmpl @@ -17,7 +17,7 @@
composer require {{.PackageDescriptor.Package.Name}}:{{.PackageDescriptor.Version.Version}}
- +
diff --git a/templates/package/content/conan.tmpl b/templates/package/content/conan.tmpl index 07ad6b644d6a9..86f1c8ede3ad6 100644 --- a/templates/package/content/conan.tmpl +++ b/templates/package/content/conan.tmpl @@ -11,7 +11,7 @@
conan install --remote=gitea {{.PackageDescriptor.Package.Name}}/{{.PackageDescriptor.Version.Version}}
- +
diff --git a/templates/package/content/conda.tmpl b/templates/package/content/conda.tmpl index 71c2c98d3f3b8..627e637e1ae9a 100644 --- a/templates/package/content/conda.tmpl +++ b/templates/package/content/conda.tmpl @@ -16,7 +16,7 @@ default_channels:
conda install{{if $channel}} -c {{$channel}}{{end}} {{.PackageDescriptor.PackageProperties.GetByName "conda.name"}}={{.PackageDescriptor.Version.Version}}
- +
diff --git a/templates/package/content/container.tmpl b/templates/package/content/container.tmpl index d928b36e604cd..5aba2b6061116 100644 --- a/templates/package/content/container.tmpl +++ b/templates/package/content/container.tmpl @@ -19,7 +19,7 @@
{{range .PackageDescriptor.Files}}{{if eq .File.LowerName "manifest.json"}}{{.Properties.GetByName "container.digest"}}{{end}}{{end}}
- +
diff --git a/templates/package/content/cran.tmpl b/templates/package/content/cran.tmpl index dcabdbce93b27..38a58bc4e7882 100644 --- a/templates/package/content/cran.tmpl +++ b/templates/package/content/cran.tmpl @@ -11,7 +11,7 @@
install.packages("{{.PackageDescriptor.Package.Name}}")
- +
diff --git a/templates/package/content/debian.tmpl b/templates/package/content/debian.tmpl index 8b60b33bcc81b..ea146d170f9a1 100644 --- a/templates/package/content/debian.tmpl +++ b/templates/package/content/debian.tmpl @@ -16,7 +16,7 @@ sudo apt update
- +
diff --git a/templates/package/content/generic.tmpl b/templates/package/content/generic.tmpl index 556e31971c570..d3e4c7a62aedd 100644 --- a/templates/package/content/generic.tmpl +++ b/templates/package/content/generic.tmpl @@ -11,7 +11,7 @@ curl - + diff --git a/templates/package/content/go.tmpl b/templates/package/content/go.tmpl index 2343d945b3a78..616698c41474b 100644 --- a/templates/package/content/go.tmpl +++ b/templates/package/content/go.tmpl @@ -7,7 +7,7 @@
GOPROXY= go install {{$.PackageDescriptor.Package.Name}}@{{$.PackageDescriptor.Version.Version}}
- +
diff --git a/templates/package/content/helm.tmpl b/templates/package/content/helm.tmpl index 9b4f57538a240..11c05a12b6e2c 100644 --- a/templates/package/content/helm.tmpl +++ b/templates/package/content/helm.tmpl @@ -12,7 +12,7 @@ helm repo update
helm install {{.PackageDescriptor.Package.Name}} {{AppDomain}}/{{.PackageDescriptor.Package.Name}}
- +
diff --git a/templates/package/content/maven.tmpl b/templates/package/content/maven.tmpl index f18f12091bc7f..d4c991c466427 100644 --- a/templates/package/content/maven.tmpl +++ b/templates/package/content/maven.tmpl @@ -40,7 +40,7 @@
mvn dependency:get -DremoteRepositories= -Dartifact={{.PackageDescriptor.Metadata.GroupID}}:{{.PackageDescriptor.Metadata.ArtifactID}}:{{.PackageDescriptor.Version.Version}}
- +
diff --git a/templates/package/content/npm.tmpl b/templates/package/content/npm.tmpl index a8d3f4031692c..e376a45f8b87f 100644 --- a/templates/package/content/npm.tmpl +++ b/templates/package/content/npm.tmpl @@ -15,7 +15,7 @@
"{{.PackageDescriptor.Package.Name}}": "{{.PackageDescriptor.Version.Version}}"
- +
diff --git a/templates/package/content/nuget.tmpl b/templates/package/content/nuget.tmpl index f3013adc76eae..e95d9176b8575 100644 --- a/templates/package/content/nuget.tmpl +++ b/templates/package/content/nuget.tmpl @@ -11,7 +11,7 @@
dotnet add package --source {{.PackageDescriptor.Owner.Name}} --version {{.PackageDescriptor.Version.Version}} {{.PackageDescriptor.Package.Name}}
- +
diff --git a/templates/package/content/pub.tmpl b/templates/package/content/pub.tmpl index 28aa29abe9afd..840bedbd9dbb9 100644 --- a/templates/package/content/pub.tmpl +++ b/templates/package/content/pub.tmpl @@ -7,7 +7,7 @@
dart pub add {{.PackageDescriptor.Package.Name}}:{{.PackageDescriptor.Version.Version}} --hosted-url=
- +
diff --git a/templates/package/content/pypi.tmpl b/templates/package/content/pypi.tmpl index 07c387ecac757..460a06fcd115d 100644 --- a/templates/package/content/pypi.tmpl +++ b/templates/package/content/pypi.tmpl @@ -7,7 +7,7 @@
pip install --index-url  {{.PackageDescriptor.Package.Name}}
- +
diff --git a/templates/package/content/rpm.tmpl b/templates/package/content/rpm.tmpl index 63bb8b07920c6..42965c3271a25 100644 --- a/templates/package/content/rpm.tmpl +++ b/templates/package/content/rpm.tmpl @@ -13,7 +13,7 @@
- +
diff --git a/templates/package/content/rubygems.tmpl b/templates/package/content/rubygems.tmpl index 6e6ee7105fcfd..2f618392e4e87 100644 --- a/templates/package/content/rubygems.tmpl +++ b/templates/package/content/rubygems.tmpl @@ -13,7 +13,7 @@ end
- +
diff --git a/templates/package/content/swift.tmpl b/templates/package/content/swift.tmpl index ea87599fcc7b6..c227e30c34358 100644 --- a/templates/package/content/swift.tmpl +++ b/templates/package/content/swift.tmpl @@ -17,7 +17,7 @@
swift package resolve
- +
diff --git a/templates/package/content/vagrant.tmpl b/templates/package/content/vagrant.tmpl index b6ec2eaf32658..e23acf58a6d35 100644 --- a/templates/package/content/vagrant.tmpl +++ b/templates/package/content/vagrant.tmpl @@ -7,7 +7,7 @@
vagrant box add --box-version {{.PackageDescriptor.Version.Version}} ""
- +
diff --git a/templates/package/shared/cargo.tmpl b/templates/package/shared/cargo.tmpl index 687fc8492d824..4e26df2909766 100644 --- a/templates/package/shared/cargo.tmpl +++ b/templates/package/shared/cargo.tmpl @@ -18,7 +18,7 @@
- +
diff --git a/templates/package/shared/list.tmpl b/templates/package/shared/list.tmpl index 1acafff41aeef..79a2d885fb37b 100644 --- a/templates/package/shared/list.tmpl +++ b/templates/package/shared/list.tmpl @@ -1,53 +1,53 @@ - {{template "base/alert" .}} -
-
- {{template "shared/searchinput" dict "locale" .locale "Value" .Query "AutoFocus" true}} - - -
-
-
- {{range .PackageDescriptors}} -
  • -
    -
    - {{.Package.Name}} - {{svg .Package.Type.SVGName 16}} {{.Package.Type.Name}} -
    -
    - {{$timeStr := TimeSinceUnix .Version.CreatedUnix $.locale}} - {{$hasRepositoryAccess := false}} - {{if .Repository}} - {{$hasRepositoryAccess = index $.RepositoryAccessMap .Repository.ID}} - {{end}} - {{if $hasRepositoryAccess}} - {{$.locale.Tr "packages.published_by_in" $timeStr .Creator.HomeLink (.Creator.GetDisplayName | Escape) .Repository.Link (.Repository.FullName | Escape) | Safe}} - {{else}} - {{$.locale.Tr "packages.published_by" $timeStr .Creator.HomeLink (.Creator.GetDisplayName | Escape) | Safe}} - {{end}} -
    +{{template "base/alert" .}} +
    +
    + {{template "shared/searchinput" dict "locale" .locale "Value" .Query "AutoFocus" true}} + + +
    +
    +
    + {{range .PackageDescriptors}} +
  • +
    +
    + {{.Package.Name}} + {{svg .Package.Type.SVGName 16}} {{.Package.Type.Name}}
    -
  • - {{else}} - {{if not .HasPackages}} -
    - {{svg "octicon-package" 48}} -

    {{.locale.Tr "packages.empty"}}

    - {{if and .Repository .CanWritePackages}} - {{$packagesUrl := URLJoin .Owner.HomeLink "-" "packages"}} -

    {{.locale.Tr "packages.empty.repo" $packagesUrl | Safe}}

    +
    + {{$timeStr := TimeSinceUnix .Version.CreatedUnix $.locale}} + {{$hasRepositoryAccess := false}} + {{if .Repository}} + {{$hasRepositoryAccess = index $.RepositoryAccessMap .Repository.ID}} + {{end}} + {{if $hasRepositoryAccess}} + {{$.locale.Tr "packages.published_by_in" $timeStr .Creator.HomeLink (.Creator.GetDisplayName | Escape) .Repository.Link (.Repository.FullName | Escape) | Safe}} + {{else}} + {{$.locale.Tr "packages.published_by" $timeStr .Creator.HomeLink (.Creator.GetDisplayName | Escape) | Safe}} {{end}} -

    {{.locale.Tr "packages.empty.documentation" "https://docs.gitea.io/en-us/usage/packages/overview/" | Safe}}

    - {{else}} -

    {{.locale.Tr "packages.filter.no_result"}}

    - {{end}} +
    + + {{else}} + {{if not .HasPackages}} +
    + {{svg "octicon-package" 48}} +

    {{.locale.Tr "packages.empty"}}

    + {{if and .Repository .CanWritePackages}} + {{$packagesUrl := URLJoin .Owner.HomeLink "-" "packages"}} +

    {{.locale.Tr "packages.empty.repo" $packagesUrl | Safe}}

    + {{end}} +

    {{.locale.Tr "packages.empty.documentation" "https://docs.gitea.io/en-us/usage/packages/overview/" | Safe}}

    +
    + {{else}} +

    {{.locale.Tr "packages.filter.no_result"}}

    {{end}} - {{template "base/paginate" .}} -
    + {{end}} + {{template "base/paginate" .}} + diff --git a/templates/package/shared/versionlist.tmpl b/templates/package/shared/versionlist.tmpl index be5c2a16de017..feba8ef14579a 100644 --- a/templates/package/shared/versionlist.tmpl +++ b/templates/package/shared/versionlist.tmpl @@ -1,37 +1,37 @@ -

    {{.PackageDescriptor.Package.Name}} / {{.locale.Tr "packages.versions"}}

    -
    -
    - {{template "shared/searchinput" dict "locale" .locale "Value" .Query "AutoFocus" true}} - - {{if eq .PackageDescriptor.Package.Type "container"}} - - {{end}} - -
    -
    -
    - {{range .PackageDescriptors}} -
  • -
    - -
    - {{$.locale.Tr "packages.published_by" (TimeSinceUnix .Version.CreatedUnix $.locale) .Creator.HomeLink (.Creator.GetDisplayName | Escape) | Safe}} -
    -
    -
  • - {{else}} -

    {{.locale.Tr "packages.filter.no_result"}}

    +

    {{.PackageDescriptor.Package.Name}} / {{.locale.Tr "packages.versions"}}

    +
    +
    + {{template "shared/searchinput" dict "locale" .locale "Value" .Query "AutoFocus" true}} + + {{if eq .PackageDescriptor.Package.Type "container"}} + {{end}} - {{template "base/paginate" .}} +
    +
    +
    + {{range .PackageDescriptors}} +
  • +
    + +
    + {{$.locale.Tr "packages.published_by" (TimeSinceUnix .Version.CreatedUnix $.locale) .Creator.HomeLink (.Creator.GetDisplayName | Escape) | Safe}} +
    +
    +
  • + {{else}} +

    {{.locale.Tr "packages.filter.no_result"}}

    + {{end}} + {{template "base/paginate" .}} +
    diff --git a/templates/projects/list.tmpl b/templates/projects/list.tmpl index ebce0ea48f048..fc8bf60811003 100644 --- a/templates/projects/list.tmpl +++ b/templates/projects/list.tmpl @@ -1,76 +1,76 @@ - {{if .CanWriteProjects}} - -
    - {{end}} +{{if .CanWriteProjects}} + +
    +{{end}} - {{template "base/alert" .}} - +{{template "base/alert" .}} + - {{if $.CanWriteProjects}}