mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-06 08:29:54 +02:00
Merge branch 'main' into lunny/some_refactors
This commit is contained in:
commit
733c5b608a
@ -80,7 +80,7 @@ The more detailed and specific you are, the faster we can fix the issue. \
|
||||
It is really helpful if you can reproduce your problem on a site running on the latest commits, i.e. <https://demo.gitea.com>, as perhaps your problem has already been fixed on a current version. \
|
||||
Please follow the guidelines described in [How to Report Bugs Effectively](http://www.chiark.greenend.org.uk/~sgtatham/bugs.html) for your report.
|
||||
|
||||
Please be kind, remember that Gitea comes at no cost to you, and you're getting free help.
|
||||
Please be kind—remember that Gitea comes at no cost to you, and you're getting free help.
|
||||
|
||||
### Types of issues
|
||||
|
||||
|
||||
@ -233,7 +233,7 @@ export default defineConfig([
|
||||
'@typescript-eslint/no-unused-vars': [2, {vars: 'all', args: 'all', caughtErrors: 'all', ignoreRestSiblings: false, argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrorsIgnorePattern: '^_', destructuredArrayIgnorePattern: '^_'}],
|
||||
'@typescript-eslint/no-use-before-define': [2, {functions: false, classes: true, variables: true, allowNamedExports: true, typedefs: false, enums: false, ignoreTypeReferences: true}],
|
||||
'@typescript-eslint/no-useless-constructor': [0],
|
||||
'@typescript-eslint/no-useless-default-assignment': [0], // https://github.com/typescript-eslint/typescript-eslint/issues/11847
|
||||
'@typescript-eslint/no-useless-default-assignment': [2],
|
||||
'@typescript-eslint/no-useless-empty-export': [0],
|
||||
'@typescript-eslint/no-wrapper-object-types': [2],
|
||||
'@typescript-eslint/non-nullable-type-assertion-style': [0],
|
||||
@ -264,6 +264,7 @@ export default defineConfig([
|
||||
'@typescript-eslint/restrict-template-expressions': [0],
|
||||
'@typescript-eslint/return-await': [0],
|
||||
'@typescript-eslint/strict-boolean-expressions': [0],
|
||||
'@typescript-eslint/strict-void-return': [0],
|
||||
'@typescript-eslint/switch-exhaustiveness-check': [0],
|
||||
'@typescript-eslint/triple-slash-reference': [2],
|
||||
'@typescript-eslint/typedef': [0],
|
||||
|
||||
@ -12,6 +12,8 @@ import (
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
// Stopwatch represents a stopwatch for time tracking.
|
||||
@ -232,3 +234,14 @@ func CancelStopwatch(ctx context.Context, user *user_model.User, issue *Issue) (
|
||||
})
|
||||
return ok, err
|
||||
}
|
||||
|
||||
// RemoveStopwatchesByRepoID removes all stopwatches for a user in a specific repository
|
||||
// this function should be called before removing all the issues of the repository
|
||||
func RemoveStopwatchesByRepoID(ctx context.Context, userID, repoID int64) error {
|
||||
_, err := db.GetEngine(ctx).
|
||||
Where("`stopwatch`.user_id = ?", userID).
|
||||
And(builder.In("`stopwatch`.issue_id",
|
||||
builder.Select("id").From("issue").Where(builder.Eq{"repo_id": repoID}))).
|
||||
Delete(new(Stopwatch))
|
||||
return err
|
||||
}
|
||||
|
||||
@ -93,15 +93,21 @@ func init() {
|
||||
db.RegisterModel(new(Release))
|
||||
}
|
||||
|
||||
// LoadAttributes load repo and publisher attributes for a release
|
||||
func (r *Release) LoadAttributes(ctx context.Context) error {
|
||||
var err error
|
||||
if r.Repo == nil {
|
||||
r.Repo, err = GetRepositoryByID(ctx, r.RepoID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
func (r *Release) LoadRepo(ctx context.Context) (err error) {
|
||||
if r.Repo != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
r.Repo, err = GetRepositoryByID(ctx, r.RepoID)
|
||||
return err
|
||||
}
|
||||
|
||||
// LoadAttributes load repo and publisher attributes for a release
|
||||
func (r *Release) LoadAttributes(ctx context.Context) (err error) {
|
||||
if err := r.LoadRepo(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if r.Publisher == nil {
|
||||
r.Publisher, err = user_model.GetUserByID(ctx, r.PublisherID)
|
||||
if err != nil {
|
||||
|
||||
@ -176,3 +176,13 @@ func WatchIfAuto(ctx context.Context, userID, repoID int64, isWrite bool) error
|
||||
}
|
||||
return watchRepoMode(ctx, watch, WatchModeAuto)
|
||||
}
|
||||
|
||||
// ClearRepoWatches clears all watches for a repository and from the user that watched it.
|
||||
// Used when a repository is set to private.
|
||||
func ClearRepoWatches(ctx context.Context, repoID int64) error {
|
||||
if _, err := db.Exec(ctx, "UPDATE `repository` SET num_watches = 0 WHERE id = ?", repoID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return db.DeleteBeans(ctx, Watch{RepoID: repoID})
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestIsWatching(t *testing.T) {
|
||||
@ -119,3 +120,21 @@ func TestWatchIfAuto(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, watchers, prevCount)
|
||||
}
|
||||
|
||||
func TestClearRepoWatches(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
const repoID int64 = 1
|
||||
watchers, err := repo_model.GetRepoWatchersIDs(t.Context(), repoID)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, watchers)
|
||||
|
||||
assert.NoError(t, repo_model.ClearRepoWatches(t.Context(), repoID))
|
||||
|
||||
watchers, err = repo_model.GetRepoWatchersIDs(t.Context(), repoID)
|
||||
assert.NoError(t, err)
|
||||
assert.Empty(t, watchers)
|
||||
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
|
||||
assert.Zero(t, repo.NumWatches)
|
||||
}
|
||||
|
||||
@ -102,7 +102,13 @@ func DeleteUserOpenID(ctx context.Context, openid *UserOpenID) (err error) {
|
||||
}
|
||||
|
||||
// ToggleUserOpenIDVisibility toggles visibility of an openid address of given user.
|
||||
func ToggleUserOpenIDVisibility(ctx context.Context, id int64) (err error) {
|
||||
_, err = db.GetEngine(ctx).Exec("update `user_open_id` set `show` = not `show` where `id` = ?", id)
|
||||
return err
|
||||
func ToggleUserOpenIDVisibility(ctx context.Context, id int64, user *User) error {
|
||||
affected, err := db.GetEngine(ctx).Exec("update `user_open_id` set `show` = not `show` where `id` = ? AND uid = ?", id, user.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if n, _ := affected.RowsAffected(); n != 1 {
|
||||
return util.NewNotExistErrorf("OpenID is unknown")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -33,12 +34,14 @@ func TestGetUserOpenIDs(t *testing.T) {
|
||||
|
||||
func TestToggleUserOpenIDVisibility(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
user, err := user_model.GetUserByID(t.Context(), int64(2))
|
||||
require.NoError(t, err)
|
||||
oids, err := user_model.GetUserOpenIDs(t.Context(), int64(2))
|
||||
require.NoError(t, err)
|
||||
require.Len(t, oids, 1)
|
||||
assert.True(t, oids[0].Show)
|
||||
|
||||
err = user_model.ToggleUserOpenIDVisibility(t.Context(), oids[0].ID)
|
||||
err = user_model.ToggleUserOpenIDVisibility(t.Context(), oids[0].ID, user)
|
||||
require.NoError(t, err)
|
||||
|
||||
oids, err = user_model.GetUserOpenIDs(t.Context(), int64(2))
|
||||
@ -46,7 +49,7 @@ func TestToggleUserOpenIDVisibility(t *testing.T) {
|
||||
require.Len(t, oids, 1)
|
||||
|
||||
assert.False(t, oids[0].Show)
|
||||
err = user_model.ToggleUserOpenIDVisibility(t.Context(), oids[0].ID)
|
||||
err = user_model.ToggleUserOpenIDVisibility(t.Context(), oids[0].ID, user)
|
||||
require.NoError(t, err)
|
||||
|
||||
oids, err = user_model.GetUserOpenIDs(t.Context(), int64(2))
|
||||
@ -55,3 +58,13 @@ func TestToggleUserOpenIDVisibility(t *testing.T) {
|
||||
assert.True(t, oids[0].Show)
|
||||
}
|
||||
}
|
||||
|
||||
func TestToggleUserOpenIDVisibilityRequiresOwnership(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
unauthorizedUser, err := user_model.GetUserByID(t.Context(), int64(2))
|
||||
require.NoError(t, err)
|
||||
|
||||
err = user_model.ToggleUserOpenIDVisibility(t.Context(), int64(1), unauthorizedUser)
|
||||
require.Error(t, err)
|
||||
assert.ErrorIs(t, err, util.ErrNotExist)
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
|
||||
activities_model "code.gitea.io/gitea/models/activities"
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/graceful"
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
@ -91,7 +92,13 @@ loop:
|
||||
}
|
||||
|
||||
for _, userStopwatches := range usersStopwatches {
|
||||
apiSWs, err := convert.ToStopWatches(ctx, userStopwatches.StopWatches)
|
||||
u, err := user_model.GetUserByID(ctx, userStopwatches.UserID)
|
||||
if err != nil {
|
||||
log.Error("Unable to get user %d: %v", userStopwatches.UserID, err)
|
||||
continue
|
||||
}
|
||||
|
||||
apiSWs, err := convert.ToStopWatches(ctx, u, userStopwatches.StopWatches)
|
||||
if err != nil {
|
||||
if !issues_model.IsErrIssueNotExist(err) {
|
||||
log.Error("Unable to APIFormat stopwatches: %v", err)
|
||||
|
||||
@ -107,6 +107,17 @@ func detectFileTypeBox(data []byte) (brands []string, found bool) {
|
||||
return brands, true
|
||||
}
|
||||
|
||||
func isEmbeddedOpenType(data []byte) bool {
|
||||
// https://www.w3.org/submissions/EOT
|
||||
if len(data) < 80 {
|
||||
return false
|
||||
}
|
||||
version := binary.LittleEndian.Uint32(data[8:]) // Actually this standard is abandoned (for IE6-IE11 only), there are only 3 versions defined
|
||||
magic := binary.LittleEndian.Uint16(data[34:36]) // MagicNumber: 0x504C ("LP")
|
||||
reserved := data[64:80] // Reserved 1-4 (each: unsigned long)
|
||||
return (version == 0x00010000 || version == 0x00020001 || version == 0x00020002) && magic == 0x504C && bytes.Count(reserved, []byte{0}) == len(reserved)
|
||||
}
|
||||
|
||||
// DetectContentType extends http.DetectContentType with more content types. Defaults to text/plain if input is empty.
|
||||
func DetectContentType(data []byte) SniffedType {
|
||||
if len(data) == 0 {
|
||||
@ -119,6 +130,18 @@ func DetectContentType(data []byte) SniffedType {
|
||||
data = data[:SniffContentSize]
|
||||
}
|
||||
|
||||
const typeMsFontObject = "application/vnd.ms-fontobject"
|
||||
if ct == typeMsFontObject {
|
||||
// Stupid Golang blindly detects any content with 34th-35th bytes being "LP" as font.
|
||||
// If it is not really for ".eot" content, we try to detect it again by hiding the "LP", see the test for more details.
|
||||
if isEmbeddedOpenType(data) {
|
||||
return SniffedType{typeMsFontObject}
|
||||
}
|
||||
data = slices.Clone(data)
|
||||
data[34] = 'l'
|
||||
ct = http.DetectContentType(data)
|
||||
}
|
||||
|
||||
vars := globalVars()
|
||||
// SVG is unsupported by http.DetectContentType, https://github.com/golang/go/issues/15888
|
||||
detectByHTML := strings.Contains(ct, "text/plain") || strings.Contains(ct, "text/html")
|
||||
|
||||
@ -6,6 +6,7 @@ package typesniffer
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@ -154,3 +155,25 @@ func TestDetectContentTypeAvif(t *testing.T) {
|
||||
st := DetectContentType(buf)
|
||||
assert.Equal(t, MimeTypeImageAvif, st.contentType)
|
||||
}
|
||||
|
||||
func TestDetectContentTypeIncorrectFont(t *testing.T) {
|
||||
s := "Stupid Golang keep detecting 34th LP as font"
|
||||
// They don't want to have any improvement to it: https://github.com/golang/go/issues/77172
|
||||
golangDetected := http.DetectContentType([]byte(s))
|
||||
assert.Equal(t, "application/vnd.ms-fontobject", golangDetected)
|
||||
// We have to make our patch to make it work correctly
|
||||
ourDetected := DetectContentType([]byte(s))
|
||||
assert.Equal(t, "text/plain; charset=utf-8", ourDetected.contentType)
|
||||
|
||||
// For binary content, ensure it still detects as font. The content is from "opensans-regular.eot"
|
||||
b := []byte{
|
||||
0x3d, 0x30, 0x00, 0x00, 0x6b, 0x2f, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x02, 0x0b, 0x06, 0x06, 0x03, 0x05, 0x04, 0x02, 0x02, 0x04, 0x01, 0x00, 0x90, 0x01, 0x00, 0x00,
|
||||
0x04, 0x00, 0x4c, 0x50, 0xef, 0x02, 0x00, 0xe0, 0x5b, 0x20, 0x00, 0x40, 0x28, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x9f, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x63, 0xf4, 0x17, 0x14,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x12, 0x00, 0x4f, 0x00, 0x70, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x53, 0x00,
|
||||
}
|
||||
assert.Equal(t, "application/vnd.ms-fontobject", http.DetectContentType(b))
|
||||
assert.Equal(t, "application/vnd.ms-fontobject", DetectContentType(b).contentType)
|
||||
}
|
||||
|
||||
170
options/fileicon/material-icon-rules.json
generated
170
options/fileicon/material-icon-rules.json
generated
@ -460,6 +460,22 @@
|
||||
".blog": "folder-docs",
|
||||
"_blog": "folder-docs",
|
||||
"__blog__": "folder-docs",
|
||||
"knowledge": "folder-docs",
|
||||
".knowledge": "folder-docs",
|
||||
"_knowledge": "folder-docs",
|
||||
"__knowledge__": "folder-docs",
|
||||
"diary": "folder-docs",
|
||||
".diary": "folder-docs",
|
||||
"_diary": "folder-docs",
|
||||
"__diary__": "folder-docs",
|
||||
"note": "folder-docs",
|
||||
".note": "folder-docs",
|
||||
"_note": "folder-docs",
|
||||
"__note__": "folder-docs",
|
||||
"notes": "folder-docs",
|
||||
".notes": "folder-docs",
|
||||
"_notes": "folder-docs",
|
||||
"__notes__": "folder-docs",
|
||||
"github/workflows": "folder-gh-workflows",
|
||||
".github/workflows": "folder-gh-workflows",
|
||||
"_github/workflows": "folder-gh-workflows",
|
||||
@ -916,6 +932,14 @@
|
||||
".sql": "folder-database",
|
||||
"_sql": "folder-database",
|
||||
"__sql__": "folder-database",
|
||||
"migrations": "folder-migrations",
|
||||
".migrations": "folder-migrations",
|
||||
"_migrations": "folder-migrations",
|
||||
"__migrations__": "folder-migrations",
|
||||
"migration": "folder-migrations",
|
||||
".migration": "folder-migrations",
|
||||
"_migration": "folder-migrations",
|
||||
"__migration__": "folder-migrations",
|
||||
"log": "folder-log",
|
||||
".log": "folder-log",
|
||||
"_log": "folder-log",
|
||||
@ -1008,6 +1032,14 @@
|
||||
".recordings": "folder-audio",
|
||||
"_recordings": "folder-audio",
|
||||
"__recordings__": "folder-audio",
|
||||
"playlist": "folder-audio",
|
||||
".playlist": "folder-audio",
|
||||
"_playlist": "folder-audio",
|
||||
"__playlist__": "folder-audio",
|
||||
"playlists": "folder-audio",
|
||||
".playlists": "folder-audio",
|
||||
"_playlists": "folder-audio",
|
||||
"__playlists__": "folder-audio",
|
||||
"vid": "folder-video",
|
||||
".vid": "folder-video",
|
||||
"_vid": "folder-video",
|
||||
@ -1544,6 +1576,22 @@
|
||||
".backends": "folder-server",
|
||||
"_backends": "folder-server",
|
||||
"__backends__": "folder-server",
|
||||
"inventory": "folder-server",
|
||||
".inventory": "folder-server",
|
||||
"_inventory": "folder-server",
|
||||
"__inventory__": "folder-server",
|
||||
"inventories": "folder-server",
|
||||
".inventories": "folder-server",
|
||||
"_inventories": "folder-server",
|
||||
"__inventories__": "folder-server",
|
||||
"infrastructure": "folder-server",
|
||||
".infrastructure": "folder-server",
|
||||
"_infrastructure": "folder-server",
|
||||
"__infrastructure__": "folder-server",
|
||||
"infra": "folder-server",
|
||||
".infra": "folder-server",
|
||||
"_infra": "folder-server",
|
||||
"__infra__": "folder-server",
|
||||
"client": "folder-client",
|
||||
".client": "folder-client",
|
||||
"_client": "folder-client",
|
||||
@ -1992,6 +2040,14 @@
|
||||
".calculations": "folder-functions",
|
||||
"_calculations": "folder-functions",
|
||||
"__calculations__": "folder-functions",
|
||||
"composable": "folder-functions",
|
||||
".composable": "folder-functions",
|
||||
"_composable": "folder-functions",
|
||||
"__composable__": "folder-functions",
|
||||
"composables": "folder-functions",
|
||||
".composables": "folder-functions",
|
||||
"_composables": "folder-functions",
|
||||
"__composables__": "folder-functions",
|
||||
"generator": "folder-generator",
|
||||
".generator": "folder-generator",
|
||||
"_generator": "folder-generator",
|
||||
@ -2936,6 +2992,14 @@
|
||||
".projects": "folder-project",
|
||||
"_projects": "folder-project",
|
||||
"__projects__": "folder-project",
|
||||
"proj": "folder-project",
|
||||
".proj": "folder-project",
|
||||
"_proj": "folder-project",
|
||||
"__proj__": "folder-project",
|
||||
"projs": "folder-project",
|
||||
".projs": "folder-project",
|
||||
"_projs": "folder-project",
|
||||
"__projs__": "folder-project",
|
||||
"prompt": "folder-prompts",
|
||||
".prompt": "folder-prompts",
|
||||
"_prompt": "folder-prompts",
|
||||
@ -3447,6 +3511,14 @@
|
||||
".in": "folder-input",
|
||||
"_in": "folder-input",
|
||||
"__in__": "folder-input",
|
||||
"salt": "folder-salt",
|
||||
".salt": "folder-salt",
|
||||
"_salt": "folder-salt",
|
||||
"__salt__": "folder-salt",
|
||||
"saltstack": "folder-salt",
|
||||
".saltstack": "folder-salt",
|
||||
"_saltstack": "folder-salt",
|
||||
"__saltstack__": "folder-salt",
|
||||
"simulations": "folder-simulations",
|
||||
".simulations": "folder-simulations",
|
||||
"_simulations": "folder-simulations",
|
||||
@ -3961,6 +4033,22 @@
|
||||
".blog": "folder-docs-open",
|
||||
"_blog": "folder-docs-open",
|
||||
"__blog__": "folder-docs-open",
|
||||
"knowledge": "folder-docs-open",
|
||||
".knowledge": "folder-docs-open",
|
||||
"_knowledge": "folder-docs-open",
|
||||
"__knowledge__": "folder-docs-open",
|
||||
"diary": "folder-docs-open",
|
||||
".diary": "folder-docs-open",
|
||||
"_diary": "folder-docs-open",
|
||||
"__diary__": "folder-docs-open",
|
||||
"note": "folder-docs-open",
|
||||
".note": "folder-docs-open",
|
||||
"_note": "folder-docs-open",
|
||||
"__note__": "folder-docs-open",
|
||||
"notes": "folder-docs-open",
|
||||
".notes": "folder-docs-open",
|
||||
"_notes": "folder-docs-open",
|
||||
"__notes__": "folder-docs-open",
|
||||
"github/workflows": "folder-gh-workflows-open",
|
||||
".github/workflows": "folder-gh-workflows-open",
|
||||
"_github/workflows": "folder-gh-workflows-open",
|
||||
@ -4417,6 +4505,14 @@
|
||||
".sql": "folder-database-open",
|
||||
"_sql": "folder-database-open",
|
||||
"__sql__": "folder-database-open",
|
||||
"migrations": "folder-migrations-open",
|
||||
".migrations": "folder-migrations-open",
|
||||
"_migrations": "folder-migrations-open",
|
||||
"__migrations__": "folder-migrations-open",
|
||||
"migration": "folder-migrations-open",
|
||||
".migration": "folder-migrations-open",
|
||||
"_migration": "folder-migrations-open",
|
||||
"__migration__": "folder-migrations-open",
|
||||
"log": "folder-log-open",
|
||||
".log": "folder-log-open",
|
||||
"_log": "folder-log-open",
|
||||
@ -4509,6 +4605,14 @@
|
||||
".recordings": "folder-audio-open",
|
||||
"_recordings": "folder-audio-open",
|
||||
"__recordings__": "folder-audio-open",
|
||||
"playlist": "folder-audio-open",
|
||||
".playlist": "folder-audio-open",
|
||||
"_playlist": "folder-audio-open",
|
||||
"__playlist__": "folder-audio-open",
|
||||
"playlists": "folder-audio-open",
|
||||
".playlists": "folder-audio-open",
|
||||
"_playlists": "folder-audio-open",
|
||||
"__playlists__": "folder-audio-open",
|
||||
"vid": "folder-video-open",
|
||||
".vid": "folder-video-open",
|
||||
"_vid": "folder-video-open",
|
||||
@ -5045,6 +5149,22 @@
|
||||
".backends": "folder-server-open",
|
||||
"_backends": "folder-server-open",
|
||||
"__backends__": "folder-server-open",
|
||||
"inventory": "folder-server-open",
|
||||
".inventory": "folder-server-open",
|
||||
"_inventory": "folder-server-open",
|
||||
"__inventory__": "folder-server-open",
|
||||
"inventories": "folder-server-open",
|
||||
".inventories": "folder-server-open",
|
||||
"_inventories": "folder-server-open",
|
||||
"__inventories__": "folder-server-open",
|
||||
"infrastructure": "folder-server-open",
|
||||
".infrastructure": "folder-server-open",
|
||||
"_infrastructure": "folder-server-open",
|
||||
"__infrastructure__": "folder-server-open",
|
||||
"infra": "folder-server-open",
|
||||
".infra": "folder-server-open",
|
||||
"_infra": "folder-server-open",
|
||||
"__infra__": "folder-server-open",
|
||||
"client": "folder-client-open",
|
||||
".client": "folder-client-open",
|
||||
"_client": "folder-client-open",
|
||||
@ -5493,6 +5613,14 @@
|
||||
".calculations": "folder-functions-open",
|
||||
"_calculations": "folder-functions-open",
|
||||
"__calculations__": "folder-functions-open",
|
||||
"composable": "folder-functions-open",
|
||||
".composable": "folder-functions-open",
|
||||
"_composable": "folder-functions-open",
|
||||
"__composable__": "folder-functions-open",
|
||||
"composables": "folder-functions-open",
|
||||
".composables": "folder-functions-open",
|
||||
"_composables": "folder-functions-open",
|
||||
"__composables__": "folder-functions-open",
|
||||
"generator": "folder-generator-open",
|
||||
".generator": "folder-generator-open",
|
||||
"_generator": "folder-generator-open",
|
||||
@ -6437,6 +6565,14 @@
|
||||
".projects": "folder-project-open",
|
||||
"_projects": "folder-project-open",
|
||||
"__projects__": "folder-project-open",
|
||||
"proj": "folder-project-open",
|
||||
".proj": "folder-project-open",
|
||||
"_proj": "folder-project-open",
|
||||
"__proj__": "folder-project-open",
|
||||
"projs": "folder-project-open",
|
||||
".projs": "folder-project-open",
|
||||
"_projs": "folder-project-open",
|
||||
"__projs__": "folder-project-open",
|
||||
"prompt": "folder-prompts-open",
|
||||
".prompt": "folder-prompts-open",
|
||||
"_prompt": "folder-prompts-open",
|
||||
@ -6948,6 +7084,14 @@
|
||||
".in": "folder-input-open",
|
||||
"_in": "folder-input-open",
|
||||
"__in__": "folder-input-open",
|
||||
"salt": "folder-salt-open",
|
||||
".salt": "folder-salt-open",
|
||||
"_salt": "folder-salt-open",
|
||||
"__salt__": "folder-salt-open",
|
||||
"saltstack": "folder-salt-open",
|
||||
".saltstack": "folder-salt-open",
|
||||
"_saltstack": "folder-salt-open",
|
||||
"__saltstack__": "folder-salt-open",
|
||||
"simulations": "folder-simulations-open",
|
||||
".simulations": "folder-simulations-open",
|
||||
"_simulations": "folder-simulations-open",
|
||||
@ -7213,6 +7357,7 @@
|
||||
"csproj": "visualstudio",
|
||||
"ruleset": "visualstudio",
|
||||
"sln": "visualstudio",
|
||||
"slnf": "visualstudio",
|
||||
"slnx": "visualstudio",
|
||||
"suo": "visualstudio",
|
||||
"vb": "visualstudio",
|
||||
@ -8162,6 +8307,7 @@
|
||||
"toc": "toc",
|
||||
"cue": "cue",
|
||||
"lean": "lean",
|
||||
"sls": "salt",
|
||||
"cljx": "clojure",
|
||||
"clojure": "clojure",
|
||||
"edn": "clojure",
|
||||
@ -10150,6 +10296,30 @@
|
||||
"esbuild.config.ts": "esbuild",
|
||||
"esbuild.config.mts": "esbuild",
|
||||
"esbuild.config.cts": "esbuild",
|
||||
"esbuild.dev.js": "esbuild",
|
||||
"esbuild.dev.mjs": "esbuild",
|
||||
"esbuild.dev.cjs": "esbuild",
|
||||
"esbuild.dev.ts": "esbuild",
|
||||
"esbuild.dev.mts": "esbuild",
|
||||
"esbuild.dev.cts": "esbuild",
|
||||
"esbuild.stage.js": "esbuild",
|
||||
"esbuild.stage.mjs": "esbuild",
|
||||
"esbuild.stage.cjs": "esbuild",
|
||||
"esbuild.stage.ts": "esbuild",
|
||||
"esbuild.stage.mts": "esbuild",
|
||||
"esbuild.stage.cts": "esbuild",
|
||||
"esbuild.prod.js": "esbuild",
|
||||
"esbuild.prod.mjs": "esbuild",
|
||||
"esbuild.prod.cjs": "esbuild",
|
||||
"esbuild.prod.ts": "esbuild",
|
||||
"esbuild.prod.mts": "esbuild",
|
||||
"esbuild.prod.cts": "esbuild",
|
||||
"esbuild.test.js": "esbuild",
|
||||
"esbuild.test.mjs": "esbuild",
|
||||
"esbuild.test.cjs": "esbuild",
|
||||
"esbuild.test.ts": "esbuild",
|
||||
"esbuild.test.mts": "esbuild",
|
||||
"esbuild.test.cts": "esbuild",
|
||||
"drizzle.config.ts": "drizzle",
|
||||
"drizzle.config.dev.ts": "drizzle",
|
||||
"drizzle.config.prod.ts": "drizzle",
|
||||
|
||||
9
options/fileicon/material-icon-svgs.json
generated
9
options/fileicon/material-icon-svgs.json
generated
@ -151,8 +151,8 @@
|
||||
"database": "<svg viewBox='0 0 32 32'><path fill='#ffca28' d='M16 24c-5.525 0-10-.9-10-2v4c0 1.1 4.475 2 10 2s10-.9 10-2v-4c0 1.1-4.475 2-10 2m0-8c-5.525 0-10-.9-10-2v4c0 1.1 4.475 2 10 2s10-.9 10-2v-4c0 1.1-4.475 2-10 2m0-12C10.477 4 6 4.895 6 6v4c0 1.1 4.475 2 10 2s10-.9 10-2V6c0-1.105-4.477-2-10-2'/></svg>",
|
||||
"deepsource": "<svg viewBox='0 0 16 16'><path fill='#1de9b6' d='M2 2h9a1 1 0 0 1 1 .992A1 1 0 0 1 11 4H2z'/><path fill='#f44336' d='M2 12h11a1 1 0 0 1 1 1 1 1 0 0 1-1 1H2z'/><path fill='#ffb300' d='M2 9h7a1 1 0 0 0 1-1 1 1 0 0 0-1-1H2z'/></svg>",
|
||||
"denizenscript": "<svg viewBox='0 0 32 32'><path fill='#ffd54f' d='M6 4h8.804a17 17 0 0 1 4.54.459 8 8 0 0 1 3.597 2.21 10.5 10.5 0 0 1 2.278 3.887A17.8 17.8 0 0 1 26 16.23a15.8 15.8 0 0 1-.733 5.108 10.6 10.6 0 0 1-2.554 4.24 8.45 8.45 0 0 1-3.385 1.915 14.5 14.5 0 0 1-4.264.508H6Zm4 4.06v15.896h4.413a13 13 0 0 0 2.913-.228 4.45 4.45 0 0 0 1.945-1 5.1 5.1 0 0 0 1.261-2.316 15.8 15.8 0 0 0 .488-4.395 14.5 14.5 0 0 0-.488-4.274 5.5 5.5 0 0 0-1.367-2.324 4.57 4.57 0 0 0-2.23-1.13 21.7 21.7 0 0 0-3.954-.229Z' style='isolation:isolate'/></svg>",
|
||||
"deno": "<svg viewBox='0 0 32 32'><path fill='#cfd8dc' d='M3.069 10.688C3.069 5.873 7.859 2 14 2a11.9 11.9 0 0 1 7.49 2.378 10.64 10.64 0 0 1 3.593 5.236l.015.049.017.057.034.108.048.198.134.463.14.529.238.875.38 1.386.613 2.28.692 2.593 1.116 4.168.42 1.571-.09.1A18.98 18.98 0 0 1 17.337 30l-.04-.273-.074-.545-.066-.395-.076-.52-.097-.634-.042-.25-.091-.602-.057-.356-.074-.462-.076-.444-.074-.432-.074-.422-.066-.413-.074-.395-.068-.38-.048-.281-.057-.271-.034-.173-.066-.35-.05-.246-.057-.305-.049-.215-.042-.205-.043-.2-.023-.132-.059-.248-.042-.181-.04-.182-.032-.114-.042-.167-.032-.157-.042-.156-.043-.148-.023-.091-.042-.142-.032-.13-.025-.092-.034-.084-.023-.072-.034-.116-.025-.085-.017-.049q-.067-.196-.148-.386l-.026-.051.19-.495-.75.026-.207.008c-6.82.14-11.222-2.759-11.222-7.301Zm14.345-4.101a2 2 0 1 0 0 2.827 2 2 0 0 0 0-2.827'/><path fill='#cfd8dc' d='M3.069 10.688c.95-12.027 21.388-11.423 22.64 1.205 1.027 3.74 2.21 8.244 3.222 11.998A18.98 18.98 0 0 1 17.337 30c-.407-2.79-.84-5.602-1.41-8.364a27 27 0 0 0-.505-2.123c-.104-.536-.523-1.043-.173-1.56-6.665.529-12.374-2.428-12.18-7.267Zm14.345-4.101c-1.807-1.861-4.689 1.02-2.827 2.828 1.807 1.86 4.689-1.021 2.827-2.828'/></svg>",
|
||||
"deno_light": "<svg viewBox='0 0 32 32'><path fill='#455a64' d='M3.07 10.688C4.02-1.34 24.46-.735 25.713 11.893c1.027 3.74 2.21 8.244 3.222 11.998A18.98 18.98 0 0 1 17.339 30c-.407-2.79-.839-5.602-1.41-8.364a27 27 0 0 0-.505-2.123c-.103-.536-.522-1.043-.173-1.56-6.665.529-12.374-2.428-12.18-7.267Zm14.347-4.101c-1.808-1.861-4.69 1.02-2.828 2.828 1.808 1.86 4.69-1.021 2.828-2.828'/></svg>",
|
||||
"deno": "<svg viewBox='0 0 32 32'><path fill='#cfd8dc' d='M3.288 23.102A13.937 14.098 0 0 1 2 17.16c0-.553.028-1.09.091-1.622a14.049 14.211 0 0 1 .273-1.586 14 14.162 0 0 1 4.333-7.37 14.007 14.169 0 0 1 6.37-3.272 14.028 14.19 0 0 1 3.997-.27 13.958 14.12 0 0 1 4.76 1.24 14.021 14.183 0 0 1 3.241 2.089 14.028 14.19 0 0 1 4.732 8.355A14.063 14.225 0 0 1 30 17.161a14.175 14.339 0 0 1-.042 1.076 13.986 14.147 0 0 1-.847 3.902 14.007 14.169 0 0 1-2.779 4.574A7.245 7.329 0 0 1 21.166 29a5.054 5.112 0 0 1-4.816-6.444c.119-.453.434-1.317.889-1.699a5.334 5.396 0 0 1-1.435-.977c-.049-.057-.042-.156.007-.22a.182.184 0 0 1 .203-.056 10.206 10.324 0 0 0 1.596.41c.777.128 1.736.298 2.709.34 2.366.12 4.844-.956 5.614-3.094.763-2.146.469-4.263-2.289-5.53-2.758-1.275-4.032-2.783-6.258-3.696-1.456-.595-3.073-.241-4.732.694-4.48 2.5-8.491 10.408-6.643 17.737a.224.227 0 0 1-.364.22 14.077 14.24 0 0 1-1.463-1.927 14.021 14.183 0 0 1-.896-1.656M15.503 9.018c.749-.057 1.414.595 1.526 1.459.147 1.154-.273 2.35-1.645 2.379-1.183.02-1.54-1.176-1.456-1.905.077-.73.665-1.862 1.568-1.933z'/></svg>",
|
||||
"deno_light": "<svg viewBox='0 0 32 32'><path fill='#455a64' d='M3.288 23.102A13.937 14.098 0 0 1 2 17.16c0-.553.028-1.09.091-1.622a14.049 14.211 0 0 1 .273-1.586 14 14.162 0 0 1 4.333-7.37 14.007 14.169 0 0 1 6.37-3.272 14.028 14.19 0 0 1 3.997-.27 13.958 14.12 0 0 1 4.76 1.24 14.021 14.183 0 0 1 3.241 2.089 14.028 14.19 0 0 1 4.732 8.355A14.063 14.225 0 0 1 30 17.161a14.175 14.339 0 0 1-.042 1.076 13.986 14.147 0 0 1-.847 3.902 14.007 14.169 0 0 1-2.779 4.574A7.245 7.329 0 0 1 21.166 29a5.054 5.112 0 0 1-4.816-6.444c.119-.453.434-1.317.889-1.699a5.334 5.396 0 0 1-1.435-.977c-.049-.057-.042-.156.007-.22a.182.184 0 0 1 .203-.056 10.206 10.324 0 0 0 1.596.41c.777.128 1.736.298 2.709.34 2.366.12 4.844-.956 5.614-3.094.763-2.146.469-4.263-2.289-5.53-2.758-1.275-4.032-2.783-6.258-3.696-1.456-.595-3.073-.241-4.732.694-4.48 2.5-8.491 10.408-6.643 17.737a.224.227 0 0 1-.364.22 14.077 14.24 0 0 1-1.463-1.927 14.021 14.183 0 0 1-.896-1.656M15.503 9.018c.749-.057 1.414.595 1.526 1.459.147 1.154-.273 2.35-1.645 2.379-1.183.02-1.54-1.176-1.456-1.905.077-.73.665-1.862 1.568-1.933z'/></svg>",
|
||||
"dependabot": "<svg viewBox='0 0 32 32'><path fill='#448aff' d='M29.5 16H28v-4a2 2 0 0 0-2-2h-6V2.5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5H18v4H6a2 2 0 0 0-2 2v4H2.5a.5.5 0 0 0-.5.5v7a.5.5 0 0 0 .5.5H4v2a2 2 0 0 0 2 2h20a2 2 0 0 0 2-2v-2h1.5a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.5-.5m-15.533 2.647-3.106 3.106a.6.6 0 0 1-.84 0l-1.867-1.866a.6.6 0 0 1 0-.84l.627-.64a.6.6 0 0 1 .848-.005l.005.005.8.8 2.053-2.04a.6.6 0 0 1 .84 0l.64.64a.58.58 0 0 1 0 .84m9.88 0-3.106 3.106a.6.6 0 0 1-.84 0l-1.867-1.866a.6.6 0 0 1 0-.84l.627-.64a.6.6 0 0 1 .84 0l.813.8 2.053-2.04a.6.6 0 0 1 .84 0l.64.64a.604.604 0 0 1 0 .84'/></svg>",
|
||||
"dependencies-update": "<svg fill='none' viewBox='0 0 16 16'><path fill='#8bc34a' d='m10.484 3.635-2.5 2.546-.875-.891 1-1.018H8q-1.563 0-2.656 1.121Q4.249 6.515 4.25 8.122a3.5 3.5 0 0 0 .375 1.59l-.937.955a5.156 5.25 0 0 1-.516-1.24A4.81 4.897 0 0 1 3 8.121Q3 5.99 4.453 4.494T8 2.999h.11l-1-1.018.874-.891zm-4.968 8.747 2.5-2.546.875.891-1 1.018H8q1.563 0 2.656-1.12 1.095-1.123 1.094-2.73a3.5 3.5 0 0 0-.375-1.59l.938-.955q.343.604.515 1.24.172.638.172 1.305 0 2.131-1.453 3.628Q10.094 13.018 8 13.018h-.11l1 1.018-.874.891z'/></svg>",
|
||||
"dhall": "<svg viewBox='0 0 24 24'><path fill='#78909c' d='M15.81 2.853 21.148 8.2l-1.54 1.518-5.326-5.327 1.528-1.54M2.853 20.373l6.995-6.962a1.04 1.04 0 0 1 .247-1.033c.42-.42 1.109-.42 1.528 0 .42.43.42 1.108 0 1.528-.28.28-.7.355-1.033.248l-6.962 6.995 11.418-3.82 3.799-6.845-5.317-5.327-6.855 3.799z'/></svg>",
|
||||
@ -495,6 +495,8 @@
|
||||
"folder-metro": "<svg viewBox='0 0 32 32'><path fill='#ef5350' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#ffcdd2' d='M24 10a2.917 2.92 0 0 0-1.305.308l-5.39 2.7A2.36 2.363 0 0 0 16 15.12v7.759a2.36 2.363 0 0 0 1.304 2.111l5.39 2.701a2.917 2.92 0 0 0 2.61 0l5.39-2.7A2.36 2.363 0 0 0 32 22.878V15.12a2.36 2.363 0 0 0-1.304-2.112l-5.391-2.7A2.917 2.92 0 0 0 23.999 10m0 1.33a2.875 2.878 0 0 1 1.286.305l4.047 2.025-1.667.834-3.667-1.835-3.666 1.835-1.667-.834 4.047-2.025A2.875 2.878 0 0 1 24 11.329zm-5.735 3.545a.882.883 0 0 1 .344.091l5.39 2.699 5.39-2.699a.882.883 0 0 1 .313-.088.882.883 0 0 1 .964.878v6.153a2.308 2.31 0 0 1-1.276 2.067l-4.114 2.06a2.853 2.856 0 0 1-2.553 0l-4.114-2.06a2.308 2.31 0 0 1-1.276-2.067v-6.153a.882.883 0 0 1 .932-.881m.401 1.788v5.673L24 25.006l5.334-2.67v-5.673l-4.133 2.07a2.683 2.686 0 0 1-2.401 0z'/></svg>",
|
||||
"folder-middleware-open": "<svg viewBox='0 0 32 32'><path fill='#5c6bc0' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#c5cae9' d='M30.107 20H32v-4a2 2 0 0 0-2-2h-4v-2a2 2 0 0 0-4 0v2h-4a2 2 0 0 0-2 2v4h-2a2 2 0 0 0 0 4h2v4a2 2 0 0 0 2 2h4v-1.893a2.074 2.074 0 0 1 1.664-2.08A2 2 0 0 1 26 28v2h4a2 2 0 0 0 2-2v-4h-2a2 2 0 0 1-1.973-2.336A2.074 2.074 0 0 1 30.107 20'/></svg>",
|
||||
"folder-middleware": "<svg viewBox='0 0 32 32'><path fill='#5c6bc0' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#c5cae9' d='M30.107 20H32v-4a2 2 0 0 0-2-2h-4v-2a2 2 0 0 0-4 0v2h-4a2 2 0 0 0-2 2v4h-2a2 2 0 0 0 0 4h2v4a2 2 0 0 0 2 2h4v-1.893a2.074 2.074 0 0 1 1.664-2.08A2 2 0 0 1 26 28v2h4a2 2 0 0 0 2-2v-4h-2a2 2 0 0 1-1.973-2.336A2.074 2.074 0 0 1 30.107 20'/></svg>",
|
||||
"folder-migrations-open": "<svg viewBox='0 0 32 32'><path fill='#ec407a' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#f8bbd0' d='M24 10c-3.41 0-6.31 1.07-7.46 2.57l5.25 5.25c.71.11 1.43.18 2.21.18 4.42 0 8-1.79 8-4s-3.58-4-8-4m-8 4v4h-4v2h4v4l4.84-5M32 16c0 2.21-3.58 4-8 4-.66 0-1.3-.05-1.91-.13l-2.47 2.47c1.26.41 2.76.66 4.38.66 4.42 0 8-1.79 8-4m0 2c0 2.21-3.58 4-8 4-2.28 0-4.33-.5-5.79-1.25l-1.68 1.68C17.68 26.93 20.59 28 24 28c4.42 0 8-1.79 8-4'/></svg>",
|
||||
"folder-migrations": "<svg viewBox='0 0 32 32'><path fill='#ec407a' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#f8bbd0' d='M24 10c-3.41 0-6.31 1.07-7.46 2.57l5.25 5.25c.71.11 1.43.18 2.21.18 4.42 0 8-1.79 8-4s-3.58-4-8-4m-8 4v4h-4v2h4v4l4.84-5M32 16c0 2.21-3.58 4-8 4-.66 0-1.3-.05-1.91-.13l-2.47 2.47c1.26.41 2.76.66 4.38.66 4.42 0 8-1.79 8-4m0 2c0 2.21-3.58 4-8 4-2.28 0-4.33-.5-5.79-1.25l-1.68 1.68C17.68 26.93 20.59 28 24 28c4.42 0 8-1.79 8-4'/></svg>",
|
||||
"folder-mjml-open": "<svg viewBox='0 0 32 32'><path fill='#ff5722' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><rect width='12' height='4' x='14' y='24' fill='#ffccbc' rx='2'/><rect width='12' height='4' x='20' y='18' fill='#ffccbc' rx='2'/><rect width='12' height='4' x='14' y='12' fill='#ffccbc' rx='2'/><circle cx='30' cy='26' r='2' fill='#ffccbc'/><circle cx='16' cy='20' r='2' fill='#ffccbc'/><circle cx='30' cy='14' r='2' fill='#ffccbc'/></svg>",
|
||||
"folder-mjml": "<svg viewBox='0 0 32 32'><path fill='#ff5722' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><rect width='12' height='4' x='14' y='24' fill='#ffccbc' rx='2'/><rect width='12' height='4' x='20' y='18' fill='#ffccbc' rx='2'/><rect width='12' height='4' x='14' y='12' fill='#ffccbc' rx='2'/><circle cx='30' cy='26' r='2' fill='#ffccbc'/><circle cx='16' cy='20' r='2' fill='#ffccbc'/><circle cx='30' cy='14' r='2' fill='#ffccbc'/></svg>",
|
||||
"folder-mobile-open": "<svg viewBox='0 0 32 32'><path fill='#ff5252' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#ffcdd2' d='M12 14v10a2 2 0 0 0 2 2h8v-2h-6V14h12v2h4v-2a2 2 0 0 0-2-2H14a2 2 0 0 0-2 2'/><path fill='#ffcdd2' d='M24 19v8a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1v-8a1 1 0 0 0-1-1h-6a1 1 0 0 0-1 1m6 7h-4v-6h4Z'/></svg>",
|
||||
@ -604,6 +606,8 @@
|
||||
"folder-rules": "<svg viewBox='0 0 32 32'><path fill='#ef5350' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#ffcdd2' d='M30 14h-2a3 3 0 0 0-6 0h-2a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V16a2 2 0 0 0-2-2m-5-1a1 1 0 1 1-1 1 1.003 1.003 0 0 1 1-1m-1.547 11.597-3.093-3.093 1.09-1.09 2.003 1.995 5.096-5.096 1.091 1.099Z'/></svg>",
|
||||
"folder-rust-open": "<svg viewBox='0 0 32 32'><path fill='#ff7043' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#ffccbc' d='M30 24v1a1 1 0 0 1-2 0v-1a2 2 0 0 0-2-2 3 3 0 0 0 2.996-3.16A3.115 3.114 0 0 0 25.83 16H14v2h2v8h-2v2h8v-2h-2v-2h4c.82.819.297 2.308 1.179 3.37a1.89 1.89 0 0 0 1.46.63H32v-4zm-6-4h-4v-2h4a1 1 0 0 1 0 2'/></svg>",
|
||||
"folder-rust": "<svg viewBox='0 0 32 32'><path fill='#ff7043' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#ffccbc' d='M30 24v1a1 1 0 0 1-2 0v-1a2 2 0 0 0-2-2 3 3 0 0 0 2.996-3.16A3.115 3.114 0 0 0 25.83 16H14v2h2v8h-2v2h8v-2h-2v-2h4c.82.819.297 2.308 1.179 3.37a1.89 1.89 0 0 0 1.46.63H32v-4zm-6-4h-4v-2h4a1 1 0 0 1 0 2'/></svg>",
|
||||
"folder-salt-open": "<svg viewBox='0 0 32 32'><path fill='#03a9f4' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#b3e5fc' d='M12 20v8h10l4-8h6v-8H22l-4 8z'/></svg>",
|
||||
"folder-salt": "<svg viewBox='0 0 32 32'><path fill='#03a9f4' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#b3e5fc' d='M12 20v8h10l4-8h6v-8H22l-4 8z'/></svg>",
|
||||
"folder-sandbox-open": "<svg viewBox='0 0 32 32'><path fill='#1e88e5' d='M28.965 12.001H9.44a2 2 0 0 0-1.898 1.368L3.998 24.001v-14h24a2 2 0 0 0-2-2H15.122a2 2 0 0 1-1.28-.464l-1.288-1.072a2 2 0 0 0-1.28-.464H3.998a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212a2 2 0 0 0-1.838-2.788'/><path fill='#bbdefb' d='M21 20h-6a1 1 0 0 1-1-1v-6a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1m7-8a4 4 0 1 0 4 4 4 4 0 0 0-4-4m.707 17.707 3-3a1 1 0 0 0 0-1.414l-3-3a1 1 0 0 0-1.414 0l-3 3a1 1 0 0 0 0 1.414l3 3a1 1 0 0 0 1.414 0m-11.581-7.193-2.999 6A1 1 0 0 0 15.001 30H21a1 1 0 0 0 .874-1.486l-2.999-6a1 1 0 0 0-1.748 0'/></svg>",
|
||||
"folder-sandbox": "<svg viewBox='0 0 32 32'><path fill='#1e88e5' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#bbdefb' d='M21 20h-6a1 1 0 0 1-1-1v-6a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1m7-8a4 4 0 1 0 4 4 4 4 0 0 0-4-4m.707 17.707 3-3a1 1 0 0 0 0-1.414l-3-3a1 1 0 0 0-1.414 0l-3 3a1 1 0 0 0 0 1.414l3 3a1 1 0 0 0 1.414 0m-11.581-7.193-2.999 6A1 1 0 0 0 15.001 30H21a1 1 0 0 0 .874-1.486l-2.999-6a1 1 0 0 0-1.748 0'/></svg>",
|
||||
"folder-sass-open": "<svg viewBox='0 0 32 32'><path fill='#f06292' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#fce4ec' d='M31.897 12.592a3 3 0 0 0-1.53-1.912 7.95 7.95 0 0 0-6.348-.05 17.4 17.4 0 0 0-5.864 3.557c-1.83 1.81-2.288 3.496-2.124 4.39.346 1.89 2.181 3.227 3.658 4.3.314.23.618.45.876.657-.92.513-2.916 1.749-3.483 3.074a2.9 2.9 0 0 0-.074 2.347 1.57 1.57 0 0 0 .874.903 3.5 3.5 0 0 0 .986.142 4.14 4.14 0 0 0 3.438-2.025 5.03 5.03 0 0 0 .55-3.886 4.5 4.5 0 0 1 1.46-.034 2.64 2.64 0 0 1 1.927.96 1.44 1.44 0 0 1 .304.968 1.2 1.2 0 0 1-.55.805c-.159.104-.356.233-.31.504.028.151.13.393.532.313a1.99 1.99 0 0 0 1.392-1.841 2.9 2.9 0 0 0-.801-2.051 3.9 3.9 0 0 0-2.897-1.135 6.5 6.5 0 0 0-1.813.226 13 13 0 0 0-1.498-1.346c-1.165-.947-2.265-1.842-2.2-3.125.085-1.654 1.672-3.306 4.716-4.909 2.7-1.422 4.894-1.47 6.04-1.041a1.44 1.44 0 0 1 .858.674 2.23 2.23 0 0 1-.257 1.866 6.57 6.57 0 0 1-5.023 3.105 2.56 2.56 0 0 1-2.225-.565c-.189-.219-.37-.423-.65-.263-.332.196-.175.625-.123.768a2.6 2.6 0 0 0 1.578 1.342 7.32 7.32 0 0 0 4.752-.482c2.631-1.078 4.384-3.933 3.83-6.236ZM21.301 26.118a3 3 0 0 1-.13.345 3.4 3.4 0 0 1-.517.795c-.648.743-1.499.978-1.776.808a.27.27 0 0 1-.088-.187 2.5 2.5 0 0 1 .742-1.704 7.8 7.8 0 0 1 1.865-1.445 3.05 3.05 0 0 1-.096 1.388'/></svg>",
|
||||
@ -1024,6 +1028,7 @@
|
||||
"ruff": "<svg viewBox='0 0 32 32'><path fill='#43a047' d='M26 16a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2H4v24h10v-8h2v8h12V18h-6v-2Zm-8-2h-6v-2h6Z'/></svg>",
|
||||
"rust": "<svg viewBox='0 0 32 32'><path fill='#ff7043' d='m30 12-4-2V6h-4l-2-4-4 2-4-2-2 4H6v4l-4 2 2 4-2 4 4 2v4h4l2 4 4-2 4 2 2-4h4v-4l4-2-2-4ZM6 16a9.9 9.9 0 0 1 .842-4H10v8H6.842A9.9 9.9 0 0 1 6 16m10 10a9.98 9.98 0 0 1-7.978-4H16v-2h-2v-2h4c.819.819.297 2.308 1.179 3.37a1.89 1.89 0 0 0 1.46.63h3.34A9.98 9.98 0 0 1 16 26m-2-12v-2h4a1 1 0 0 1 0 2Zm11.158 6H24a2.006 2.006 0 0 1-2-2 2 2 0 0 0-2-2 3 3 0 0 0 3-3q0-.08-.004-.161A3.115 3.115 0 0 0 19.83 10H8.022a9.986 9.986 0 0 1 17.136 10'/></svg>",
|
||||
"salesforce": "<svg viewBox='0 0 24 24'><path fill='#039be5' d='M18.206 6.522c-.681 0-1.275.204-1.858.399-.681-1.177-1.956-1.956-3.328-1.956-1.07 0-2.043.487-2.734 1.168-.779-.973-1.956-1.664-3.318-1.664-2.267 0-4.213 1.858-4.213 4.126 0 .574.204 1.157.399 1.741a3.58 3.58 0 0 0-1.859 3.124c0 1.946 1.567 3.62 3.523 3.62.292 0 .583 0 .778-.098.39 1.469 1.858 2.55 3.62 2.55 1.654 0 3.026-.984 3.512-2.356.496.205.983.4 1.47.4 1.274 0 2.442-.71 3.025-1.762.302.078.613.078.886.078 2.54 0 4.592-2.034 4.592-4.67.098-2.627-1.946-4.7-4.495-4.7'/></svg>",
|
||||
"salt": "<svg viewBox='0 0 16 16'><path fill='#03a9f4' d='M1 8v6h7l3-6h4V2H8L5 8z'/></svg>",
|
||||
"san": "<svg viewBox='0 0 32 32'><path fill='#01579b' d='M28 17.898 4 23.316V30l24-5.418Zm0-10.623L4 12.694v6.683l24-5.418Z'/><path fill='#b3e5fc' d='M28 13.926 4 8.684V2l24 5.242Zm0 10.623L4 19.307v-6.684l24 5.242Z'/></svg>",
|
||||
"sas": "<svg viewBox='0 0 6.35 6.35'><path fill='#039be5' d='M3.16.546a1.9 1.9 0 0 0-.667.13c-.378.157-.678.4-.846.74-.255.452-.296 1.032.04 1.536.31.474.72.908 1.148 1.407.382.139.572-.272.515-.42-.276-.35-.57-.695-.804-1.06a1.1 1.1 0 0 1-.07-.906c.075-.198.503-.84 1.372-.836.345.04.658.059 1.086.53a1.6 1.6 0 0 0-.536-.753A2.05 2.05 0 0 0 3.159.546zm.245 1.4c-.277.002-.406.227-.348.437.253.365.578.748.869 1.122.316.609.092 1.077-.512 1.472-.82.458-1.576.116-2.026-.298.234.489.423.636.471.679.31.27.81.527 1.62.423.456-.102 1.06-.256 1.396-1.097.093-.265.125-.54.03-.843-.09-.338-.274-.58-.466-.829-.3-.351-.77-.979-.906-1.053a.6.6 0 0 0-.128-.013'/></svg>",
|
||||
"sass": "<svg viewBox='0 0 32 32'><path fill='#ec407a' d='M27.837 5.673a4.33 4.33 0 0 0-2.293-2.701c-2.362-1.261-6.11-1.298-9.548-.092a26.3 26.3 0 0 0-8.76 4.966c-2.752 2.542-3.438 4.925-3.189 6.194.523 2.668 3.274 4.539 5.485 6.042.418.284.822.559 1.175.816-1.429.76-4.261 2.444-5.088 4.248a3.88 3.88 0 0 0-.118 3.332A2.37 2.37 0 0 0 6.869 29.8a5.6 5.6 0 0 0 1.49.2 6.35 6.35 0 0 0 5.19-2.856 6.74 6.74 0 0 0 .864-5.382 7.3 7.3 0 0 1 2.044-.03 3.92 3.92 0 0 1 2.816 1.311 1.82 1.82 0 0 1 .423 1.262 1.55 1.55 0 0 1-.772 1.05c-.234.14-.586.355-.504.803.036.194.198.633.894.512a2.93 2.93 0 0 0 2.145-2.651 4 4 0 0 0-1.197-2.904 5.94 5.94 0 0 0-4.396-1.626 10.6 10.6 0 0 0-2.672.304 20 20 0 0 0-2.203-1.846c-1.712-1.3-3.33-2.529-3.235-4.26.125-2.263 2.468-4.532 6.964-6.744 4.016-1.976 7.254-2.037 8.944-1.438a2 2 0 0 1 1.204.883 2.77 2.77 0 0 1-.36 2.47 9.71 9.71 0 0 1-7.425 4.304 3.86 3.86 0 0 1-3.238-.757c-.278-.302-.593-.645-1.074-.383q-.565.31-.225 1.189a3.9 3.9 0 0 0 2.407 1.92 11.7 11.7 0 0 0 7.128-.671c3.527-1.35 6.681-5.202 5.756-8.787M11.895 24.475a4 4 0 0 1-.192.468 4.5 4.5 0 0 1-.753 1.081 2.83 2.83 0 0 1-2.533 1.107c-.056-.032-.078-.146-.085-.193a3.28 3.28 0 0 1 1.076-2.284 11.3 11.3 0 0 1 2.644-1.933 3.85 3.85 0 0 1-.157 1.754'/></svg>",
|
||||
|
||||
38
package.json
38
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"type": "module",
|
||||
"packageManager": "pnpm@10.26.0",
|
||||
"packageManager": "pnpm@10.28.0",
|
||||
"engines": {
|
||||
"node": ">= 22.6.0",
|
||||
"pnpm": ">= 10.0.0"
|
||||
@ -8,7 +8,7 @@
|
||||
"dependencies": {
|
||||
"@citation-js/core": "0.7.21",
|
||||
"@citation-js/plugin-bibtex": "0.7.21",
|
||||
"@citation-js/plugin-csl": "0.7.21",
|
||||
"@citation-js/plugin-csl": "0.7.22",
|
||||
"@citation-js/plugin-software-formats": "0.6.1",
|
||||
"@github/markdown-toolbar-element": "2.2.3",
|
||||
"@github/paste-markdown": "1.5.3",
|
||||
@ -21,7 +21,7 @@
|
||||
"@techknowlogick/license-checker-webpack-plugin": "0.3.0",
|
||||
"add-asset-webpack-plugin": "3.1.1",
|
||||
"ansi_up": "6.0.6",
|
||||
"asciinema-player": "3.13.5",
|
||||
"asciinema-player": "3.14.0",
|
||||
"chart.js": "4.5.1",
|
||||
"chartjs-adapter-dayjs-4": "1.0.4",
|
||||
"chartjs-plugin-zoom": "2.2.0",
|
||||
@ -32,7 +32,7 @@
|
||||
"dayjs": "1.11.19",
|
||||
"dropzone": "6.0.0-beta.2",
|
||||
"easymde": "2.20.0",
|
||||
"esbuild-loader": "4.4.0",
|
||||
"esbuild-loader": "4.4.2",
|
||||
"htmx.org": "2.0.8",
|
||||
"idiomorph": "0.7.4",
|
||||
"jquery": "3.7.1",
|
||||
@ -41,7 +41,7 @@
|
||||
"mini-css-extract-plugin": "2.9.4",
|
||||
"monaco-editor": "0.55.1",
|
||||
"monaco-editor-webpack-plugin": "7.1.1",
|
||||
"online-3d-viewer": "0.17.0",
|
||||
"online-3d-viewer": "0.18.0",
|
||||
"pdfobject": "2.3.1",
|
||||
"perfect-debounce": "2.0.0",
|
||||
"postcss": "8.5.6",
|
||||
@ -56,11 +56,11 @@
|
||||
"tributejs": "5.1.3",
|
||||
"uint8-to-base64": "0.2.1",
|
||||
"vanilla-colorful": "0.7.2",
|
||||
"vue": "3.5.25",
|
||||
"vue": "3.5.26",
|
||||
"vue-bar-graph": "2.2.0",
|
||||
"vue-chartjs": "5.3.3",
|
||||
"vue-loader": "17.4.2",
|
||||
"webpack": "5.104.0",
|
||||
"webpack": "5.104.1",
|
||||
"webpack-cli": "6.0.1",
|
||||
"wrap-ansi": "9.0.2"
|
||||
},
|
||||
@ -68,38 +68,38 @@
|
||||
"@eslint-community/eslint-plugin-eslint-comments": "4.5.0",
|
||||
"@eslint/json": "0.14.0",
|
||||
"@playwright/test": "1.57.0",
|
||||
"@stylistic/eslint-plugin": "5.6.1",
|
||||
"@stylistic/eslint-plugin": "5.7.0",
|
||||
"@stylistic/stylelint-plugin": "4.0.0",
|
||||
"@types/codemirror": "5.60.17",
|
||||
"@types/dropzone": "5.7.9",
|
||||
"@types/jquery": "3.5.33",
|
||||
"@types/katex": "0.16.7",
|
||||
"@types/katex": "0.16.8",
|
||||
"@types/pdfobject": "2.2.5",
|
||||
"@types/sortablejs": "1.15.9",
|
||||
"@types/swagger-ui-dist": "3.30.6",
|
||||
"@types/throttle-debounce": "5.0.2",
|
||||
"@types/tinycolor2": "1.4.6",
|
||||
"@types/toastify-js": "1.12.4",
|
||||
"@typescript-eslint/parser": "8.50.0",
|
||||
"@typescript-eslint/parser": "8.53.0",
|
||||
"@vitejs/plugin-vue": "6.0.3",
|
||||
"@vitest/eslint-plugin": "1.5.2",
|
||||
"@vitest/eslint-plugin": "1.6.6",
|
||||
"eslint": "9.39.2",
|
||||
"eslint-import-resolver-typescript": "4.4.4",
|
||||
"eslint-plugin-array-func": "5.1.0",
|
||||
"eslint-plugin-github": "6.0.0",
|
||||
"eslint-plugin-import-x": "4.16.1",
|
||||
"eslint-plugin-playwright": "2.4.0",
|
||||
"eslint-plugin-playwright": "2.5.0",
|
||||
"eslint-plugin-regexp": "2.10.0",
|
||||
"eslint-plugin-sonarjs": "3.0.5",
|
||||
"eslint-plugin-unicorn": "62.0.0",
|
||||
"eslint-plugin-vue": "10.6.2",
|
||||
"eslint-plugin-vue-scoped-css": "2.12.0",
|
||||
"eslint-plugin-wc": "3.0.2",
|
||||
"globals": "16.5.0",
|
||||
"happy-dom": "20.0.11",
|
||||
"globals": "17.0.0",
|
||||
"happy-dom": "20.1.0",
|
||||
"jiti": "2.6.1",
|
||||
"markdownlint-cli": "0.47.0",
|
||||
"material-icon-theme": "5.29.0",
|
||||
"material-icon-theme": "5.30.0",
|
||||
"nolyfill": "1.0.44",
|
||||
"postcss-html": "1.8.0",
|
||||
"spectral-cli-bundle": "1.0.3",
|
||||
@ -107,14 +107,14 @@
|
||||
"stylelint-config-recommended": "17.0.0",
|
||||
"stylelint-declaration-block-no-ignored-properties": "2.8.0",
|
||||
"stylelint-declaration-strict-value": "1.10.11",
|
||||
"stylelint-value-no-unknown-custom-properties": "6.0.1",
|
||||
"stylelint-value-no-unknown-custom-properties": "6.1.0",
|
||||
"svgo": "4.0.0",
|
||||
"typescript": "5.9.3",
|
||||
"typescript-eslint": "8.50.0",
|
||||
"typescript-eslint": "8.53.0",
|
||||
"updates": "17.0.7",
|
||||
"vite-string-plugin": "1.4.9",
|
||||
"vitest": "4.0.16",
|
||||
"vue-tsc": "3.1.8"
|
||||
"vitest": "4.0.17",
|
||||
"vue-tsc": "3.2.2"
|
||||
},
|
||||
"browserslist": [
|
||||
"defaults"
|
||||
|
||||
1489
pnpm-lock.yaml
generated
1489
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -224,7 +224,7 @@ func GetStopwatches(ctx *context.APIContext) {
|
||||
return
|
||||
}
|
||||
|
||||
apiSWs, err := convert.ToStopWatches(ctx, sws)
|
||||
apiSWs, err := convert.ToStopWatches(ctx, ctx.Doer, sws)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
|
||||
@ -15,6 +15,7 @@ import (
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/optional"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
@ -128,7 +129,9 @@ func prepareUserNotificationsData(ctx *context.Context) {
|
||||
ctx.Data["Notifications"] = notifications
|
||||
ctx.Data["Link"] = setting.AppSubURL + "/notifications"
|
||||
ctx.Data["SequenceNumber"] = ctx.FormString("sequence-number")
|
||||
|
||||
pager.AddParamFromRequest(ctx.Req)
|
||||
pager.RemoveParam(container.SetOf("div-only", "sequence-number"))
|
||||
ctx.Data["Page"] = pager
|
||||
}
|
||||
|
||||
|
||||
14
routers/web/user/setting/security/main_test.go
Normal file
14
routers/web/user/setting/security/main_test.go
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package security
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
unittest.MainTest(m)
|
||||
}
|
||||
@ -4,12 +4,14 @@
|
||||
package security
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/auth/openid"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
"code.gitea.io/gitea/services/forms"
|
||||
@ -116,7 +118,11 @@ func DeleteOpenID(ctx *context.Context) {
|
||||
}
|
||||
|
||||
if err := user_model.DeleteUserOpenID(ctx, &user_model.UserOpenID{ID: ctx.FormInt64("id"), UID: ctx.Doer.ID}); err != nil {
|
||||
ctx.ServerError("DeleteUserOpenID", err)
|
||||
if errors.Is(err, util.ErrNotExist) {
|
||||
ctx.HTTPError(http.StatusNotFound)
|
||||
} else {
|
||||
ctx.ServerError("DeleteUserOpenID", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
log.Trace("OpenID address deleted: %s", ctx.Doer.Name)
|
||||
@ -132,8 +138,12 @@ func ToggleOpenIDVisibility(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := user_model.ToggleUserOpenIDVisibility(ctx, ctx.FormInt64("id")); err != nil {
|
||||
ctx.ServerError("ToggleUserOpenIDVisibility", err)
|
||||
if err := user_model.ToggleUserOpenIDVisibility(ctx, ctx.FormInt64("id"), ctx.Doer); err != nil {
|
||||
if errors.Is(err, util.ErrNotExist) {
|
||||
ctx.HTTPError(http.StatusNotFound)
|
||||
} else {
|
||||
ctx.ServerError("ToggleUserOpenIDVisibility", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
36
routers/web/user/setting/security/openid_test.go
Normal file
36
routers/web/user/setting/security/openid_test.go
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package security
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
"code.gitea.io/gitea/services/contexttest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestDeleteOpenIDReturnsNotFoundForOtherUsersAddress(t *testing.T) {
|
||||
unittest.PrepareTestEnv(t)
|
||||
ctx, _ := contexttest.MockContext(t, "POST /user/settings/security")
|
||||
contexttest.LoadUser(t, ctx, 2)
|
||||
ctx.SetFormString("id", "1")
|
||||
|
||||
DeleteOpenID(ctx)
|
||||
|
||||
assert.Equal(t, http.StatusNotFound, ctx.Resp.WrittenStatus())
|
||||
}
|
||||
|
||||
func TestToggleOpenIDVisibilityReturnsNotFoundForOtherUsersAddress(t *testing.T) {
|
||||
unittest.PrepareTestEnv(t)
|
||||
ctx, _ := contexttest.MockContext(t, "POST /user/settings/security")
|
||||
contexttest.LoadUser(t, ctx, 2)
|
||||
ctx.SetFormString("id", "1")
|
||||
|
||||
ToggleOpenIDVisibility(ctx)
|
||||
|
||||
assert.Equal(t, http.StatusNotFound, ctx.Resp.WrittenStatus())
|
||||
}
|
||||
@ -29,7 +29,7 @@ func GetStopwatches(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
apiSWs, err := convert.ToStopWatches(ctx, sws)
|
||||
apiSWs, err := convert.ToStopWatches(ctx, ctx.Doer, sws)
|
||||
if err != nil {
|
||||
ctx.HTTPError(http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
|
||||
@ -8,8 +8,10 @@ import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
"code.gitea.io/gitea/modules/paginator"
|
||||
)
|
||||
|
||||
@ -49,6 +51,14 @@ func (p *Pagination) AddParamFromRequest(req *http.Request) {
|
||||
p.AddParamFromQuery(req.URL.Query())
|
||||
}
|
||||
|
||||
func (p *Pagination) RemoveParam(keys container.Set[string]) {
|
||||
p.urlParams = slices.DeleteFunc(p.urlParams, func(s string) bool {
|
||||
k, _, _ := strings.Cut(s, "=")
|
||||
k, _ = url.QueryUnescape(k)
|
||||
return keys.Contains(k)
|
||||
})
|
||||
}
|
||||
|
||||
// GetParams returns the configured URL params
|
||||
func (p *Pagination) GetParams() template.URL {
|
||||
return template.URL(strings.Join(p.urlParams, "&"))
|
||||
|
||||
35
services/context/pagination_test.go
Normal file
35
services/context/pagination_test.go
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package context
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestPagination(t *testing.T) {
|
||||
p := NewPagination(1, 1, 1, 1)
|
||||
params := url.Values{}
|
||||
params.Add("k1", "11")
|
||||
params.Add("k1", "12")
|
||||
params.Add("k", "a")
|
||||
params.Add("k", "b")
|
||||
params.Add("k2", "21")
|
||||
params.Add("k2", "22")
|
||||
params.Add("foo", "bar")
|
||||
|
||||
p.AddParamFromQuery(params)
|
||||
v, _ := url.ParseQuery(string(p.GetParams()))
|
||||
assert.Equal(t, params, v)
|
||||
|
||||
p.RemoveParam(container.SetOf("k", "foo"))
|
||||
params.Del("k")
|
||||
params.Del("foo")
|
||||
v, _ = url.ParseQuery(string(p.GetParams()))
|
||||
assert.Equal(t, params, v)
|
||||
}
|
||||
@ -10,6 +10,7 @@ import (
|
||||
"strings"
|
||||
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
access_model "code.gitea.io/gitea/models/perm/access"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/label"
|
||||
@ -163,11 +164,12 @@ func ToTrackedTime(ctx context.Context, doer *user_model.User, t *issues_model.T
|
||||
}
|
||||
|
||||
// ToStopWatches convert Stopwatch list to api.StopWatches
|
||||
func ToStopWatches(ctx context.Context, sws []*issues_model.Stopwatch) (api.StopWatches, error) {
|
||||
func ToStopWatches(ctx context.Context, doer *user_model.User, sws []*issues_model.Stopwatch) (api.StopWatches, error) {
|
||||
result := api.StopWatches(make([]api.StopWatch, 0, len(sws)))
|
||||
|
||||
issueCache := make(map[int64]*issues_model.Issue)
|
||||
repoCache := make(map[int64]*repo_model.Repository)
|
||||
permCache := make(map[int64]access_model.Permission)
|
||||
var (
|
||||
issue *issues_model.Issue
|
||||
repo *repo_model.Repository
|
||||
@ -182,13 +184,30 @@ func ToStopWatches(ctx context.Context, sws []*issues_model.Stopwatch) (api.Stop
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
issueCache[sw.IssueID] = issue
|
||||
}
|
||||
repo, ok = repoCache[issue.RepoID]
|
||||
if !ok {
|
||||
repo, err = repo_model.GetRepositoryByID(ctx, issue.RepoID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
log.Error("GetRepositoryByID(%d): %v", issue.RepoID, err)
|
||||
continue
|
||||
}
|
||||
repoCache[issue.RepoID] = repo
|
||||
}
|
||||
|
||||
// ADD: Check user permissions
|
||||
perm, ok := permCache[repo.ID]
|
||||
if !ok {
|
||||
perm, err = access_model.GetUserRepoPermission(ctx, repo, doer)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
permCache[repo.ID] = perm
|
||||
}
|
||||
|
||||
if !perm.CanReadIssuesOrPulls(issue.IsPull) {
|
||||
continue
|
||||
}
|
||||
|
||||
result = append(result, api.StopWatch{
|
||||
|
||||
@ -8,9 +8,11 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
@ -55,3 +57,29 @@ func TestMilestone_APIFormat(t *testing.T) {
|
||||
Deadline: milestone.DeadlineUnix.AsTimePtr(),
|
||||
}, *ToAPIMilestone(milestone))
|
||||
}
|
||||
|
||||
func TestToStopWatchesRespectsPermissions(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
ctx := t.Context()
|
||||
publicSW := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{ID: 1})
|
||||
privateIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: 3})
|
||||
privateSW := &issues_model.Stopwatch{IssueID: privateIssue.ID, UserID: 5}
|
||||
assert.NoError(t, db.Insert(ctx, privateSW))
|
||||
assert.NotZero(t, privateSW.ID)
|
||||
|
||||
regularUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
|
||||
adminUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
|
||||
|
||||
sws := []*issues_model.Stopwatch{publicSW, privateSW}
|
||||
|
||||
visible, err := ToStopWatches(ctx, regularUser, sws)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, visible, 1)
|
||||
assert.Equal(t, "repo1", visible[0].RepoName)
|
||||
|
||||
visibleAdmin, err := ToStopWatches(ctx, adminUser, sws)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, visibleAdmin, 2)
|
||||
assert.ElementsMatch(t, []string{"repo1", "repo3"}, []string{visibleAdmin[0].RepoName, visibleAdmin[1].RepoName})
|
||||
}
|
||||
|
||||
@ -127,20 +127,10 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, permissionInR
|
||||
projectsMode = config.ProjectsMode
|
||||
}
|
||||
|
||||
hasReleases := false
|
||||
if _, err := repo.GetUnit(ctx, unit_model.TypeReleases); err == nil {
|
||||
hasReleases = true
|
||||
}
|
||||
|
||||
hasPackages := false
|
||||
if _, err := repo.GetUnit(ctx, unit_model.TypePackages); err == nil {
|
||||
hasPackages = true
|
||||
}
|
||||
|
||||
hasActions := false
|
||||
if _, err := repo.GetUnit(ctx, unit_model.TypeActions); err == nil {
|
||||
hasActions = true
|
||||
}
|
||||
hasCode := repo.UnitEnabled(ctx, unit_model.TypeCode)
|
||||
hasReleases := repo.UnitEnabled(ctx, unit_model.TypeReleases)
|
||||
hasPackages := repo.UnitEnabled(ctx, unit_model.TypePackages)
|
||||
hasActions := repo.UnitEnabled(ctx, unit_model.TypeActions)
|
||||
|
||||
if err := repo.LoadOwner(ctx); err != nil {
|
||||
return nil
|
||||
@ -221,6 +211,7 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, permissionInR
|
||||
Updated: repo.UpdatedUnix.AsTime(),
|
||||
ArchivedAt: repo.ArchivedUnix.AsTime(),
|
||||
Permissions: permission,
|
||||
HasCode: hasCode,
|
||||
HasIssues: hasIssues,
|
||||
ExternalTracker: externalTracker,
|
||||
InternalTracker: internalTracker,
|
||||
|
||||
@ -7,9 +7,12 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"slices"
|
||||
|
||||
access_model "code.gitea.io/gitea/models/perm/access"
|
||||
"code.gitea.io/gitea/models/renderhelper"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/markup/markdown"
|
||||
@ -44,6 +47,16 @@ func MailNewRelease(ctx context.Context, rel *repo_model.Release) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := rel.LoadRepo(ctx); err != nil {
|
||||
log.Error("rel.LoadRepo: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// delete publisher or any users with no permission
|
||||
recipients = slices.DeleteFunc(recipients, func(u *user_model.User) bool {
|
||||
return u.ID == rel.PublisherID || !access_model.CheckRepoUnitUser(ctx, rel.Repo, u, unit.TypeReleases)
|
||||
})
|
||||
|
||||
langMap := make(map[string][]*user_model.User)
|
||||
for _, user := range recipients {
|
||||
if user.ID != rel.PublisherID {
|
||||
|
||||
71
services/mailer/mail_release_test.go
Normal file
71
services/mailer/mail_release_test.go
Normal file
@ -0,0 +1,71 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package mailer
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
sender_service "code.gitea.io/gitea/services/mailer/sender"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestMailNewReleaseFiltersUnauthorizedWatchers(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
origMailService := setting.MailService
|
||||
origDomain := setting.Domain
|
||||
origAppName := setting.AppName
|
||||
origAppURL := setting.AppURL
|
||||
origTemplates := LoadedTemplates()
|
||||
defer func() {
|
||||
setting.MailService = origMailService
|
||||
setting.Domain = origDomain
|
||||
setting.AppName = origAppName
|
||||
setting.AppURL = origAppURL
|
||||
loadedTemplates.Store(origTemplates)
|
||||
}()
|
||||
|
||||
setting.MailService = &setting.Mailer{
|
||||
From: "Gitea",
|
||||
FromEmail: "noreply@example.com",
|
||||
}
|
||||
setting.Domain = "example.com"
|
||||
setting.AppName = "Gitea"
|
||||
setting.AppURL = "https://example.com/"
|
||||
prepareMailTemplates(string(tplNewReleaseMail), "{{.Subject}}", "<p>{{.Release.TagName}}</p>")
|
||||
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
|
||||
require.True(t, repo.IsPrivate)
|
||||
|
||||
admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
|
||||
unauthorized := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
|
||||
|
||||
assert.NoError(t, repo_model.WatchRepo(t.Context(), admin, repo, true))
|
||||
assert.NoError(t, repo_model.WatchRepo(t.Context(), unauthorized, repo, true))
|
||||
|
||||
rel := unittest.AssertExistsAndLoadBean(t, &repo_model.Release{ID: 11})
|
||||
rel.Repo = nil
|
||||
rel.Publisher = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: rel.PublisherID})
|
||||
|
||||
var sent []*sender_service.Message
|
||||
origSend := SendAsync
|
||||
SendAsync = func(msgs ...*sender_service.Message) {
|
||||
sent = append(sent, msgs...)
|
||||
}
|
||||
defer func() {
|
||||
SendAsync = origSend
|
||||
}()
|
||||
|
||||
MailNewRelease(t.Context(), rel)
|
||||
|
||||
require.Len(t, sent, 1)
|
||||
assert.Equal(t, admin.EmailTo(), sent[0].To)
|
||||
assert.NotEqual(t, unauthorized.EmailTo(), sent[0].To)
|
||||
}
|
||||
@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
access_model "code.gitea.io/gitea/models/perm/access"
|
||||
@ -62,6 +63,36 @@ func TestTeam_RemoveMember(t *testing.T) {
|
||||
assert.True(t, organization.IsErrLastOrgOwner(err))
|
||||
}
|
||||
|
||||
func TestRemoveTeamMemberRemovesSubscriptionsAndStopwatches(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
ctx := t.Context()
|
||||
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2})
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
|
||||
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repo.ID})
|
||||
|
||||
assert.NoError(t, repo_model.WatchRepo(ctx, user, repo, true))
|
||||
assert.NoError(t, issues_model.CreateOrUpdateIssueWatch(ctx, user.ID, issue.ID, true))
|
||||
ok, err := issues_model.CreateIssueStopwatch(ctx, user, issue)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, ok)
|
||||
|
||||
assert.NoError(t, RemoveTeamMember(ctx, team, user))
|
||||
|
||||
watch, err := repo_model.GetWatch(ctx, user.ID, repo.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, repo_model.IsWatchMode(watch.Mode))
|
||||
|
||||
_, exists, err := issues_model.GetIssueWatch(ctx, user.ID, issue.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, exists)
|
||||
|
||||
hasStopwatch, _, _, err := issues_model.HasUserStopwatch(ctx, user.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, hasStopwatch)
|
||||
}
|
||||
|
||||
func TestNewTeam(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
|
||||
@ -120,6 +120,11 @@ func ReconsiderWatches(ctx context.Context, repo *repo_model.Repository, user *u
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove all stopwatches a user has running in the repository
|
||||
if err := issues_model.RemoveStopwatchesByRepoID(ctx, user.ID, repo.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove all IssueWatches a user has subscribed to in the repository
|
||||
return issues_model.RemoveIssueWatchersByRepoID(ctx, user.ID, repo.ID)
|
||||
}
|
||||
|
||||
@ -6,7 +6,10 @@ package repository
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
access_model "code.gitea.io/gitea/models/perm/access"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
@ -32,8 +35,8 @@ func TestRepository_AddCollaborator(t *testing.T) {
|
||||
func TestRepository_DeleteCollaboration(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15})
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 22})
|
||||
|
||||
assert.NoError(t, repo.LoadOwner(t.Context()))
|
||||
assert.NoError(t, DeleteCollaboration(t.Context(), repo, user))
|
||||
@ -44,3 +47,50 @@ func TestRepository_DeleteCollaboration(t *testing.T) {
|
||||
|
||||
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repo.ID})
|
||||
}
|
||||
|
||||
func TestRepository_DeleteCollaborationRemovesSubscriptionsAndStopwatches(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
ctx := t.Context()
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15})
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 22})
|
||||
assert.NoError(t, repo.LoadOwner(ctx))
|
||||
assert.NoError(t, repo_model.WatchRepo(ctx, user, repo, true))
|
||||
|
||||
hasAccess, err := access_model.HasAnyUnitAccess(ctx, user.ID, repo)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, hasAccess)
|
||||
|
||||
issueCount, err := db.GetEngine(ctx).Where("repo_id=?", repo.ID).Count(new(issues_model.Issue))
|
||||
assert.NoError(t, err)
|
||||
tempIssue := &issues_model.Issue{
|
||||
RepoID: repo.ID,
|
||||
Index: issueCount + 1,
|
||||
PosterID: repo.OwnerID,
|
||||
Title: "temp issue",
|
||||
Content: "temp",
|
||||
}
|
||||
assert.NoError(t, db.Insert(ctx, tempIssue))
|
||||
assert.NoError(t, issues_model.CreateOrUpdateIssueWatch(ctx, user.ID, tempIssue.ID, true))
|
||||
ok, err := issues_model.CreateIssueStopwatch(ctx, user, tempIssue)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, ok)
|
||||
|
||||
assert.NoError(t, DeleteCollaboration(ctx, repo, user))
|
||||
|
||||
hasAccess, err = access_model.HasAnyUnitAccess(ctx, user.ID, repo)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, hasAccess)
|
||||
|
||||
watch, err := repo_model.GetWatch(ctx, user.ID, repo.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, repo_model.IsWatchMode(watch.Mode))
|
||||
|
||||
_, exists, err := issues_model.GetIssueWatch(ctx, user.ID, tempIssue.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, exists)
|
||||
|
||||
hasStopwatch, _, _, err := issues_model.HasUserStopwatch(ctx, user.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, hasStopwatch)
|
||||
}
|
||||
|
||||
@ -194,6 +194,10 @@ func MakeRepoPrivate(ctx context.Context, repo *repo_model.Repository) (err erro
|
||||
return err
|
||||
}
|
||||
|
||||
if err = repo_model.ClearRepoWatches(ctx, repo.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create/Remove git-daemon-export-ok for git-daemon...
|
||||
if err := CheckDaemonExportOK(ctx, repo); err != nil {
|
||||
return err
|
||||
|
||||
@ -13,6 +13,7 @@ import (
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestLinkedRepository(t *testing.T) {
|
||||
@ -70,3 +71,24 @@ func TestRepository_HasWiki(t *testing.T) {
|
||||
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
|
||||
assert.False(t, HasWiki(t.Context(), repo2))
|
||||
}
|
||||
|
||||
func TestMakeRepoPrivateClearsWatches(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
||||
repo.IsPrivate = false
|
||||
|
||||
watchers, err := repo_model.GetRepoWatchersIDs(t.Context(), repo.ID)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, watchers)
|
||||
|
||||
assert.NoError(t, MakeRepoPrivate(t.Context(), repo))
|
||||
|
||||
watchers, err = repo_model.GetRepoWatchersIDs(t.Context(), repo.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.Empty(t, watchers)
|
||||
|
||||
updatedRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo.ID})
|
||||
assert.True(t, updatedRepo.IsPrivate)
|
||||
assert.Zero(t, updatedRepo.NumWatches)
|
||||
}
|
||||
|
||||
@ -122,7 +122,7 @@ function initAdminAuthentication() {
|
||||
document.querySelector<HTMLInputElement>(`#oauth2_${custom}`)!.value = document.querySelector<HTMLInputElement>(`#${provider}_${custom}`)!.value;
|
||||
}
|
||||
const customInput = document.querySelector(`#${provider}_${custom}`);
|
||||
if (customInput && customInput.getAttribute('data-available') === 'true') {
|
||||
if (customInput?.getAttribute('data-available') === 'true') {
|
||||
for (const input of document.querySelectorAll(`.oauth2_${custom} input`)) {
|
||||
input.setAttribute('required', 'required');
|
||||
}
|
||||
|
||||
@ -369,7 +369,7 @@ export class ComboMarkdownEditor {
|
||||
hideElem(this.textareaMarkdownToolbar);
|
||||
}
|
||||
|
||||
value(v: any = undefined) {
|
||||
value(v?: any) {
|
||||
if (v === undefined) {
|
||||
if (this.easyMDE) {
|
||||
return this.easyMDE.value();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user